i have a program in visual studio but it doesn't quit after i pres x i have to manually stop the debugging, also some feedback on my coding style would be great.
#include "main.h"
createGLContext GLContext;
int WINAPI winMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
bool mainLoopRunning;
LARGE_INTEGER prevTime, curTime;
float deltaTime, fixedTimeStep = 0.0;
QueryPerformanceFrequency(&curTime);
const float pcFreq = curTime.QuadPart / 1000.0;
/*###############################################
load everything and create render context
###############################################*/
if (!createWindow("engiene", 1280, 720, &hInstance))
{
OutputDebugString("Couldn't create window.");
return 0;
}
GLContext.setupScene();
/*###############
main loop
###############*/
mainLoopRunning = true;
while (mainLoopRunning)
{
#pragma region calculate deltaTime
prevTime = curTime;
QueryPerformanceCounter(&curTime);
deltaTime = ((float)(curTime.QuadPart - prevTime.QuadPart) / pcFreq);
#ifdef DEBUG
if (deltaTime > 500)//if i break the code during debugging for a long time
deltaTime = 500;
#endif
#pragma endregion
/*######################
process messages
######################*/
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // If we have a message to process, process it
if (msg.message == WM_QUIT) {
mainLoopRunning = false; // Set running to false if we have a message to quit
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else { // If we don't have a message to process
/*##################
update world
##################*/
GLContext.tempRender();
}
#pragma region Print_fps
fixedTimeStep += deltaTime;
while (fixedTimeStep > 500.0)
{
char str[12];
sprintf_s(str, "%.2f FPS\n", 1000.0 / deltaTime);
OutputDebugString(str);
fixedTimeStep -= 500.0;
}
#pragma endregion
Sleep(16);//TODO make an actual game so i can remove this
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/*###########################
windows event handler
###########################*/
switch (message)
{
case WM_SIZE: // If our window is resizing
{
GLContext.reshapeWindow(LOWORD(lParam), HIWORD(lParam));
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
bool createWindow(const LPCSTR title, const int width, const int height, HINSTANCE *hInstance) {
/*#########################################
creates a window and openGL context
#########################################*/
WNDCLASS windowClass;
HWND hWnd;
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
*hInstance = GetModuleHandle(NULL);
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc = (WNDPROC)WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = *hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = title;
if (!RegisterClass(&windowClass)) {
return false;
}
hWnd = CreateWindowEx(dwExStyle, title, title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, width, height, NULL, NULL, *hInstance, NULL);
GLContext.createContext(hWnd); // Create our OpenGL context on the given window we just created
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
return true;
}
#include "createGLContext.h"
createGLContext::createGLContext()
{
}
bool createGLContext::createContext(HWND hwnd) {
this->hwnd = hwnd; // Set the HWND for our window
hdc = GetDC(hwnd); // Get the device context for our window
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
int nPixelFormat = ChoosePixelFormat(hdc, &pfd); // Check if our PFD is valid and get a pixel format back
if (nPixelFormat == 0) // If it fails
return false;
BOOL bResult = SetPixelFormat(hdc, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD
if (!bResult) // If it fails
return false;
HGLRC tempOpenGLContext = wglCreateContext(hdc); // Create an OpenGL 2.1 context for our device context
wglMakeCurrent(hdc, tempOpenGLContext); // Make the OpenGL 2.1 context current and active
GLenum error = glewInit(); // Enable GLEW
if (error != GLEW_OK) // If GLEW fails
return false;
int attributes[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3
WGL_CONTEXT_MINOR_VERSION_ARB, 3, // Set the MINOR version of OpenGL to 2
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible
0
};
if (wglewIsSupported("WGL_ARB_create_context") == 1) { // If the OpenGL 3.x context creation extension is available
hrc = wglCreateContextAttribsARB(hdc, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes
wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active
wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context
wglMakeCurrent(hdc, hrc); // Make our OpenGL 3.0 context current
}
else {
return false;
}
#pragma region print openGL version
int glVersion[2] = { -1, -1 }; // Set some default values for the version
glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using
glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MAJOR version we are using
char str[65];
sprintf_s(str, "Using openGL version %d.%d\n", glVersion[0], glVersion[1]);
OutputDebugString(str);
#pragma endregion
return true; // We have successfully created a context, return true
}
/*########################################################################
setupScene will contain anything we need to setup before we render
########################################################################*/
void createGLContext::setupScene(void) {
glClearColor(0.4f, 0.6f, 0.9f, 0.0f);
}
void createGLContext::reshapeWindow(const int w, const int h)
{
glViewport(0, 0, w, h); // Set the viewport size to fill the window
}
void createGLContext::tempRender()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
SwapBuffers(hdc); // Swap buffers so we can see our rendering
}
createGLContext::~createGLContext()
{
wglMakeCurrent(hdc, 0); // Remove the rendering context from our device context
wglDeleteContext(hrc); // Delete our rendering context
ReleaseDC(hwnd, hdc); // Release the device context from our window
}