Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как увеличить скорость отрисовки в OpenGL ???

37K
06 августа 2008 года
snakeskull
14 / / 02.08.2008
Создаю приложение по эмуляции работы станка ЧПУ. Однако оказалось, что скорость отрисовки 3D сцены через OpenGL очень мала :( Может я что не так инициализировал? Подскажите пожалуйста, буду очень рад помощи.

Вот моя заготовка программы (скопированный урок из книги по OpenGL идеально подходит под мою задачу, толь вместо куба будет нечто подобное). Куб вращается медлено,если задаю шаг угла больше, то получается некрасиво, а хотелось бы чтобы и плавно и быстро было.
Код:
#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
       


}
37K
06 августа 2008 года
snakeskull
14 / / 02.08.2008
Характеристики системы :
Windows XP Professional SP3
Железо :
Intel(R) Core(TM) 2 QuadCPU Q6600@2.4GHz 1ГБ ОЗУ (PC-8600)
NVIDIA GeForce 8800GTS 640МБ
1.9K
09 августа 2008 года
andriano
474 / / 10.01.2008
Честно говоря, код не смотрел.
Но сразу вопросы:
1. Какая версия OpenGL? Если 1.1, то это софтверная реализация от Микрософт, не использующая возможности видеокарты.
2. Сколько примерно полигонов в сцене (всего и отдельно - полупрозрачных)?
3. Какова скорость отрисовки?
37K
14 августа 2008 года
snakeskull
14 / / 02.08.2008
Версия как раз 1.1 оказалась.
Но я уже все на Direct3D перенес, скорость около 150ftp стала, а была на уровне...5ftp (или около того).
Но всеравно спасибо, а то я уже на видеокарту грешить начал.
1.9K
15 августа 2008 года
andriano
474 / / 10.01.2008
Проблема не с самой видеокартой, а с драйверами для нее. Надо ставить драйвера от производителя, а не микрософтовские, тогда производительность в DirectX и OpenGL будет одинаковой.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог