-
-
Save Keshizin/5fae32b8bc27388edffb to your computer and use it in GitHub Desktop.
Janela OpenGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <gl\GL.h> | |
#include <gl\GLU.h> | |
HGLRC hRC = NULL; // Rendering Context | |
HDC hDC = NULL; // GDI Device Context | |
HINSTANCE hInstance; // handle para aplicação | |
bool keys[256]; // estado (pressionado ou não) das 256 teclas do teclado | |
HWND hWnd = NULL; // handle para a janela | |
bool isActive = true; // estado da janela (se está com foco, minimizado ou fora de foco) | |
bool isFullscreen = true; // estado da janela (se a janela está no modo tela cheia ou não) | |
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // manipulação das mensagens | |
int initGL(); // inicialização do OpenGL | |
GLvoid resizeGLScene(GLsizei width, GLsizei height); // configuração da viewport do OpenGL | |
int drawGLScene(); // desenha na janela | |
GLvoid killGLWindow(); // destrói a janela | |
bool createGLWindow(char *title, int width, int height, int bits, bool isFullscreen); // cria uma janela | |
// função MAIN - O programa inicia com esta função!!! | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) | |
{ | |
MSG msg; | |
bool done = false; | |
if(MessageBox(NULL, TEXT("Gostaria de executar em tela cheia?"), TEXT("Janela OpenGL"), MB_YESNO | MB_ICONQUESTION) == IDNO) | |
{ | |
::isFullscreen = false; | |
} | |
if(!createGLWindow("Minha Janela OpenGL sZ", 640, 480, 32, ::isFullscreen)) | |
return 0; | |
while(!done) | |
{ | |
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) | |
{ | |
if(msg.message == WM_QUIT) | |
done = true; | |
else | |
{ | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
else | |
{ | |
if(::isActive) | |
{ | |
if(::keys[VK_ESCAPE]) | |
done = true; | |
else | |
{ | |
drawGLScene(); | |
SwapBuffers(hDC); | |
} | |
} | |
if(::keys[VK_F1]) | |
{ | |
::keys[VK_F1] = false; | |
killGLWindow(); | |
::isFullscreen = !::isFullscreen; | |
if(!createGLWindow("Minha Janela OpenGL sZ", 640, 480, 32, ::isFullscreen)) | |
return 0; | |
} | |
} | |
} | |
killGLWindow(); | |
return (msg.wParam); | |
} | |
int initGL() | |
{ | |
glShadeModel(GL_SMOOTH); | |
glClearColor(1.0f, 0.0f, 1.0f, .0f); | |
glClearDepth(1.0f); | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); | |
return true; | |
} | |
GLvoid resizeGLScene(GLsizei width, GLsizei height) | |
{ | |
if(height == 0) | |
height = 1; | |
glViewport(0, 0, width, height); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
gluOrtho2D(0, width, 0, height); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
} | |
int drawGLScene() | |
{ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glLoadIdentity(); | |
// DESENHE ALGO AQUI! | |
return true; | |
} | |
GLvoid killGLWindow() | |
{ | |
if(::isFullscreen) | |
{ | |
ChangeDisplaySettings(NULL, 0); | |
ShowCursor(true); | |
} | |
if(::hRC) | |
{ | |
if(!wglMakeCurrent(NULL, NULL)) | |
MessageBox(NULL, TEXT("Nao foi possivel liberar DC e RC."), TEXT("Erro"), MB_OK | MB_ICONINFORMATION); | |
if(!wglDeleteContext(::hRC)) | |
MessageBox(NULL, TEXT("Nao foi possivel liberar Rendering Context."), TEXT("Erro"), MB_OK | MB_ICONINFORMATION); | |
::hRC = NULL; | |
} | |
if(::hDC && !ReleaseDC(::hWnd, ::hDC)) | |
{ | |
MessageBox(NULL, TEXT("Nao foi possivel liberar Device Context."), TEXT("Erro"), MB_OK | MB_ICONINFORMATION); | |
::hDC = NULL; | |
} | |
if(::hWnd && !DestroyWindow(::hWnd)) | |
{ | |
MessageBox(NULL, TEXT("Nao foi possivel liberar a janela."), TEXT("Erro"), MB_OK | MB_ICONINFORMATION); | |
::hWnd = NULL; | |
} | |
if(!UnregisterClass(TEXT("OpenGL"), ::hInstance)) | |
{ | |
MessageBox(NULL, TEXT("Nao foi possivel liberar WINDOWCLASS"), TEXT("Erro"), MB_OK | MB_ICONINFORMATION); | |
::hInstance = NULL; | |
} | |
} | |
bool createGLWindow(char *title, int width, int height, int bits, bool isFullscreen) | |
{ | |
GLuint pixelFormat; | |
WNDCLASS wc; | |
DWORD dwExStyle; | |
DWORD dwStyle; | |
RECT windowRect; | |
windowRect.left = (long)0; | |
windowRect.right = (long)width; | |
windowRect.top = (long)0; | |
windowRect.bottom = (long)height; | |
::isFullscreen = isFullscreen; | |
::hInstance = GetModuleHandle(NULL); | |
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; | |
wc.lpfnWndProc = 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; | |
wc.lpszMenuName = NULL; | |
wc.lpszClassName = TEXT("OpenGL"); | |
if(!RegisterClass(&wc)) | |
{ | |
MessageBox(NULL, TEXT("Nao foi possivel registar WINDOWCLASS."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
if(::isFullscreen) | |
{ | |
DEVMODE dmScreenSettings; | |
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); | |
dmScreenSettings.dmSize = sizeof(dmScreenSettings); | |
dmScreenSettings.dmPelsWidth = width; | |
dmScreenSettings.dmPelsHeight = height; | |
dmScreenSettings.dmBitsPerPel = bits; | |
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; | |
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) | |
{ | |
if(MessageBox(NULL, TEXT("O modo tela cheia nao e suportado. Utilizar modo janela?"), | |
TEXT("GL"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES) | |
{ | |
::isFullscreen = false; | |
} | |
else | |
{ | |
MessageBox(NULL, TEXT("Programa sera encerrando."), TEXT("ERRO"), MB_OK | MB_ICONSTOP); | |
return false; | |
} | |
} | |
} | |
if(::isFullscreen) | |
{ | |
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, TEXT("OpenGL"), (LPCWSTR)title, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, 0, 0, | |
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, NULL))) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Falha na criacao da janela."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
static PIXELFORMATDESCRIPTOR pfd = | |
{ | |
sizeof(PIXELFORMATDESCRIPTOR), | |
1, // número da versão | |
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // tipos de formato (Window, OpenGL e double buffering) | |
PFD_TYPE_RGBA, // tipo de formato | |
bits, // color depth | |
0, 0, 0, 0, 0, 0, // bits ignorados | |
0, // sem alpha buffer | |
0, // bit ignored | |
0, // sem accumulation buffer | |
0, 0, 0, 0, // bits ignorados | |
16, // 16bit z-buffer | |
0, // sem stencil buffer | |
0, // sem auxiliar buffer | |
PFD_MAIN_PLANE, // camada principal de desenho | |
0, // reservedo | |
0, 0, 0 // layer marks ignorados | |
}; | |
if(!(::hDC = GetDC(::hWnd))) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Nao e possivel criar GL Device Context."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
if(!(pixelFormat = ChoosePixelFormat(::hDC, &pfd))) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Nao foi possivel encontrar formato de pixel adequado."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
if(!SetPixelFormat(::hDC, pixelFormat, &pfd)) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Nao foi configurar o format de pixel."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
if(!(::hRC = wglCreateContext(::hDC))) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Nao foi possivel criar GL Rendering Context."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return FALSE; | |
} | |
if(!wglMakeCurrent(::hDC, ::hRC)) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Nao foi possivel ativar GL Rendering Context."), TEXT("ERRO"), MB_OK | MB_ICONEXCLAMATION); | |
return false; | |
} | |
ShowWindow(::hWnd, SW_SHOW); | |
SetForegroundWindow(::hWnd); | |
SetFocus(::hWnd); | |
resizeGLScene(width, height); | |
if(!initGL()) | |
{ | |
killGLWindow(); | |
MessageBox(NULL, TEXT("Initialization failed."), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION); | |
return FALSE; | |
} | |
return true; | |
} | |
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
switch(uMsg) | |
{ | |
case WM_ACTIVATE: | |
if(!HIWORD(wParam)) | |
{ | |
::isActive = true; | |
} | |
else | |
{ | |
::isActive = false; | |
} | |
return 0; | |
case WM_SYSCOMMAND: | |
if(wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) | |
return 0; | |
break; | |
case WM_CLOSE: | |
PostQuitMessage(0); | |
return 0; | |
case WM_KEYDOWN: | |
::keys[wParam] = true; | |
return 0; | |
case WM_KEYUP: | |
::keys[wParam] = false; | |
return 0; | |
case WM_SIZE: | |
resizeGLScene(LOWORD(lParam), HIWORD(lParam)); | |
return 0; | |
} | |
return DefWindowProc(hWnd, uMsg, wParam, lParam); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment