admin 管理员组文章数量: 1184232
outdated: 24.Tokens, Extensions, Scissor Testing And TGA Loading
这一篇主要说的是,怎样实现在窗口中裁剪一个小的视图窗口(即glScissor()函数)?以及对glGetString()函数的应用。
在本文中,用到的贴图材质是TGA格式图片,相对于JPG格式,会更加清晰,因使用不失真的压缩。不了解TGA格式图片的可以看看这篇。基于对TGA格式的了解,具有独有的一个8位的Alpha通道。在其代码中,在24位和32位之间来转换,差的8位即为Alpha。所以,一开始会有一个变量type,默认为32位---GL_RGBA。支持扩展是很好的一个特性,使得DrawGLScene()函数中的glGetString()函数可以使用。
LoadTGA()函数中,只会加载24位和32位的TGA,首先第一个变量,
GLubyte TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 在与所读文件前12个字节比较后,确保是Targa文件。
下一个变量,
GLubyte header[6];
读取宽(位置)、高(位置)和每像素值的比特位,共6字节。
glPrint函数中的glScalef()函数用来设置字体的形变。
DrawGLScene()函数中的glGetString()函数,其参数有四个,依次为渲染器,渲染器出处,渲染器版本,支持的扩展。
| Meaning | |
|---|---|
| Returns the company responsible for this OpenGL implementation. This name does not change from release to release. |
| Returns the name of the renderer. This name is typically specific to a particular configuration of a hardware platform. It does not change from release to release. |
| Returns a version or release number. |
| Returns a space-separated list of supported extensions to OpenGL. |
glScissor()函数,设置一个小窗口,当然都是在windows窗体的限制内。
void WINAPI glScissor(GLint x,GLint y,GLsizei width,GLsizei height );
下面为代码,同样修改部分位于双行星号内。
1 #include <windows.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <math.h>
5 #include <string.h>
6 #include <gl/glew.h>
7 #include <gl/glut.h>
8 #include <GL/GLUAX.H>
9 #include <GL/glext.h>
10 #pragma comment(lib, "legacy_stdio_definitions.lib")
11
12 /*
13 * Every OpenGL program is linked to a Rendering Context.
14 * A Rendering Context is what links OpenGL calls to the Device Context.
15 * In order for your program to draw to a Window you need to create a Device Context.
16 * The DC connects the Window to the GDI (Graphics Device Interface).
17 */
18
19 HGLRC hRC = NULL; // Permanent rendering context
20 HDC hDC = NULL; // Private GDI device context
21 HWND hWnd = NULL; // Holds our window handle
22 HINSTANCE hInstance; // Holds the instance of the application
23
24 /*
25 * It's important to make this global so that each procedure knows if
26 * the program is running in fullscreen mode or not.
27 */
28
29 bool keys[256]; // Array used for the keyboard routine
30 bool active = TRUE; // Window active flag set to TRUE by default
31 bool fullscreen = TRUE; // Fullscreen flag set to fullscreen mode by default
32 /******************************************************************************************************************************************/
33 /******************************************************************************************************************************************/
34 int scroll; // Used for scrolling the screen
35 int maxtokens; // Keeps track of the number of extensions supported
36 int swidth; // Scissor width
37 int sheight; // Scissor height
38
39 GLuint base; // Base display list for the font
40
41 typedef struct {
42 GLubyte* imageData;
43 GLuint bpp; // Image color depth in bits per pixel
44 GLuint width;
45 GLuint height;
46 GLuint texID; // Texture ID used to select a texture
47 } TextureImage;
48
49 TextureImage texture[1];
50
51 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc
52
53 bool LoadTGA(TextureImage* texture, char* filename) // Loads a TGA filr into memory
54 {
55 GLubyte TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Uncompressed TGA
56 GLubyte TGAcompare[12]; // Used to compare TGA header
57 GLubyte header[6]; // First 6 useful bytes from the header
58 GLuint bytesPerpixel; // Holds number of byte per pixel used in the TGA file
59
60 GLuint imageSize; // Used to store the image size when setting aside ram
61 GLuint temp; // Temporary variable
62 GLuint type = GL_RGBA; // Set the default GL mode to RGBA (32 bpp)
63
64 FILE* file = fopen(filename, "rb");
65
66 if ((file == NULL) || // Dose file even exits
67 (fread(TGAcompare, 1, sizeof(TGAcompare), file) != sizeof(TGAcompare)) || // Are there 12 bytes to read
68 (memcmp(TGAheader, TGAcompare, sizeof(TGAheader)) != 0) || // Dose the header match what we want
69 (fread(header, 1, sizeof(header), file) != sizeof(header))) // If so read next 6 header bytes
70 {
71 if (file == NULL) {
72 return false;
73 }
74 else {
75 fclose(file);
76 return false;
77 }
78 }
79 texture->width = header[1] * 256 + header[0]; // Determine the TGA width (highbyte * 256 + lowbyte)
80 texture->height = header[3] * 256 + header[2]; // Determine the TGA height (highbyte * 256 + lowbyte)
81
82 if (texture->width <= 0 || texture->height <= 0 || (header[4] != 24 && header[4] != 32)) {
83 fclose(file);
84 return false;
85 }
86
87 texture->bpp = header[4]; // Grab the TGA's bits per pixel (24 or 32)
88 bytesPerpixel = texture->bpp / 8; // Divide by 8 to get the bytes per pixel
89 // Calculate the memory required for the TGA data
90 imageSize = texture->width * texture->height * bytesPerpixel;
91
92 texture->imageData = (GLubyte*)malloc(imageSize); // Resever memory to hold the TGA data
93
94 if (texture->imageData == NULL ||
95 fread(texture->imageData, 1, imageSize, file) != imageSize)
96 {
97 if (texture->imageData == NULL) {
98 free(texture->imageData);
99 }
100 fclose(file);
101 return false;
102 }
103
104 for (GLuint i = 0; i < int(imageSize); i += bytesPerpixel) {
105 temp = texture->imageData[i]; // Swap the 1st and 3rd bytes (R and B)
106 texture->imageData[i] = texture->imageData[i + 2];
107 texture->imageData[i + 2] = temp;
108 }
109 fclose(file);
110
111 // Build a texture from the data
112 glGenTextures(1, &texture[0].texID);
113
114 glBindTexture(GL_TEXTURE_2D, texture[0].texID);
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117
118 // The TGA was 24 bit, the type will be GL_RGB, the TGA was 32 bit, the type would be GL_RGBA
119 if (texture[0].bpp == 24) {
120 type = GL_RGB;
121 }
122
123 glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type,
124 GL_UNSIGNED_BYTE, texture[0].imageData);
125 return true;
126 }
127
128 GLvoid BuildFont(GLvoid)
129 {
130 base = glGenLists(256);
131 glBindTexture(GL_TEXTURE_2D, texture[0].texID);
132
133 for (int loop = 0; loop < 256; ++loop) {
134 float cx = float(loop % 16) / 16.0f; // X position of current character
135 float cy = float(loop / 16) / 16.0f; // Y position of current character
136 glNewList(base + loop, GL_COMPILE);
137 glBegin(GL_QUADS);
138 glTexCoord2f(cx, 1.0f - cy - 0.0625f); // Texture coord
139 glVertex2d(0, 16); // Vertex coord
140 glTexCoord2f(cx + 0.0625f, 1.0f - cy - 0.0625f);
141 glVertex2i(16, 16);
142 glTexCoord2f(cx + 0.0625f, 1.0f - cy - 0.001f);
143 glVertex2i(16, 0);
144 glTexCoord2f(cx, 1.0f - cy - 0.001f);
145 glVertex2i(0, 0);
146 glEnd();
147 glTranslated(14, 0, 0);
148 glEndList();
149 }
150 }
151
152 GLvoid KillFont(GLvoid)
153 {
154 glDeleteLists(base, 256);
155 }
156
157 GLvoid glPrint(GLint x, GLint y, int set, const char* fmt, ...)
158 {
159 char text[1024];
160 va_list ap; // Pointer to list of arguments
161
162 if (fmt == NULL) {
163 return;
164 }
165
166 va_start(ap, fmt); // Parses the string for variables
167 vsprintf(text, fmt, ap); // And converts symbols to actual
168 va_end(ap); // Result are stored in text
169
170 if (set > 1) {
171 set = 1;
172 }
173 glEnable(GL_TEXTURE_2D);
174 glLoadIdentity();
175 glTranslated(x, y, 0);
176 glListBase(base - 32 + (128 * set)); // Choose the font set (0 or 1)
177
178 glScalef(1.0f, 2.0f, 1.0f); // Make the text 2X taller
179
180 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Write the text to the screen
181
182 glDisable(GL_TEXTURE_2D);
183 }
184
185 GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window
186 {
187 swidth = width; // Set scissor width to window width
188 sheight = height;
189
190 if (height == 0) { // Prevent a divide by zero by
191 height = 1; // Making height equal one
192 }
193
194 glViewport(0, 0, width, height); // Reset the current viewport
195
196 /*
197 * The following lines set the screen up for a perspective view.
198 * Meaning things in the distance get smaller. This creates a realistic looking scene.
199 * The perspective is calculated with a 45 degree viewing angle based on
200 * the windows width and height. The 0.1f, 100.0f is the starting point and
201 * ending point for how deep we can draw into the screen.
202 *
203 * The projection matrix is responsible for adding perspective to our scene.
204 * glLoadIdentity() restores the selected matrix to it's original state.
205 * The modelview matrix is where our object information is stored.
206 * Lastly we reset the modelview matrix.
207 */
208
209 glMatrixMode(GL_PROJECTION); // Select the projection matrix
210 glLoadIdentity(); // Reset the projection matrix
211
212 // Calculate the aspect ratio of the window
213 // gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
214 glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f); // Create orhto 640X480 view (0, 0, at the top)
215
216 glMatrixMode(GL_MODELVIEW); // Seclet the modelview matrix
217 glLoadIdentity(); // Reset the modelview matrix
218 }
219
220 int InitGL(GLvoid) // All setup for OpenGL goes here
221 {
222 if (!LoadTGA(&texture[0], "Font.tga")) {
223 return FALSE;
224 }
225
226 BuildFont();
227
228 glShadeModel(GL_SMOOTH); // Enables smooth shading
229 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background
230
231 glClearDepth(1.0f); // Depth buffer setup
232
233 glBindTexture(GL_TEXTURE_2D, texture[0].texID);
234
235 return TRUE;
236 }
237 /*
238 * For now all we will do is clear the screen to the color we previously decided on,
239 * clear the depth buffer and reset the scene. We wont draw anything yet.
240 */
241 int DrawGLScene(GLvoid) // Here's where we do all the drawing
242 {
243 char* token; // Storage for our token
244 int cnt = 0; // Loacl counter variable
245
246 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
247
248 glColor3f(1.0f, 0.5f, 0.5f);
249 glPrint(50, 16, 1, "Renderer");
250 glPrint(80, 48, 1, "Vendor");
251 glPrint(66, 80, 1, "Version");
252
253 glColor3f(1.0f, 0.7f, 0.4f);
254 glPrint(200, 16, 1, (char*)glGetString(GL_RENDERER));
255 glPrint(200, 48, 1, (char*)glGetString(GL_VENDOR));
256 glPrint(200, 80, 1, (char*)glGetString(GL_VERSION));
257
258 glColor3f(0.5f, 0.5f, 1.0f);
259 glPrint(250, 432, 1, "OpenGl");
260
261 glLoadIdentity();
262 glColor3f(1.0f, 1.0f, 1.0f);
263 glBegin(GL_LINE_STRIP);
264 glVertex2d(639, 417);
265 glVertex2d(0, 417);
266 glVertex2d(0, 480);
267 glVertex2d(639, 480);
268 glVertex2d(639, 128);
269 glEnd();
270 glBegin(GL_LINE_STRIP);
271 glVertex2d(0, 128);
272 glVertex2d(639, 128);
273 glVertex2d(639, 1);
274 glVertex2d(0, 1);
275 glVertex2d(0, 417);
276 glEnd();
277
278 glScissor(1, int(0.135416f * sheight), swidth - 2, int(0.597916f * sheight)); // Define scissor region
279 glEnable(GL_SCISSOR_TEST);
280 // Allocate memory for our extension string
281 char* text = (char*)malloc(strlen((char*)glGetString(GL_EXTENSIONS)) + 1);
282 strcpy(text, (char*)glGetString(GL_EXTENSIONS)); // Grab the extension list, store in text
283
284 token = strtok(text, " ");
285 while (token != NULL) {
286 cnt++;
287 if (cnt > maxtokens) {
288 maxtokens = cnt;
289 }
290
291 glColor3f(0.5f, 1.0f, 0.5f);
292 glPrint(0, 96 + (cnt * 32) - scroll, 0, "%i", cnt); // Print the current extension number
293
294 glColor3f(1.0f, 1.0f, 0.5f);
295 glPrint(50, 96 + (cnt * 32) - scroll, 0, token); // Print the current token extension name
296
297 token = strtok(NULL, " "); // Serch for the next token
298 }
299
300 glDisable(GL_SCISSOR_TEST);
301 free(text);
302
303 glFlush();
304 return true;
305 }
306 /******************************************************************************************************************************************/
307 /******************************************************************************************************************************************/
308 /*
309 * The job of KillGLWindow() is to release the Rendering Context,
310 * the Device Context and finally the Window Handle.
311 */
312
313 GLvoid KillGLWindow(GLvoid) // Properly kill the window
314 {
315 if (fullscreen) { // Are we in fullscreen mode
316
317 /*
318 * We use ChangeDisplaySettings(NULL,0) to return us to our original desktop.
319 * After we've switched back to the desktop we make the cursor visible again.
320 */
321
322 ChangeDisplaySettings(NULL, 0); // if so switch back to the desktop
323 ShowCursor(TRUE); // Show mouse pointer
324 }
325
326 if (hRC) { // Do we have a rendering context
327 if (!wglMakeCurrent(NULL, NULL)) { // Are we able to release the DC and RC contexts
328 MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
329 }
330
331 if (!wglDeleteContext(hRC)) { // Are we able to delete the RC
332 MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
333 hRC = NULL; // Set RC to NULL
334 }
335
336 if (hDC && !ReleaseDC(hWnd, hDC)) { // Are we able to release the DC
337 MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
338 hDC = NULL; // Set DC to NULL
339 }
340 if (hWnd && !DestroyWindow(hWnd)) { // Are we able to destroy the window
341 MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
342 hWnd = NULL; // Set hWnd to NULL
343 }
344
345 if (!UnregisterClass("OpenGL", hInstance)) { // Are we able to unregister class
346 MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
347 hInstance = NULL; // Set hInstance to NULL
348 }
349 }
350 /******************************************************************************************************************************************/
351 /******************************************************************************************************************************************/
352 KillFont();
353 /******************************************************************************************************************************************/
354 /******************************************************************************************************************************************/
355 }
356
357 /*
358 * The next section of code creates our OpenGL Window.
359 */
360
361 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
362 {
363 /*
364 * Find a pixel format that matches the one we want
365 */
366 GLuint PixelFormat; // Holds the result after serching for a match
367
368 /*
369 * Before you create a window, you MUST register a Class for the window
370 */
371 WNDCLASS wc; // Windows class structure
372
373 /*
374 * dwExStyle and dwStyle will store the Extended and normal Window Style Information.
375 */
376 DWORD dwExStyle; // Window extend style
377 DWORD dwStyle; // Window style
378
379 RECT WindowRect; // Grabs rectangle upper left/lower right values
380 WindowRect.left = (long)0; // Set left value to 0
381 WindowRect.right = (long)width; // Set right value to requested width
382 WindowRect.top = (long)0; // Set top value to 0
383 WindowRect.bottom = (long)height; // Set bottom value to requested height
384
385 fullscreen = fullscreenflag; // Set the global fullscreen flag
386
387 /*
388 * The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized.
389 * CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications.
390 * WndProc is the procedure that watches for messages in our program.
391 * No extra Window data is used so we zero the two fields. Then we set the instance.
392 * Next we set hIcon to NULL meaning we don't want an ICON in the Window,
393 * and for a mouse pointer we use the standard arrow. The background color doesn't matter
394 * (we set that in GL). We don't want a menu in this Window so we set it to NULL,
395 * and the class name can be any name you want. I'll use "OpenGL" for simplicity.
396 */
397 hInstance = GetModuleHandle(NULL); // Grab an instance for our window
398 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on move, and own DC for window
399 wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc handles message
400 wc.cbClsExtra = 0; // No extra window date
401 wc.cbWndExtra = 0; // No extra window date
402 wc.hInstance = hInstance; // set the instance
403 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon
404 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer
405 wc.hbrBackground = NULL; // No background requried for GL
406 wc.lpszMenuName = NULL; // We don't want a menu
407 wc.lpszClassName = "OpenGL"; // set the class name
408
409 if (!RegisterClass(&wc)) { // Attempt to register the window class
410 MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
411 return FALSE; // Exit and return false
412 }
413
414 if (fullscreen) { // attempt fullsreen model
415
416 /*
417 T* here are a few very important things you should keep in mind when switching to full screen mode.
418 * Make sure the width and height that you use in fullscreen mode is the same as
419 * the width and height you plan to use for your window, and most importantly,
420 * set fullscreen mode BEFORE you create your window.
421 */
422 DEVMODE dmScreenSettings; // Device mode
423 memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory's cleared
424 dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of devmode structure
425 dmScreenSettings.dmPelsWidth = width; // Select window width
426 dmScreenSettings.dmPelsHeight = height; // Select window height
427 dmScreenSettings.dmBitsPerPel = bits; // Select bits per pixel
428 dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
429
430 /*
431 * In the line below ChangeDisplaySettings tries to switch to a mode that matches
432 * what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes,
433 * because it's supposed to remove the start bar at the bottom of the screen,
434 * plus it doesn't move or resize the windows on your desktop when you switch to
435 * fullscreen mode and back.
436 */
437 //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar
438 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
439 //If the mode fails, offer two options. Quit or run in a window
440 if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use"
441 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
442 {
443 fullscreen = FALSE; // Select windowed mode (fullscreen=FLASE)
444 }
445 else {
446 // Pop up a message box letting user know the programe is closing.
447 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP);
448 return FALSE; // Exit and return FALSE
449 }
450 }
451 }
452
453 if (fullscreen) { // Are we still in fullscreen mode
454
455 /*
456 * If we are still in fullscreen mode we'll set the extended style to WS_EX_APPWINDOW,
457 * which force a top level window down to the taskbar once our window is visible.
458 * For the window style we'll create a WS_POPUP window.
459 * This type of window has no border around it, making it perfect for fullscreen mode.
460
461 * Finally, we disable the mouse pointer. If your program is not interactive,
462 * it's usually nice to disable the mouse pointer when in fullscreen mode. It's up to you though.
463 */
464 dwExStyle = WS_EX_APPWINDOW; // Window extended style
465 dwStyle = WS_POPUP; // Window style
466 ShowCursor(FALSE); // Hide mosue pointer
467 }
468 else {
469
470 /*
471 * If we're using a window instead of fullscreen mode,
472 * we'll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look.
473 * For style we'll use WS_OVERLAPPEDWINDOW instead of WS_POPUP.
474 * WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border,
475 * window menu, and minimize / maximize buttons.
476 */
477 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style
478 dwStyle = WS_OVERLAPPEDWINDOW; // Window style
479 }
480
481 /*
482 * By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders,
483 * instead, the window will be made larger to account for the pixels needed to draw the window border.
484 * In fullscreen mode, this command has no effect.
485 */
486 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust window to true resqusted
487
488 /*
489 * WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly.
490 * These styles prevent other windows from drawing over or into our OpenGL Window.
491 */
492 if (!(hWnd = CreateWindowEx(dwExStyle, // Extended style for the window
493 "OpenGL", // Class name
494 title, // Window title
495 WS_CLIPSIBLINGS | // Requried window style
496 WS_CLIPCHILDREN | // Requried window style
497 dwStyle, // Select window style
498 0, 0, // Window position
499 WindowRect.right - WindowRect.left, // Calculate adjusted window width
500 WindowRect.bottom - WindowRect.top, // Calculate adjusted window height
501 NULL, // No parent window
502 NULL, // No menu
503 hInstance, // Instance
504 NULL))) // Don't pass anything to WM_CREATE
505 {
506 KillGLWindow(); //Reset the display
507 MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
508 return FALSE; // Retrurn FALSE;
509 }
510
511 /*
512 * aside from the stencil buffer and the (slow) accumulation buffer
513 */
514 static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be
515 {
516 sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor
517 1, // Version number
518 PFD_DRAW_TO_WINDOW | // Format must support window
519 PFD_SUPPORT_OPENGL | // Format must support OpenGL
520 PFD_DOUBLEBUFFER, // Must support double buffer
521 PFD_TYPE_RGBA, // Request an RGBA format
522 bits, // Select our color depth
523 0, 0, 0, 0, 0, 0, // Color bits ignored
524 0, // No alpha buffer
525 0, // shift bit ignored
526 0, // No accumulation buffer
527 0, 0, 0, 0, // Accumulation bits ignored
528 16, // 16Bits Z_Buffer (depth buffer)
529 0, // No stencil buffer
530 0, // No auxiliary buffer
531 PFD_MAIN_PLANE, // Main drawing layer
532 0, // Reserved
533 0, 0, 0 // Layer makes ignored
534 };
535
536 if (!(hDC = GetDC(hWnd))) { // Did we get a device context
537 KillGLWindow(); // Reset the display
538 MessageBox(NULL, "Can't create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
539 return FALSE; // Return FALSE
540 }
541
542 if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { // Did window find a matching pixel format
543 KillGLWindow(); // Reset the display
544 MessageBox(NULL, "Can't find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
545 return FALSE; // Return FALSE;
546 }
547
548 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) { // Are we able to set the pixel format
549 KillGLWindow(); // Reset the display
550 MessageBox(NULL, "Can't set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
551 return FALSE; // Return FALSE;
552 }
553
554 if (!(hRC = wglCreateContext(hDC))) { // Are we able to rendering context
555 KillGLWindow(); // Reset the display
556 MessageBox(NULL, "Can't create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
557 return FALSE; // Return FASLE;
558 }
559
560 if (!wglMakeCurrent(hDC, hRC)) { // Try to activate the rendering context
561 KillGLWindow(); // Reset the display
562 MessageBox(NULL, "Can't activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
563 return FALSE; // Return FALSE
564 }
565
566 /*
567 * ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.
568 */
569 ShowWindow(hWnd, SW_SHOW); // Show the window
570 SetForegroundWindow(hWnd); // slightly higher priority
571 SetFocus(hWnd); // Sets keyboard focus to the window
572 ReSizeGLScene(width, height); // Set up our perspective GL screen
573
574 /*
575 * we can set up lighting, textures, and anything else that needs to be setup in InitGL().
576 */
577 if (!InitGL()) { // Initialize our newly created GL window
578 KillGLWindow(); // Reset the display
579 MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
580 return FALSE; // Return FALSE
581 }
582 return TRUE;
583 }
584
585 LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window
586 UINT uMsg, // Message for this window
587 WPARAM wParam, // Additional message information
588 LPARAM lParam) // Additional message information
589 {
590 switch (uMsg) { // Check for window message
591 case WM_ACTIVATE: { // Check minimization state
592 if (!HIWORD(wParam)) {
593 active = TRUE; // Program is active
594 }
595 else {
596 active = FALSE; // Program is no longer active
597 }
598 return 0; // Return to the message loop
599 }
600 case WM_SYSCOMMAND: { // Intercept system commands
601 switch (wParam) { // Check system calls
602 case SC_SCREENSAVE: // Screensaver trying to start
603 case SC_MONITORPOWER: // Monitor trying to enter powersave
604 return 0; // Prevent form happening
605 }
606 break; // Exit
607 }
608 case WM_CLOSE: { // Did we receive a close message
609 PostQuitMessage(0); // Send a quit message
610 return 0;
611 }
612 case WM_KEYDOWN: { // Is a key being held down
613 keys[wParam] = TRUE; // if so, mark it as TRUE
614 return 0; // Jump back
615 }
616 case WM_KEYUP: { // Has a key been released
617 keys[wParam] = FALSE; // if so, mark it as FALSE
618 return 0; // Jump back
619 }
620 case WM_SIZE: { // Resize the OpenGL window
621 ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord = width HiWord = height
622 return 0; // Jump back
623 }
624 }
625 return DefWindowProc(hWnd, uMsg, wParam, lParam); // Pass all unhandled message to DefWindwProc
626 }
627
628 int WINAPI WinMain(HINSTANCE hInstance, // Instance
629 HINSTANCE hPrevInstance, // Previous instance
630 LPSTR lpCmdLine, // Command line parameters
631 int nCmdShow) // Window show state
632 {
633 MSG msg; // Window message structure
634 BOOL done = FALSE; // Bool variable to exit loop
635 // Ask the user which screen mode they prefer
636 if (MessageBox(NULL, "Would you like to run in fullscreen mode?",
637 "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO)
638 {
639 fullscreen = FALSE; // Window mode
640 }
641 // Create our OpenGL window
642 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { // (Modified)
643 return 0; // Quit if window was not create
644 }
645 /******************************************************************************************************************************************/
646 /******************************************************************************************************************************************/
647
648 while (!done) { // Loop that runs until donw = TRUE
649 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Is there a message wating
650 if (msg.message == WM_QUIT) { // Havw we received a quit message
651 done = TRUE; // if so done = TRUE
652 }
653 else { // If not, deal with window message
654 TranslateMessage(&msg); // Translate message
655 DispatchMessage(&msg); // Dispatch message
656 }
657 }
658 else {
659 // Draw the scene. Watch for ESC key and quit message from DrawGLScene()
660 if (active) { // Program active
661 if (keys[VK_ESCAPE]) { // Was ESC pressed
662 done = TRUE; // ESC signalled a quit
663 }
664 else { // Not time to quit, update screen
665 DrawGLScene(); // Draw scene
666 SwapBuffers(hDC); // Swap buffers (double buffering)
667 }
668 }
669
670 if (keys[VK_UP] && (scroll > 0)) {
671 scroll -= 2;
672 }
673 if (keys[VK_DOWN] && (scroll < 32 * (maxtokens - 9))) {
674 scroll += 2;
675 }
676 /*
677 * It allows us to press the F1 key to switch from fullscreen mode to
678 * windowed mode or windowed mode to fullscreen mode.
679 */
680 if (keys[VK_F1]) { // Is F1 being pressed
681 keys[VK_F1] = FALSE; // If so make key FASLE
682 KillGLWindow(); // Kill our current window
683 fullscreen = !fullscreen; // Toggle fullscreen / window mode
684 //Recreate our OpenGL window(modified)
685 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {
686 return 0; // Quit if window was not create
687 }
688 }
689 }
690 }
691 // Shutdown
692 KillGLWindow(); // Kill the window
693 return (msg.wParam); // Exit the program
694 }
695 /******************************************************************************************************************************************/
696 /******************************************************************************************************************************************/ Thanks for Nehe's tutorials, this is his home.
转载于:.html
本文标签: outdated 24Tokens Extensions Scissor Testing And TGA Loading
版权声明:本文标题:outdated: 24.Tokens, Extensions, Scissor Testing And TGA Loading 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1699066694a326036.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论