PMG https://forum.pmg.org.ru/ |
|
Проблема с текстурами в openGL https://forum.pmg.org.ru/viewtopic.php?f=1&t=9422 |
Страница 1 из 1 |
Автор: | Вирус777 [ 19 сен 2012 15:45 ] |
Заголовок сообщения: | Проблема с текстурами в openGL |
Я сделал куб с текстурами в openGL в Visual C++ 2010. Компилятор не ругается, запускаю программу. И тут начинается самое интересное: куб с текстурами есть, но через секунд 30 прога останавливается и вылетает с надписью "Out of memory". Что же делать? Ах, да! Еще же код нужен: Код: #include <windows.h>
#include <tchar.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") #pragma comment (lib,"Glaux.lib") static HGLRC hRC; // Постоянный контекст рендеринга static HDC hDC; // Приватный контекст устройства GDI // HGLRC hRC=NULL; // Постоянный контекст рендеринга // HDC hDC=NULL; // Приватный контекст устройства GDI HWND hWnd=NULL; // Здесь будет хранится дескриптор окна HINSTANCE hInstance; // Здесь будет хранится дескриптор приложения bool keys[256]; // Массив, используемый для операций с клавиатурой bool active=true; // Флаг активности окна, установленный в true по умолчанию bool fullscreen=true; // Флаг режима окна, установленный в полноэкранный по умолчанию GLfloat rtri; // Угол для треугольник GLfloat rquad; // Угол для четырехугольника GLfloat xrot; // Вращение X GLfloat yrot; // Y GLfloat zrot; // Z GLuint texture[1]; // Место для одной текстуры LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); // Прототип функции WndProc GLvoid ReSizeGLScene( GLsizei width, GLsizei height ) // Изменить размер и инициализировать окно GL { 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 ); // Выбор матрицы вида модели glLoadIdentity(); // Сброс матрицы вида модели } // Загрузка картинки и конвертирование в текстуру GLvoid LoadGLTextures() { // Загрузка картинки AUX_RGBImageRec *texture1; texture1 = auxDIBImageLoad(L"texture1.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) { LoadGLTextures(); // Загрузка текстур glEnable(GL_TEXTURE_2D); // Разрешение наложение текстуры glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); } int DrawGLScene( GLvoid ) // Здесь будет происходить вся прорисовка { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Очистить экран и буфер глубины /* glLoadIdentity(); // Сбросить текущую матрицу glTranslatef(-1.5f,0.0f,-6.0f); // Сдвиг в глубь экрана и влево glRotatef(rtri,1.0f,0.0f,0.0f); // Вращение треугольника по оси Y glBegin(GL_TRIANGLES); glColor3f(1.0f,0.0f,0.0f); // Красный glVertex3f( 0.0f, 1.0f, 0.0f); // Верх треугольника (Передняя) glColor3f(0.0f,1.0f,0.0f); // Зеленный glVertex3f(-1.0f,-1.0f, 1.0f); // Левая точка glColor3f(0.0f,0.0f,1.0f); // Синий glVertex3f( 1.0f,-1.0f, 1.0f); // Правая точка glColor3f(1.0f,0.0f,0.0f); // Красная glVertex3f( 0.0f, 1.0f, 0.0f); // Верх треугольника (Правая) glColor3f(0.0f,0.0f,1.0f); // Синия glVertex3f( 1.0f,-1.0f, 1.0f); // Лево треугольника (Правая) glColor3f(0.0f,1.0f,0.0f); // Зеленная glVertex3f( 1.0f,-1.0f, -1.0f); // Право треугольника (Правая) glColor3f(1.0f,0.0f,0.0f); // Красный glVertex3f( 0.0f, 1.0f, 0.0f); // Низ треугольника (Сзади) glColor3f(0.0f,1.0f,0.0f); // Зеленный glVertex3f( 1.0f,-1.0f, -1.0f); // Лево треугольника (Сзади) glColor3f(0.0f,0.0f,1.0f); // Синий glVertex3f(-1.0f,-1.0f, -1.0f); // Право треугольника (Сзади) glColor3f(1.0f,0.0f,0.0f); // Красный glVertex3f( 0.0f, 1.0f, 0.0f); // Верх треугольника (Лево) glColor3f(0.0f,0.0f,1.0f); // Синий glVertex3f(-1.0f,-1.0f,-1.0f); // Лево треугольника (Лево) glColor3f(0.0f,1.0f,0.0f); // Зеленный glVertex3f(-1.0f,-1.0f, 1.0f); // Право треугольника (Лево) glEnd(); glBegin(GL_QUADS); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glColor3f(0.0f,0.0f,1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glColor3f(0.0f,0.0f,1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glEnd(); */ glLoadIdentity(); glTranslatef(1.5f,0.0f,-6.0f); // Сдвиг вправо на 1.5 glRotatef(rquad,1.0f,0.0f,0.0f); // Вращение по оси X glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); // Передняя грань 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(); rtri+=0.2f; // Увеличение переменной вращения для треугольника rquad-=0.15f; // Уменьшение переменной вращения для квадрата return true; // Прорисовка прошла успешно } GLvoid KillGLWindow( GLvoid ) // Корректное разрушение окна { if( fullscreen ) // Мы в полноэкранном режиме? { ChangeDisplaySettings( NULL, 0 ); // Если да, то переключаемся обратно в оконный режим ShowCursor( true ); // Показать курсор мышки } if( hRC ) // Существует ли Контекст Рендеринга? { if( !wglMakeCurrent( NULL, NULL ) ) // Возможно ли освободить RC и DC? { MessageBox( NULL, L"Release Of DC And RC Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); } if( !wglDeleteContext( hRC ) ) // Возможно ли удалить RC? { MessageBox( NULL, L"Release Rendering Context Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); } hRC = NULL; // Установить RC в NULL } if( hDC && !ReleaseDC( hWnd, hDC ) ) // Возможно ли уничтожить DC? { MessageBox( NULL, L"Release Device Context Failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); hDC=NULL; // Установить DC в NULL } if(hWnd && !DestroyWindow(hWnd)) // Возможно ли уничтожить окно? { MessageBox( NULL, L"Could Not Release hWnd.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); hWnd = NULL; // Установить hWnd в NULL } if( !UnregisterClass( L"OpenGL", hInstance ) ) // Возможно ли разрегистрировать класс { MessageBox( NULL, L"Could Not Unregister Class.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hInstance = NULL; // Установить hInstance в NULL } } BOOL CreateGLWindow( LPCWSTR title, int width, int height, int bits, bool fullscreenflag ) { GLuint PixelFormat; // Хранит результат после поиска WNDCLASS wc; // Структура класса окна DWORD dwExStyle; // Расширенный стиль окна DWORD dwStyle; // Обычный стиль окна RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left=(long)0; // Установить левую составляющую в 0 WindowRect.right=(long)width; // Установить правую составляющую в Width WindowRect.top=(long)0; // Установить верхнюю составляющую в 0 WindowRect.bottom=(long)height; // Установить нижнюю составляющую в Height fullscreen=fullscreenflag; // Устанавливаем значение глобальной переменной fullscreen hInstance = GetModuleHandle(NULL); // Считаем дескриптор нашего приложения wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Перерисуем при перемещении и создаём скрытый DC wc.lpfnWndProc = (WNDPROC) WndProc; // Процедура обработки сообщений wc.cbClsExtra = 0; // Нет дополнительной информации для окна wc.cbWndExtra = 0; // Нет дополнительной информации для окна wc.hInstance = hInstance; // Устанавливаем дескриптор wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Загружаем иконку по умолчанию wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Загружаем указатель мышки wc.hbrBackground = NULL; // Фон не требуется для GL wc.lpszMenuName = NULL; // Меню в окне не будет wc.lpszClassName = L"OpenGL"; // Устанавливаем имя классу if( !RegisterClass( &wc ) ) // Пытаемся зарегистрировать класс окна { MessageBox( NULL, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Выход и возвращение функцией значения false } if( fullscreen ) // Полноэкранный режим? { DEVMODE dmScreenSettings; // Режим устройства memset( &dmScreenSettings, 0, sizeof( dmScreenSettings ) ); // Очистка для хранения установок dmScreenSettings.dmSize=sizeof( dmScreenSettings ); // Размер структуры Devmode dmScreenSettings.dmPelsWidth = width; // Ширина экрана dmScreenSettings.dmPelsHeight = height; // Высота экрана dmScreenSettings.dmBitsPerPel = bits; // Глубина цвета dmScreenSettings.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;// Режим Пикселя // Пытаемся установить выбранный режим и получить результат. Примечание: CDS_FULLSCREEN убирает панель управления. if( ChangeDisplaySettings( &dmScreenSettings, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) { // Если переключение в полноэкранный режим невозможно, будет предложено два варианта: оконный режим или выход. if( MessageBox( NULL, L"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?", L"NeHe GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES ) { fullscreen = false; // Выбор оконного режима (fullscreen = false) } else { // Выскакивающее окно, сообщающее пользователю о закрытие окна. MessageBox( NULL, L"Program Will Now Close.", L"ERROR", MB_OK | MB_ICONSTOP ); return false; // Выход и возвращение функцией false } } } if(fullscreen) // Мы остались в полноэкранном режиме? { dwExStyle = WS_EX_APPWINDOW; // Расширенный стиль окна dwStyle = WS_POPUP; // Обычный стиль окна ShowCursor( false ); // Скрыть указатель мышки } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Расширенный стиль окна dwStyle = WS_OVERLAPPEDWINDOW; // Обычный стиль окна } AdjustWindowRectEx( &WindowRect, dwStyle, false, dwExStyle ); // Подбирает окну подходящие размеры if( !( hWnd = CreateWindowEx( dwExStyle, // Расширенный стиль для окна _T("OpenGL"), // Имя класса title, // Заголовок окна WS_CLIPSIBLINGS | // Требуемый стиль для окна WS_CLIPCHILDREN | // Требуемый стиль для окна dwStyle, // Выбираемые стили для окна 0, 0, // Позиция окна WindowRect.right-WindowRect.left, // Вычисление подходящей ширины WindowRect.bottom-WindowRect.top, // Вычисление подходящей высоты NULL, // Нет родительского NULL, // Нет меню hInstance, // Дескриптор приложения NULL ) ) ) // Не передаём ничего до WM_CREATE (???) { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } static PIXELFORMATDESCRIPTOR pfd= // pfd сообщает Windows каким будет вывод на экран каждого пикселя { sizeof(PIXELFORMATDESCRIPTOR), // Размер дескриптора данного формата пикселей 1, // Номер версии PFD_DRAW_TO_WINDOW | // Формат для Окна PFD_SUPPORT_OPENGL | // Формат для OpenGL PFD_DOUBLEBUFFER, // Формат для двойного буфера PFD_TYPE_RGBA, // Требуется RGBA формат bits, // Выбирается бит глубины цвета 0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов 0, // Нет буфера прозрачности 0, // Сдвиговый бит игнорируется 0, // Нет буфера накопления 0, 0, 0, 0, // Биты накопления игнорируются 32, // 32 битный Z-буфер (буфер глубины) 0, // Нет буфера трафарета 0, // Нет вспомогательных буферов PFD_MAIN_PLANE, // Главный слой рисования 0, // Зарезервировано 0, 0, 0 // Маски слоя игнорируются }; if( !( hDC = GetDC( hWnd ) ) ) // Можем ли мы получить Контекст Устройства? { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Can't Create A GL Device Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } if( !( PixelFormat = ChoosePixelFormat( hDC, &pfd ) ) ) // Найден ли подходящий формат пикселя? { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Can't Find A Suitable PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } if( !SetPixelFormat( hDC, PixelFormat, &pfd ) ) // Возможно ли установить Формат Пикселя? { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Can't Set The PixelFormat.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } if( !( hRC = wglCreateContext( hDC ) ) ) // Возможно ли установить Контекст Рендеринга? { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Can't Create A GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } if( !wglMakeCurrent( hDC, hRC ) ) // Попробовать активировать Контекст Рендеринга { KillGLWindow(); // Восстановить экран MessageBox( NULL, L"Can't Activate The GL Rendering Context.", L"ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } ShowWindow( hWnd, SW_SHOW ); // Показать окно SetForegroundWindow( hWnd ); // Слегка повысим приоритет SetFocus( hWnd ); // Установить фокус клавиатуры на наше окно ReSizeGLScene( width, height ); // Настроим перспективу для нашего OpenGL экрана. if( !InitGL() ) // Инициализация только что созданного окна { KillGLWindow(); // Восстановить экран MessageBox( NULL, _T("Initialization Failed."), _T("ERROR"), MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } return true; // Всё в порядке! } LRESULT CALLBACK WndProc( HWND hWnd, // Дескриптор нужного окна UINT uMsg, // Сообщение для этого окна WPARAM wParam, // Дополнительная информация LPARAM lParam) // Дополнительная информация { switch (uMsg) // Проверка сообщения для окна { case WM_ACTIVATE: // Проверка сообщения активности окна { if( !HIWORD( wParam ) ) // Проверить состояние минимизации { active = true; // Программа активна } else { active = false; // Программа теперь не активна } return 0; // Возвращаемся в цикл обработки сообщений } case WM_SYSCOMMAND: // Перехватываем системную команду { switch ( wParam ) // Останавливаем системный вызов { case SC_SCREENSAVE: // Пытается ли запустится скринсейвер? case SC_MONITORPOWER: // Пытается ли монитор перейти в режим сбережения энергии? return 0; // Предотвращаем это } break; // Выход } case WM_CLOSE: // Мы получили сообщение о закрытие? { PostQuitMessage( 0 ); // Отправить сообщение о выходе return 0; // Вернуться назад } case WM_KEYDOWN: // Была ли нажата кнопка? { keys[wParam] = true; // Если так, мы присваиваем этой ячейке true return 0; // Возвращаемся } case WM_KEYUP: // Была ли отпущена клавиша? { keys[wParam] = false; // Если так, мы присваиваем этой ячейке false return 0; // Возвращаемся } case WM_SIZE: // Изменены размеры OpenGL окна { ReSizeGLScene( LOWORD(lParam), HIWORD(lParam) ); // Младшее слово=Width, старшее слово=Height return 0; // Возвращаемся } } // пересылаем все необработанные сообщения DefWindowProc return DefWindowProc( hWnd, uMsg, wParam, lParam ); } int WINAPI WinMain( HINSTANCE hInstance, // Дескриптор приложения HINSTANCE hPrevInstance, // Дескриптор родительского приложения LPSTR lpCmdLine, // Параметры командной строки int nCmdShow ) // Состояние отображения окна { MSG msg; // Структура для хранения сообщения Windows BOOL done = false; // Логическая переменная для выхода из цикла // Спрашивает пользователя, какой режим экрана он предпочитает if( MessageBox( NULL, L"Хотите ли Вы запустить приложение в полноэкранном режиме?", L"Запустить в полноэкранном режиме?", MB_YESNO | MB_ICONQUESTION) == IDNO ) { fullscreen = false; // Оконный режим } // Создать наше OpenGL окно if( !CreateGLWindow( L"Мой домашний openGL", 1024, 768, 32, fullscreen ) ) { return 0; // Выйти, если окно не может быть создано } while( !done ) // Цикл продолжается, пока done не равно true { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) // Есть ли в очереди какое-нибудь сообщение? { if( msg.message == WM_QUIT ) // Мы поучили сообщение о выходе? { done = true; // Если так, done=true } else // Если нет, обрабатывает сообщения { TranslateMessage( &msg ); // Переводим сообщение DispatchMessage( &msg ); // Отсылаем сообщение } } else // Если нет сообщений { // Прорисовываем сцену. if( active ) // Активна ли программа? { if(keys[VK_ESCAPE]) // Было ли нажата клавиша ESC? { done = true; // ESC говорит об останове выполнения программы } else // Не время для выхода, обновим экран. { DrawGLScene(); // Рисуем сцену SwapBuffers( hDC ); // Меняем буфер (двойная буферизация) } } if( keys[VK_F1] ) // Была ли нажата F1? { keys[VK_F1] = false; // Если так, меняем значение ячейки массива на false KillGLWindow(); // Разрушаем текущее окно fullscreen = !fullscreen; // Переключаем режим // Пересоздаём наше OpenGL окно if( !CreateGLWindow( _T("Мой домашний openGL"), 1024, 768, 32, fullscreen ) ) { return 0; // Выходим, если это невозможно } } } } // Shutdown KillGLWindow(); // Разрушаем окно return ( msg.wParam ); // Выходим из программы } |
Автор: | MagicWolf [ 24 сен 2012 14:02 ] |
Заголовок сообщения: | Re: Проблема с текстурами в openGL |
Лучше не код, а проект. Так легче увидеть, что не так. И скорее всего, что-то создается и не удаляется каждый раз при выводе куба на экран. |
Автор: | Вирус777 [ 01 окт 2012 15:36 ] |
Заголовок сообщения: | Re: Проблема с текстурами в openGL |
Спасибо уже не надо. Проблема решена. Проблема в функции InitGL |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |