129fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
229fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens//
329fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
429fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// you may not use this file except in compliance with the License.
529fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// You may obtain a copy of the License at
629fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens//
729fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
829fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens//
929fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// Unless required by applicable law or agreed to in writing, software
1029fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
1129fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1229fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// See the License for the specific language governing permissions and
1329fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens// limitations under the License.
1429fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens
15cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire/******************************************************************************
16cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
17cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire@File			OGLSimpleCube.cpp
18cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
19cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire@Title			OpenGL Simple cube application
20cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
21cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire@Version		1.0
22cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
23cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire@Platform		Windows
24cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
25cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire@Description	Basic window with a cube drawn in it, using libGL (opengl32).
26cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireInspired by http://www.cs.rit.edu/~ncs/Courses/570/UserGuide/OpenGLonWin-11.html
27cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
28cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire******************************************************************************/
29cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire#include <windows.h>
30cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire#include <math.h>
31cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
32cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire#include <gl\GL.h>
33cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
34cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire#define PI 3.14159265
35792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire#define SCALE_FACTOR 0.5
36cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
37cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
38cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
39cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoireconst char *className = "OpenGL";
405a3f319956efad8d107e314619f2ed17986d072fNicolas Capensconst char *windowName = "OpenGL Cube";
41cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoireint winX = 0, winY = 0;
42cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoireint winWidth = 300, winHeight = 300;
43792950afd707a12129af8291117b63a91eaf229bMaxime Gregoirefloat angle = 0.1f;
44cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoiredouble theta = angle * PI / 180.0;
45792950afd707a12129af8291117b63a91eaf229bMaxime Gregoireint listIndex;
46792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire
47792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire// Rotation matrix
48cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireGLfloat R[16] = { 1, 0, 0, 0, 0, cos(theta), -sin(theta), 0, 0, sin(theta), cos(theta), 0, 0, 0, 0, 1 };
49cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
50792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire// Scaling matrix
51792950afd707a12129af8291117b63a91eaf229bMaxime GregoireGLfloat S[16] = { SCALE_FACTOR, 0, 0, 0, 0, SCALE_FACTOR, 0, 0, 0, 0, SCALE_FACTOR, 0, 0, 0, 0, 1 };
52792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire
53cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireHDC hDC;
54cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireHGLRC hGLRC;
55792950afd707a12129af8291117b63a91eaf229bMaxime GregoireHPALETTE hPalette;
56cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
57792950afd707a12129af8291117b63a91eaf229bMaxime GregoireGLfloat vertices1[] = {
58cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0.5F, 0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F,
59cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	-0.5F, -0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F, -0.5F, -0.5F,
60cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0.5F, 0.5F, 0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F,
61cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	-0.5F, -0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F,
62cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0.5F, 0.5F, 0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F, -0.5F,
63cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	-0.5F, -0.5F, -0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F, -0.5F
64cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire};
65cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
66792950afd707a12129af8291117b63a91eaf229bMaxime GregoireGLfloat normals1[] = {
67cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
68cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
69cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
70cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
71792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
72cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0
73cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire};
74cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
75792950afd707a12129af8291117b63a91eaf229bMaxime GregoireGLfloat colors1[] = {
76cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,
77cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0,
78cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,
79cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
80cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0,
81cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1
82792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire};
83cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
84cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoirevoid initializeView(void)
85cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
86cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Set viewing projection
87cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glMatrixMode(GL_PROJECTION);
88fec8129f5146bc317e2ca59f444c9ec063376cf3Maxime Gregoire	glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
89cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
90cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Position viewer
91cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glMatrixMode(GL_MODELVIEW);
92cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glTranslatef(0.0F, 0.0F, -2.0F);
93cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
94cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Position object
95cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glRotatef(30.0F, 1.0F, 0.0F, 0.0F);
96792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	glRotatef(30.0F, 0.0F, 1.0F, 0.0F);
97cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
98cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEnable(GL_DEPTH_TEST);
99cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEnable(GL_COLOR_MATERIAL);
100792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire}
101cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
102792950afd707a12129af8291117b63a91eaf229bMaxime Gregoirevoid initDisplayList(void)
103792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire{
104792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	listIndex = glGenLists(1);
105792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	glNewList(listIndex, GL_COMPILE);
106cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glNormalPointer(GL_FLOAT, 0, normals1);
107cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glColorPointer(3, GL_FLOAT, 0, colors1);
108cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glVertexPointer(3, GL_FLOAT, 0, vertices1);
109cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
110cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEnableClientState(GL_NORMAL_ARRAY);
111cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEnableClientState(GL_COLOR_ARRAY);
112cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEnableClientState(GL_VERTEX_ARRAY);
113cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
114cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glPushMatrix();
115792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	glMultMatrixf(S);
116cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glDrawArrays(GL_QUADS, 0, 24);
117cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glPopMatrix();
118cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
119cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glDisableClientState(GL_VERTEX_ARRAY);
120cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glDisableClientState(GL_COLOR_ARRAY);
121cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glDisableClientState(GL_NORMAL_ARRAY);
122cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glEndList();
123cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}
124cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
125cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoirevoid redraw(void)
126cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
127cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
128cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glCallList(listIndex);
12929fa07fddcd1a3da060d04651e28dccc42b53904Nicolas Capens
130792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	// Rotation
131792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	glMultMatrixf(R);
132792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire
133cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	SwapBuffers(hDC);
134cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}
135cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
136cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoirevoid resize(void)
137cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
138cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Set viewport to cover the window
139cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	glViewport(0, 0, winWidth, winHeight);
140cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}
141cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
142cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoirevoid setupPixelFormat(HDC hDC)
143cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
144cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	PIXELFORMATDESCRIPTOR pfd = {
145cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		sizeof(PIXELFORMATDESCRIPTOR),  // Size
146cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		1,                              // Version
147cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PFD_SUPPORT_OPENGL |
148cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PFD_DRAW_TO_WINDOW |
149cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PFD_DOUBLEBUFFER,               // Support double-buffering
150cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PFD_TYPE_RGBA,                  // Color type
151cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		16,                             // Prefered color depth
152cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0, 0, 0, 0, 0, 0,               // Color bits (ignored)
153cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // No alpha buffer
154cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // Alpha bits (ignored)
155cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // No accumulation buffer
156cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0, 0, 0, 0,                     // Accum bits (ignored)
157cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		16,                             // Depth buffer
158cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // No stencil buffer
159cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // No auxiliary buffers
160cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PFD_MAIN_PLANE,                 // Main layer
161cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0,                              // Reserved
162cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		0, 0, 0,                        // No layer, visible, damage masks
163cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	};
164cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	int pixelFormat;
165cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
166cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	pixelFormat = ChoosePixelFormat(hDC, &pfd);
167cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	if(pixelFormat == 0) {
168cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		MessageBox(WindowFromDC(hDC), L"ChoosePixelFormat failed.", L"Error",
169cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			MB_ICONERROR | MB_OK);
170cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		exit(1);
171cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	}
172cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
173cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	if(SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
174cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		MessageBox(WindowFromDC(hDC), L"SetPixelFormat failed.", L"Error",
175cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			MB_ICONERROR | MB_OK);
176cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		exit(1);
177cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	}
178cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}
179cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
180a818c45371a81739aeb521dca24ba74ca6a4d38bAlexis Hetuint __stdcall WinMain(__in HINSTANCE hCurrentInst, __in_opt HINSTANCE hPreviousInst, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
181cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
182cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	WNDCLASS wndClass;
183cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	HWND hWnd;
184cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	MSG msg;
185cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
186cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Register window class
187cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
188cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.lpfnWndProc = WndProc;
189cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.cbClsExtra = 0;
190cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.cbWndExtra = 0;
191cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.hInstance = hCurrentInst;
192cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
193cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
194cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.hbrBackground = (HBRUSH)BLACK_BRUSH;
195cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.lpszMenuName = NULL;
196cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wndClass.lpszClassName = L"OpenGL cube";
197cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	RegisterClass(&wndClass);
198cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
199cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Create window
200cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	hWnd = CreateWindow(
201cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		L"OpenGL cube", L"OpenGL",
202cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		WS_OVERLAPPEDWINDOW,
203cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		winX, winY, winWidth, winHeight,
204cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		NULL, NULL, hCurrentInst, NULL);
205cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
206cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	// Display window
207cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	ShowWindow(hWnd, nShowCmd);
208792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire
209792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	hDC = GetDC(hWnd);
210792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	setupPixelFormat(hDC);
211792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	hGLRC = wglCreateContext(hDC);
212792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	wglMakeCurrent(hDC, hGLRC);
213792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	initializeView();
214792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire	initDisplayList();
215792950afd707a12129af8291117b63a91eaf229bMaxime Gregoire
216cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	while(true)
217cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	{
218cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
219cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		{
220cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			if(msg.message == WM_QUIT)
221cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			{
222cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire				break;
223cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			}
224cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
225cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			TranslateMessage(&msg);
226cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			DispatchMessage(&msg);
227cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
228cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		else
229cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		{
230cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			redraw();
231cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
232cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	}
233cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
234cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wglMakeCurrent(NULL, NULL);
235cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	wglDeleteContext(hGLRC);
236cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	ReleaseDC(hWnd, hDC);
237cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
238cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	return msg.wParam;
239cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}
240cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
241cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime GregoireLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
242cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire{
243cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	switch(message) {
244cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	case WM_DESTROY:
245cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		// Finish OpenGL rendering
246cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(hGLRC) {
247cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			wglMakeCurrent(NULL, NULL);
248cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			wglDeleteContext(hGLRC);
249cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
250cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(hPalette) {
251cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			DeleteObject(hPalette);
252cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
253cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		ReleaseDC(hWnd, hDC);
254cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		PostQuitMessage(0);
255cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		return 0;
256cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	case WM_SIZE:
257cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		// Track window size changes
258cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(hGLRC) {
259cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			winWidth = (int)LOWORD(lParam);
260cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			winHeight = (int)HIWORD(lParam);
261cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			resize();
262cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			return 0;
263cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
264cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	case WM_PALETTECHANGED:
265cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		// Realize palette if this is *not* the current window
266cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(hGLRC && hPalette && (HWND)wParam != hWnd) {
267cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			UnrealizeObject(hPalette);
268cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			SelectPalette(hDC, hPalette, FALSE);
269cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			RealizePalette(hDC);
270cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			redraw();
271cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			break;
272cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
273cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		break;
274cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	case WM_QUERYNEWPALETTE:
275cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		// Realize palette if this is the current window
276cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		if(hGLRC && hPalette) {
277cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			UnrealizeObject(hPalette);
278cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			SelectPalette(hDC, hPalette, FALSE);
279cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			RealizePalette(hDC);
280cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire			return TRUE;
281cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		}
282cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		break;
283cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	default:
284cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire		break;
285cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	}
286cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire
287cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire	return DefWindowProc(hWnd, message, wParam, lParam);
288cf72c8cd12b8e2bff4298445adb6a6f345f1d79fMaxime Gregoire}