#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
HWND hWnd;
static HGLRC hRC; // контекст рендеринга
static HDC hDC; // контекст устройства GDI
GLfloat rtri; // угол поворота box
GLuint box; // Память для списка отображения box
GLfloat xrot; // поворот по X
GLfloat yrot; // Y
GLfloat zrot; // Z
GLuint texture[1]; // Место для одной текстуры (256*256)
GLvoid InitGL(GLsizei, GLsizei);
GLvoid ReSizeGLScene(GLsizei, GLsizei);
GLvoid DrawGLScene(GLvoid);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TESTGL,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TESTGL);
while (1)
{
// Обработка всех сообщений
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return TRUE;
}
}
// Нарисовать сцену
DrawGLScene();
SwapBuffers(hDC);
// Переключить буфер экрана
if (keys[VK_ESCAPE]) SendMessage(hWnd,WM_CLOSE,0,0); // Если ESC - выйти
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TESTGL);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_TESTGL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{ hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
RECT Screen;
GLuint PixelFormat;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR), // Размер этой структуры
1, // Номер версии
PFD_DRAW_TO_WINDOW | // Формат для Окна
PFD_SUPPORT_OPENGL | // Формат для OpenGL
PFD_DOUBLEBUFFER, // Формат для двойного буфера
PFD_TYPE_RGBA, // Требуется RGBA формат
16, // Выбор 16 бит глубины цвета
0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов (?)
0, // нет буфера прозрачности
0, // Сдвиговый бит игнорируется (?)
0, // Нет буфера аккумуляции
0, 0, 0, 0, // Биты аккумуляции игнорируются (?)
16, // 16 битный Z-буфер (буфер глубины)
0, // Нет буфера траффарета
0, // Нет вспомогательных буферов (?)
PFD_MAIN_PLANE, // Главный слой рисования
0, // Резерв (?)
0, 0, 0 // Маски слоя игнорируются (?)
};
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
hDC = GetDC(hWnd);
PixelFormat = ChoosePixelFormat(hDC, &pfd);
hRC = wglCreateContext(hDC);
GetClientRect(hWnd, &Screen);
InitGL(Screen.right, Screen.bottom);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
ChangeDisplaySettings(NULL, 0);
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd,hDC);
PostQuitMessage(0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
GLvoid BuildLists() //создаем список отображения
{
box=glGenLists(1);
glNewList(box,GL_COMPILE);
glBegin(GL_QUADS);
glColor4f(0.0f,1.7f,1.7f,1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Низ лево
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Низ право
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Верх право
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Верх лево
// Задняя грань
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Низ право
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Верх право
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Верх лево
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Низ лево
// Верхняя грань
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Верх лево
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Низ лево
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Низ право
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Верх право
// Нижняя грань
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Верх право
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Верх лево
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Низ лево
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Низ право
// Правая грань
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Низ право
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Верх право
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Верх лево
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Низ лево
// Левая грань
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Низ лево
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Низ право
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Верх право
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Верх лево
glEnd();
glEndList();
}
GLvoid LoadGLTextures()
{
// Загрузка картинки
AUX_RGBImageRec *texture1;
texture1 = auxDIBImageLoad("001.bmp");
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, texture1->data);
}
GLvoid InitGL(GLsizei Width, GLsizei Height) // Вызвать после создания окна GL
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
LoadGLTextures();
BuildLists();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_FLAT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height)
{
if (Height==0) Height=1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION); // Выбор матрицы проекций
glLoadIdentity(); // Сброс матрицы проекции
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
GLvoid DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-0.0f, 0.0f,-6.0f);
glRotatef(rquad,xrot,yrot,zrot);
glCallList(box);
rquad +=1;
xrot+=0.3f; // Ось вращения X
yrot+=0.2f; // Ось вращения Y
zrot+=0.4f; // Ось вращения Z
}
Как увеличить скорость отрисовки в OpenGL ???
Вот моя заготовка программы (скопированный урок из книги по OpenGL идеально подходит под мою задачу, толь вместо куба будет нечто подобное). Куб вращается медлено,если задаю шаг угла больше, то получается некрасиво, а хотелось бы чтобы и плавно и быстро было.
Код:
Windows XP Professional SP3
Железо :
Intel(R) Core(TM) 2 QuadCPU Q6600@2.4GHz 1ГБ ОЗУ (PC-8600)
NVIDIA GeForce 8800GTS 640МБ
Но сразу вопросы:
1. Какая версия OpenGL? Если 1.1, то это софтверная реализация от Микрософт, не использующая возможности видеокарты.
2. Сколько примерно полигонов в сцене (всего и отдельно - полупрозрачных)?
3. Какова скорость отрисовки?
Но я уже все на Direct3D перенес, скорость около 150ftp стала, а была на уровне...5ftp (или около того).
Но всеравно спасибо, а то я уже на видеокарту грешить начал.
Проблема не с самой видеокартой, а с драйверами для нее. Надо ставить драйвера от производителя, а не микрософтовские, тогда производительность в DirectX и OpenGL будет одинаковой.