At the moment, I'm trying to get some experience writing C++, Win32 and OpenGL, so I decided to implement a "Hello World" of sorts. However, instead of printing Hello World!
to the console, I render a colorful triangle.
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/glext.h>
#include <gl/wglext.h>
#include <gl/glcorearb.h>
#include "SWOGLL.h"
struct Window
{
HINSTANCE hInstance;
HWND hWnd;
HDC hdc;
HGLRC hglrc;
int width;
int height;
};
Window currentWindow;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = TEXT("W32OGL");
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
RegisterClass(&wc);
currentWindow.width = 800;
currentWindow.height = 600;
currentWindow.hInstance = hInstance;
currentWindow.hWnd = CreateWindow(TEXT("W32OGL"), TEXT("W32OGL"), WS_OVERLAPPEDWINDOW, 50, 50, 800, 600, NULL, NULL, hInstance, NULL);
currentWindow.hdc = GetDC(currentWindow.hWnd);
ShowWindow(currentWindow.hWnd, iCmdShow);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize - sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
int chosenPixelFormat = ChoosePixelFormat(currentWindow.hdc, &pfd);
SetPixelFormat(currentWindow.hdc, chosenPixelFormat, &pfd);
currentWindow.hglrc = wglCreateContext(currentWindow.hdc);
wglMakeCurrent(currentWindow.hdc, currentWindow.hglrc);
MSG msg;
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
glViewport(0, 0, currentWindow.width, currentWindow.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, (float)currentWindow.width / (float)currentWindow.height, 0.1f, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0);
glVertex3f(-5, -4, 0);
glColor3f(0, 1, 0);
glVertex3f(5, -4, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 3.5f, 0);
glEnd();
SwapBuffers(currentWindow.hdc);
}
}
wglMakeCurrent(NULL, NULL);
wglDeleteContext(currentWindow.hglrc);
ReleaseDC(currentWindow.hWnd, currentWindow.hdc);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
}
The "SWOGLL.h"
include is simply my own custom OpenGL function loader, which is too long to include in this question. It can be found here.
I'd (preferably) like to know a few things:
- Is there anything I can do to reduce CPU usage?
- Am I writing succinct and correct Win32 code? This is my first time using Win32.
- Is it okay to use
memset
in C++, or is there a more modern and/or safer alternative? - Is it a good idea to use a
while(true)
loop here? - Is the format of my main application loop appropriate?
- Is there anything in general that needs to be improved?