Skip to content

Instantly share code, notes, and snippets.

@Keshizin
Created January 13, 2016 19:59
Show Gist options
  • Save Keshizin/5fae32b8bc27388edffb to your computer and use it in GitHub Desktop.
Save Keshizin/5fae32b8bc27388edffb to your computer and use it in GitHub Desktop.
Janela OpenGL
#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