PMG https://forum.pmg.org.ru/ |
|
Чёрный экран https://forum.pmg.org.ru/viewtopic.php?f=1&t=9462 |
Страница 1 из 1 |
Автор: | inotos [ 08 авг 2013 12:31 ] |
Заголовок сообщения: | Чёрный экран |
Доброго времени суток, Код от NeHe, убран fullscreen и keys. Компилируется, линкуется. Cygwin GCC. Сабж - ничего не рисуется, чёрный экран и всё. Пробовал запускать на OpenGL 1.1 и 3.х (не помню точно какая). После запуска на 3.х думаю что косяк в коде. Посмотрите, пожалуйста, мб что увидите. stcpp.h: Код: #ifndef STCPP_H_ #define STCPP_H_ #include <iostream> #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <gl\glaux.h> extern HGLRC hRC; // Постоянный контекст рендеринга extern HDC hDC; // Приватный контекст устройства GDI extern HWND hWnd; // Здесь будет хранится дескриптор окна extern HINSTANCE hInstance; // Здесь будет хранится дескриптор приложения extern bool active; int DrawGLScene( void ); int InitGL( void ); void ReSizeGLScene( GLsizei, GLsizei ); void KillGLWindow( void ); BOOL CreateGLWindow(char *, int, int, int); LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); // Прототип функции WndProc #endif // STCPP_H_ stcpp.cpp: Код: #include "stcpp.h"
HGLRC hRC = NULL; // Постоянный контекст рендеринга HDC hDC = NULL; // Приватный контекст устройства GDI HWND hWnd = NULL; // Здесь будет хранится дескриптор окна HINSTANCE hInstance = NULL; // Здесь будет хранится дескриптор приложения bool active = false; int DrawGLScene( void ) // Здесь будет происходить вся прорисовка { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Очистить экран и буфер глубины glLoadIdentity(); // Сбросить текущую матрицу glTranslatef(-1.5f,0.0f,-6.0f); // Сдвинемся влево на 1.5 единицы и 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, 0.0f); // Слева снизу glColor3f(0.0f,0.0f,1.0f); // Синий цвет glVertex3f( 1.0f,-1.0f, 0.0f); // Справа снизу glEnd(); glTranslatef(3.0f,0.0f,0.0f); // Сдвинем вправо на 3 единицы glBegin(GL_QUADS); glVertex3f(-1.0f, 1.0f, 0.0f); // Слева вверху glVertex3f( 1.0f, 1.0f, 0.0f); // Справа вверху glVertex3f( 1.0f,-1.0f, 0.0f); // Справа внизу glVertex3f(-1.0f,-1.0f, 0.0f); // Слева внизу glEnd(); return true; // Прорисовка прошла успешно } int InitGL( void ) // Все установки касаемо OpenGL происходят здесь { glShadeModel( GL_SMOOTH ); // Разрешить плавное цветовое сглаживание glClearColor(0.2f, 0.0f, 0.3f, 0.5f); // Очистка экрана в черный цвет glClearDepth( 1.0f ); // Разрешить очистку буфера глубины glEnable( GL_DEPTH_TEST ); // Разрешить тест глубины glDepthFunc( GL_LEQUAL ); // Тип теста глубины glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Улучшение в вычислении перспективы std::cout << "Init done\n"; return true; // Инициализация прошла успешно } void 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(); // Сброс матрицы вида модели std::cout << "Resize done\n"; } void KillGLWindow( void ) // Корректное разрушение окна { if( hRC ) // Существует ли Контекст Рендеринга? { if( !wglMakeCurrent( NULL, NULL ) ) MessageBox( NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); // Возможно ли освободить RC и DC? if( !wglDeleteContext( hRC ) ) MessageBox( NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); // Возможно ли удалить RC? hRC = NULL; // Установить RC в NULL } if( hDC && !ReleaseDC( hWnd, hDC ) ) // Возможно ли уничтожить DC? { MessageBox( NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); hDC=NULL; // Установить DC в NULL } if(hWnd && !DestroyWindow(hWnd)) // Возможно ли уничтожить окно? { MessageBox( NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION ); hWnd = NULL; // Установить hWnd в NULL } if( !UnregisterClass( "OpenGL", hInstance ) ) // Возможно ли разрегистрировать класс { MessageBox( NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hInstance = NULL; // Установить hInstance в NULL } } BOOL CreateGLWindow(char *title, int width, int height, int bits ) { std::cout << "Let's create GL window!\n"; 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 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 = "OpenGL"; // Устанавливаем имя классу if( !RegisterClass( &wc ) ) // Пытаемся зарегистрировать класс окна { MessageBox( NULL, "Failed To Register The Window Class.", "ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Выход и возвращение функцией значения false } dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Расширенный стиль окна dwStyle = WS_OVERLAPPEDWINDOW; // Обычный стиль окна AdjustWindowRectEx( &WindowRect, dwStyle, false, dwExStyle ); // Подбирает окну подходящие размеры if( !( hWnd = CreateWindowEx( dwExStyle, // Расширенный стиль для окна "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, "Window Creation Error.", "ERROR", MB_OK | MB_ICONEXCLAMATION ); return false; // Вернуть false } static PIXELFORMATDESCRIPTOR pfd = {0}; // pfd сообщает Windows каким будет вывод на экран каждого пикселя pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Размер дескриптора данного формата пикселей pfd.nVersion = 1; // Номер версии pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; // Формат для Окна и Формат для OpenGL и Формат для двойного буфера pfd.iPixelType = PFD_TYPE_RGBA; // Требуется RGBA формат pfd.cColorBits = bits; // Выбирается бит глубины цвета pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; // Главный слой рисования if(!(hDC = GetDC(hWnd))) // Можем ли мы получить Контекст Устройства? { KillGLWindow(); // Восстановить экран MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } if(!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Найден ли подходящий формат пикселя? { KillGLWindow(); // Восстановить экран MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } if(!SetPixelFormat(hDC, PixelFormat, &pfd)) // Возможно ли установить Формат Пикселя? { KillGLWindow(); // Восстановить экран MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } if(!(hRC = wglCreateContext(hDC))) // Возможно ли установить Контекст Рендеринга? { KillGLWindow(); // Восстановить экран MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } if(!wglMakeCurrent(hDC, hRC)) // Попробовать активировать Контекст Рендеринга { KillGLWindow(); // Восстановить экран MessageBox(NULL, "Can't Activate The GL Rendering Context.", "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, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; // Вернуть false } std::cout << "Create GL window done\n"; return true; // Всё в порядке! } int WINAPI WinMain( HINSTANCE hInstance, // Дескриптор приложения HINSTANCE hPrevInstance, // Дескриптор родительского приложения LPSTR lpCmdLine, // Параметры командной строки int nCmdShow ) // Состояние отображения окна { MSG msg; // Структура для хранения сообщения Windows BOOL done = false; // Логическая переменная для выхода из цикла // Создать наше OpenGL окно if( !CreateGLWindow( "OpenGL window", 800, 600, 32 ) ) 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 ) // Активна ли программа? { DrawGLScene(); // Рисуем сцену SwapBuffers( hDC ); // Меняем буфер (двойная буферизация) } } } // Shutdown KillGLWindow(); // Разрушаем окно return ( msg.wParam ); // Выходим из программы } 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_SIZE: // Изменены размеры OpenGL окна { std::cout << "ReSizeGLScene()\n"; ReSizeGLScene( LOWORD(lParam), HIWORD(lParam) ); // Младшее слово=Width, старшее слово=Height return 0; // Возвращаемся } } // пересылаем все необработанные сообщения DefWindowProc return DefWindowProc( hWnd, uMsg, wParam, lParam ); } |
Автор: | MagicWolf [ 08 авг 2013 16:24 ] |
Заголовок сообщения: | Re: Чёрный экран |
GCC нет . Так-то лучше взять код для gcc с сайта nehe (в конце урока). Компильнуть его - если получиться, тогда уже убирать куски кода... |
Автор: | inotos [ 09 авг 2013 14:42 ] |
Заголовок сообщения: | Re: Чёрный экран |
Из исходников с сайта NeHe - тоже чёрный экран. Хотя бинарники оттуда же запускаются на ура. Буду пробовать на линуксе с чистым GCC. |
Автор: | inotos [ 12 авг 2013 11:15 ] |
Заголовок сообщения: | Re: Чёрный экран |
Да, проблема была с компилятором. Cygwin GCC подвёл. MinGW'шный компилятор схавал. |
Автор: | MagicWolf [ 12 авг 2013 13:08 ] |
Заголовок сообщения: | Re: Чёрный экран |
Странно как-то. По идее с Cygwin GCC должно работать. Может проблема в библиотеках... |
Автор: | inotos [ 14 авг 2013 11:25 ] |
Заголовок сообщения: | Re: Чёрный экран |
Ну да, или в библиотеках, не исключено. На двух разных компах выкачивал одни и те же библиотеки. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |