/
LAB4-Zadanie1.cpp
618 lines (500 loc) · 15.3 KB
/
LAB4-Zadanie1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
// Lab4-Zadanie-2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <GL/glut.h>
#include <GL/glext.h>
#ifndef WIN32
#define GLX_GLXEXT_LEGACY
#include <GL/glx.h>
#define wglGetProcAddress glXGetProcAddressARB
#endif
#include <stdlib.h>
#include <stdio.h>
#include "colors.h"
#include "targa.h"
// wskaźnik na funkcję glWindowPos2i
PFNGLWINDOWPOS2IPROC glWindowPos2i = NULL;
// stałe do obsługi menu podręcznego
enum
{
TEXTURE_COMPRESSION_FASTEST, // kompresja tekstur - GL_FASTEST
TEXTURE_COMPRESSION_DONT_CARE, // kompresja tekstur - GL_DONT_CARE
TEXTURE_COMPRESSION_NICEST, // kompresja tekstur - GL_NICEST
TEXTURE_LENA, // tekstura lena
TEXTURE_LENA_UNC, // teksura lena nieskompresowana
TEXTURE_LENA_GRAY, // tekstura lena_gray
TEXTURE_LENA_GRAY_UNC, // tekstura lena_gray nieskompresowana
FULL_WINDOW, // aspekt obrazu - całe okno
ASPECT_1_1, // aspekt obrazu 1:1
EXIT // wyjście
};
// aspekt obrazu
int aspect = FULL_WINDOW;
// usunięcie definicji makr near i far
#ifdef near
#undef near
#endif
#ifdef far
#undef far
#endif
// rozmiary bryły obcinania
const GLdouble left = -2.0;
const GLdouble right = 2.0;
const GLdouble bottom = -2.0;
const GLdouble top = 2.0;
const GLdouble near = 3.0;
const GLdouble far = 7.0;
// identyfikatory tekstur
GLuint LENA, LENA_UNC, LENA_GRAY, LENA_GRAY_UNC;
// identyfikator bieżącej tekstury;
GLuint texture;
// wskazówki do kompresji tekstur
GLint texture_compression_hint = GL_DONT_CARE;
// funkcja rysująca napis w wybranym miejscu
// (wersja korzystająca z funkcji glWindowPos2i)
void DrawString(GLint x, GLint y, char *string)
{
// położenie napisu
glWindowPos2i(x, y);
// wyświetlenie napisu
int len = strlen(string);
for (int i = 0; i < len; i++)
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}
// funkcja generująca scenę 3D
void DisplayScene()
{
// kolor tła - zawartość bufora koloru
glClearColor(1.0, 1.0, 1.0, 1.0);
// czyszczenie bufora koloru
glClear(GL_COLOR_BUFFER_BIT);
// wybór macierzy modelowania
glMatrixMode(GL_MODELVIEW);
// macierz modelowania = macierz jednostkowa
glLoadIdentity();
// przesunięcie układu współrzędnych obiektów do środka bryły odcinania
glTranslatef(0.0, 0.0, -(near + far) / 2);
// przesunięcie obiektu z teksturą do góry okna
glTranslatef(0.0, 1.0, 0.0);
// włączenie teksturowania dwuwymiarowego
glEnable(GL_TEXTURE_2D);
// ustawienie parametów środowiska tekstur
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// dowiązanie stanu tekstury
glBindTexture(GL_TEXTURE_2D, texture);
// filtr powiàkszający
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// filtr pomniejszający
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// narysowanie kwadratu z teksturą
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(-1.5, -1.5);
glTexCoord2f(0.0, 1.0);
glVertex2f(-1.5, 1.5);
glTexCoord2f(1.0, 1.0);
glVertex2f(1.5, 1.5);
glTexCoord2f(1.0, 0.0);
glVertex2f(1.5, -1.5);
glEnd();
// wyłączenie teksturowania dwuwymiarowego
glDisable(GL_TEXTURE_2D);
// wyświetlenie wybranych informacji
char string[200];
GLint var;
glColor3fv(Black);
// informacja czy tekstura jest skompresowana
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &var);
if (var == GL_FALSE)
sprintf(string, "GL_TEXTURE_COMPRESSED = GL_FALSE");
else
sprintf(string, "GL_TEXTURE_COMPRESSED = GL_TRUE");
DrawString(2, 2, string);
// rozmiar danych tekstury
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &var);
sprintf(string, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE = %i", var);
DrawString(2, 16, string);
// wewnętrzny format tekstury
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &var);
switch (var)
{
// formaty rozszerzenia EXT_texture_compression_s3tc
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGB_S3TC_DXT1_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT");
break;
// formaty rozszerzenia 3DFX_texture_compression_FXT1
case GL_COMPRESSED_RGB_FXT1_3DFX:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGB_FXT1_3DFX");
break;
case GL_COMPRESSED_RGBA_FXT1_3DFX:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGBA_FXT1_3DFX");
break;
// format rozszerzenia ATI_texture_compression_3dc (nie występuje w pliku glext.h)
case 0x8837:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_COMPRESSED_RGB_3DC_ATI");
break;
// wybrane formaty nieskompresowane
case GL_RED:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_RED");
break;
case GL_GREEN:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_GREEN");
break;
case GL_BLUE:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_BLUE");
break;
case GL_ALPHA:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_ALPHA");
break;
case GL_RGB:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_RGB");
break;
case GL_RGBA:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_RGBA");
break;
case GL_LUMINANCE:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_LUMINANCE");
break;
case GL_LUMINANCE_ALPHA:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = GL_LUMINANCE_ALPHA");
break;
// pozostałe formaty
default:
sprintf(string, "GL_TEXTURE_INTERNAL_FORMAT = nieznany");
break;
}
DrawString(2, 30, string);
// informacja o wskazówkach do kompresji tekstur
glGetIntegerv(GL_TEXTURE_COMPRESSION_HINT, &var);
switch (var)
{
case GL_FASTEST:
sprintf(string, "GL_TEXTURE_COMPRESSION_HINT = GL_FASTEST");
break;
case GL_DONT_CARE:
sprintf(string, "GL_TEXTURE_COMPRESSION_HINT = GL_DONT_CARE");
break;
case GL_NICEST:
sprintf(string, "GL_TEXTURE_COMPRESSION_HINT = GL_NICEST");
break;
}
DrawString(2, 44, string);
// ilość obsługiwanych formatów kompresji tekstur
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &var);
sprintf(string, "GL_NUM_COMPRESSED_TEXTURE_FORMATS = %i", var);
// wykaz obsługiwanych formatów kompresji tekstur
GLint formats[256];
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
for (int i = 0; i < var; i++)
{
switch (formats[i])
{
// formaty rozszerzenia EXT_texture_compression_s3tc
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
sprintf(string, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
sprintf(string, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
sprintf(string, "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT");
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
sprintf(string, "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT");
break;
// formaty rozszerzenia 3DFX_texture_compression_FXT1
case GL_COMPRESSED_RGB_FXT1_3DFX:
sprintf(string, "GL_COMPRESSED_RGB_FXT1_3DFX");
break;
case GL_COMPRESSED_RGBA_FXT1_3DFX:
sprintf(string, "GL_COMPRESSED_RGBA_FXT1_3DFX");
break;
// format rozszerzenia ATI_texture_compression_3dc
// (nie występuje w pliku glext.h)
case 0x8837:
sprintf(string, "GL_COMPRESSED_RGB_3DC_ATI");
break;
// pozostrałe formaty
default:
sprintf(string, "Format nieznany (0x%X)", formats[i]);
break;
}
DrawString(2, 70 + 14 * i, string);
}
// skierowanie poleceń do wykonania
glFlush();
// zamiana buforów koloru
glutSwapBuffers();
}
// zmiana wielkości okna
void Reshape(int width, int height)
{
// obszar renderingu - całe okno
glViewport(0, 0, width, height);
// wybór macierzy rzutowania
glMatrixMode(GL_PROJECTION);
// macierz rzutowania = macierz jednostkowa
glLoadIdentity();
// parametry bryły obcinania
if (aspect == ASPECT_1_1)
{
// wysokość okna większa od wysokości okna
if (width < height && width > 0)
glFrustum(left, right, bottom*height / width, top*height / width, near, far);
else
// szerokość okna większa lub równa wysokości okna
if (width >= height && height > 0)
glFrustum(left*width / height, right*width / height, bottom, top, near, far);
}
else
glFrustum(left, right, bottom, top, near, far);
// generowanie sceny 3D
DisplayScene();
}
// utworzenie list wyświetlania
void GenerateTextures()
{
// zmienne użyte przy obsłudze plików TARGA
GLsizei width, height;
GLenum format, type;
GLvoid *pixels;
// tryb upakowania bajtów danych tekstury
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// wskazówki do kompresji tesktur
glHint(GL_TEXTURE_COMPRESSION_HINT, texture_compression_hint);
// wczytanie tekstury grafika.tga
GLboolean error = load_targa("grafika.tga", width, height, format, type, pixels);
// błąd odczytu pliku
if (error == GL_FALSE)
{
printf("Niepoprawny odczyt pliku grafika.tga");
exit(0);
}
// utworzenie identyfikatora tekstury
glGenTextures(1, &LENA);
// dowiązanie stanu tekstury
glBindTexture(GL_TEXTURE_2D, LENA);
// definiowanie tekstury z kompresją
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, width, height, 0, format, type, pixels);
// utworzenie identyfikatora tekstury
glGenTextures(1, &LENA_UNC);
// dowiązanie stanu tekstury
glBindTexture(GL_TEXTURE_2D, LENA_UNC);
// definiowanie tekstury bez kompresji
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, type, pixels);
// porządki
delete[](unsigned char*)pixels;
// wczytanie tekstury grafika.tga
error = load_targa("grafika.tga", width, height, format, type, pixels);
// błąd odczytu pliku
if (error == GL_FALSE)
{
printf("Niepoprawny odczyt pliku grafika.tga");
exit(0);
}
// utworzenie identyfikatora tekstury
glGenTextures(1, &LENA_GRAY);
// dowiązanie stanu tekstury
glBindTexture(GL_TEXTURE_2D, LENA_GRAY);
// definiowanie tekstury z kompresją
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_LUMINANCE, width, height, 0, format, type, pixels);
// utworzenie identyfikatora tekstury
glGenTextures(1, &LENA_GRAY_UNC);
// dowiązanie stanu tekstury
glBindTexture(GL_TEXTURE_2D, LENA_GRAY_UNC);
// definiowanie tekstury bez kompresji
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, format, type, pixels);
// porządki
delete[](unsigned char*)pixels;
// wybór bieżącej tekstury
texture = LENA;
}
// obsługa menu podręcznego
void Menu(int value)
{
GLint tmp_texture;
switch (value)
{
// kompresja tekstur - GL_FASTEST
case TEXTURE_COMPRESSION_FASTEST:
{
texture_compression_hint = GL_FASTEST;
tmp_texture = texture;
GenerateTextures();
texture = tmp_texture;
DisplayScene();
}
break;
// kompresja tekstur - GL_DONT_CARE
case TEXTURE_COMPRESSION_DONT_CARE:
{
texture_compression_hint = GL_DONT_CARE;
tmp_texture = texture;
GenerateTextures();
texture = tmp_texture;
DisplayScene();
}
break;
// kompresja tekstur - GL_NICEST
case TEXTURE_COMPRESSION_NICEST:
{
texture_compression_hint = GL_NICEST;
tmp_texture = texture;
GenerateTextures();
texture = tmp_texture;
DisplayScene();
}
break;
// tekstura lena
case TEXTURE_LENA:
{
texture = LENA;
DisplayScene();
}
break;
// teksura lena nieskompresowana
case TEXTURE_LENA_UNC:
{
texture = LENA_UNC;
DisplayScene();
}
break;
// tekstura lena_gray
case TEXTURE_LENA_GRAY:
{
texture = LENA_GRAY;
DisplayScene();
}
break;
// tekstura lena_gray nieskompresowana
case TEXTURE_LENA_GRAY_UNC:
{
texture = LENA_GRAY_UNC;
DisplayScene();
}
break;
// obszar renderingu - całe okno
case FULL_WINDOW:
{
aspect = FULL_WINDOW;
Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}
break;
// obszar renderingu - aspekt 1:1
case ASPECT_1_1:
{
aspect = ASPECT_1_1;
Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}
break;
// wyjście
case EXIT:
exit(0);
}
}
// sprawdzenie i przygotowanie obsługi wybranych rozszerzeń
void ExtensionSetup()
{
// pobranie numeru wersji biblioteki OpenGL
const char *version = (char*)glGetString(GL_VERSION);
// odczyt wersji OpenGL
int major = 0, minor = 0;
if (sscanf(version, "%d.%d", &major, &minor) != 2)
{
#ifdef WIN32
printf("Błędny format wersji OpenGL\n");
#else
printf("Bledny format wersji OpenGL\n");
#endif
exit(0);
}
// sprawdzenie czy jest co najmniej wersja 1.4
if (major > 1 || minor >= 4)
{
// pobranie wskaźnika wybranej funkcji OpenGL 1.4
glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress("glWindowPos2i");
}
else
// sprawdzenie czy jest obsługiwane rozszerzenie ARB_window_pos
if (glutExtensionSupported("GL_ARB_window_pos"))
{
// pobranie wskaźnika wybranej funkcji rozszerzenia ARB_window_pos
glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress
("glWindowPos2iARB");
}
else
{
printf("Brak rozszerzenia ARB_window_pos!\n");
exit(0);
}
// sprawdzenie czy jest co najmniej wersja 1.3 OpenGL lub
// czy jest obsługiwane rozszerzenie ARB_texture_compression
if (!(major > 1 || minor >= 3) &&
!glutExtensionSupported("GL_ARB_texture_compression"))
{
printf("Brak rozszerzenia GL_ARB_texture_compression!\n");
exit(0);
}
}
int main(int argc, char *argv[])
{
// inicjalizacja biblioteki GLUT
glutInit(&argc, argv);
// inicjalizacja bufora ramki
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// rozmiary głównego okna programu
glutInitWindowSize(550, 550);
// utworzenie głównego okna programu
glutCreateWindow("Kompresja tekstur");
// dołączenie funkcji generującej scenę 3D
glutDisplayFunc(DisplayScene);
// dołączenie funkcji wywoływanej przy zmianie rozmiaru okna
glutReshapeFunc(Reshape);
// utworzenie podmenu - Tekstura
int MenuTexture = glutCreateMenu(Menu);
glutAddMenuEntry("lena.tga (kompresja)", TEXTURE_LENA);
glutAddMenuEntry("lena.tga (bez kompresji)", TEXTURE_LENA_UNC);
glutAddMenuEntry("lena_gray.tga (kompresja)", TEXTURE_LENA_GRAY);
glutAddMenuEntry("lena_gray.tga (bez kompresji)", TEXTURE_LENA_GRAY_UNC);
// utworzenie podmenu - GL_TEXTURE_COMPRESSION_HINT
int MenuTextureCompressionHint = glutCreateMenu(Menu);
glutAddMenuEntry("GL_FASTEST", TEXTURE_COMPRESSION_FASTEST);
glutAddMenuEntry("GL_DONT_CARE", TEXTURE_COMPRESSION_DONT_CARE);
glutAddMenuEntry("GL_NICEST", TEXTURE_COMPRESSION_NICEST);
// utworzenie podmenu - Aspekt obrazu
int MenuAspect = glutCreateMenu(Menu);
#ifdef WIN32
glutAddMenuEntry("Aspekt obrazu - całe okno", FULL_WINDOW);
#else
glutAddMenuEntry("Aspekt obrazu - cale okno", FULL_WINDOW);
#endif
glutAddMenuEntry("Aspekt obrazu 1:1", ASPECT_1_1);
// menu główne
glutCreateMenu(Menu);
glutAddSubMenu("Tekstura", MenuTexture);
glutAddSubMenu("GL_TEXTURE_COMPRESSION_HINT", MenuTextureCompressionHint);
glutAddSubMenu("Aspekt obrazu", MenuAspect);
#ifdef WIN32
glutAddMenuEntry("Wyjście", EXIT);
#else
glutAddMenuEntry("Wyjscie", EXIT);
#endif
// określenie przycisku myszki obsługującego menu podręczne
glutAttachMenu(GLUT_RIGHT_BUTTON);
// utworzenie tekstur
GenerateTextures();
// sprawdzenie i przygotowanie obsługi wybranych rozszerzeń
ExtensionSetup();
// wprowadzenie programu do obsługi pętli komunikatów
glutMainLoop();
return 0;
}