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