Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOOpenGL.m
Go to the documentation of this file.
1/*
2
3OOOpenGL.m
4
5Oolite
6Copyright (C) 2004-2013 Giles C Williams and contributors
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21MA 02110-1301, USA.
22
23*/
24
25#import "OOOpenGL.h"
26#import "OOLogging.h"
27#import "OOMaths.h"
28#import "OOMacroOpenGL.h"
31
32#ifndef NDEBUG
33static NSString * const kOOLogOpenGLStateDump = @"rendering.opengl.stateDump";
34#endif
35
36static GLfloat sDisplayScaleFactor = 1.0f;
37
38
39BOOL OOCheckOpenGLErrors(NSString *format, ...)
40{
41 GLenum errCode;
42 const GLubyte *errString = NULL;
43 BOOL errorOccurred = NO;
44 va_list args;
45 static BOOL noReenter;
46
47 if (noReenter) return NO;
48 noReenter = YES;
49
51
52 // Short-circut here, because glGetError() is quite expensive.
54 {
55 for (;;)
56 {
57 errCode = glGetError();
58
59 if (errCode == GL_NO_ERROR) break;
60
61 errorOccurred = YES;
62 errString = gluErrorString(errCode);
63 if (format == nil) format = @"<unknown>";
64
65 va_start(args, format);
66 format = [[[NSString alloc] initWithFormat:format arguments:args] autorelease];
67 va_end(args);
68 OOLog(kOOLogOpenGLError, @"OpenGL error: \"%s\" (%#x), context: %@", errString, errCode, format);
69 }
70 }
71
72#if OO_CHECK_GL_HEAVY
73 if (errorOccurred)
74 {
78 while (glGetError() != 0) {} // Suppress any errors caused by LogOpenGLState().
79 }
80#endif
81
82 noReenter = NO;
83 return errorOccurred;
84}
85
86
88{
90
91 /* Because of where this is called relative to the
92 * OpenGLStateManager methods, pushAttrib/popAttrib causes the
93 * OpenGL state to move away from where it should be. So, instead,
94 * just switch polygon mode as needed. Linewidth is set already by
95 * everything that needs it and not handled by the state
96 * manager. - CIM*/
97// OOGL(glPushAttrib(GL_POLYGON_BIT | GL_LINE_BIT | GL_TEXTURE_BIT));
99 OOGL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
100}
101
102
104{
106 OOGL(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
107// OOGL(glPopAttrib());
108}
109
110
111void GLDrawBallBillboard(GLfloat radius, GLfloat step, GLfloat z_distance)
112{
113 if (EXPECT_NOT((radius <= 0)||(step < 1))) return;
114 if (EXPECT_NOT(radius >= z_distance)) return; // inside the sphere
115
116 GLfloat i, delta;
117 GLfloat s, c;
118 GLfloat r;
119
121
122 r = radius * z_distance / sqrt(z_distance * z_distance - radius * radius);
123 delta = step * M_PI / 180.0f; // Convert step from degrees to radians
124
125 glVertex3i(0, 0, 0);
126 for (i = 0; i < (M_PI * 2.0); i += delta)
127 {
128 s = r * sin(i);
129 c = r * cos(i);
130 glVertex3f(s, c, 0.0);
131 }
132 glVertex3f(0.0, r, 0.0); //repeat the zero value to close
133}
134
135
136static void GLDrawOvalPoints(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
137{
138 GLfloat ww = 0.5 * siz.width;
139 GLfloat hh = 0.5 * siz.height;
140 GLfloat theta;
141 GLfloat delta;
142
144
145 delta = step * M_PI / 180.0f;
146
147 for (theta = 0.0f; theta < (2.0f * M_PI); theta += delta)
148 {
149 glVertex3f(x + ww * sin(theta), y + hh * cos(theta), z);
150 }
151 glVertex3f(x, y + hh, z);
152}
153
154
155void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
156{
158
159 OOGLBEGIN(GL_LINE_STRIP);
160 GLDrawOvalPoints(x, y, z, siz, step);
161 OOGLEND();
162}
163
164
165void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
166{
168
169 OOGLBEGIN(GL_TRIANGLE_FAN);
170 GLDrawOvalPoints(x, y, z, siz, step);
171 OOGLEND();
172}
173
174void GLDrawPoints(OOGLVector *points, int n)
175{
176 int i;
178 OOGLBEGIN(GL_LINE_STRIP);
179 for (i = 0; i < n; i++)
180 {
181 glVertex3f(points->x, points->y, points->z);
182 points++;
183 }
184 OOGLEND();
185 return;
186}
187
188void GLDrawFilledPoints(OOGLVector *points, int n)
189{
190 int i;
192 OOGLBEGIN(GL_TRIANGLE_FAN);
193 for (i = 0; i < n; i++)
194 {
195 glVertex3f(points->x, points->y, points->z);
196 points++;
197 }
198 OOGLEND();
199 return;
200}
201
202
203void GLDrawQuadStrip(OOGLVector *points, int n)
204{
205 int i;
207 OOGLBEGIN(GL_QUAD_STRIP);
208 for (i = 0; i < n; i++)
209 {
210 glVertex3f(points->x, points->y, points->z );
211 points++;
212 }
213 OOGLEND();
214 return;
215}
216
217
218void GLScaledLineWidth(GLfloat width)
219{
221 glLineWidth(width * sDisplayScaleFactor);
222}
223
224
226{
228 glPointSize(size * sDisplayScaleFactor);
229}
230
231
233{
234 return sDisplayScaleFactor;
235}
236
237
238void GLSetDisplayScaleFactor(GLfloat factor)
239{
240 NSCParameterAssert(factor >= 0.0f && isfinite(factor));
241 sDisplayScaleFactor = factor;
242}
243
244
245// MARK: LogOpenGLState() and helpers
246
247#ifndef NDEBUG
248
249static void GLDumpLightState(unsigned lightIdx);
250static void GLDumpMaterialState(void);
251static void GLDumpCullingState(void);
252static void GLDumpFogState(void);
253static void GLDumpStateFlags(void);
254
255
257{
258 unsigned i;
259
261
263
264 OOLog(kOOLogOpenGLStateDump, @"%@", @"OpenGL state dump:");
265 OOLogIndent();
266
269 if (glIsEnabled(GL_LIGHTING))
270 {
271 OOLog(kOOLogOpenGLStateDump, @"%@", @"Lighting: ENABLED");
272 for (i = 0; i != 8; ++i)
273 {
275 }
276 }
277 else
278 {
279 OOLog(kOOLogOpenGLStateDump, @"%@", @"Lighting: disabled");
280 }
281
284
285 OOCheckOpenGLErrors(@"After state dump");
286
287 OOLogOutdent();
288}
289
290
291NSString *OOGLColorToString(GLfloat color[4])
292{
293 #define COLOR_EQUAL(color, r, g, b, a) (color[0] == (r) && color[1] == (g) && color[2] == (b) && color[3] == (a))
294 #define COLOR_CASE(r, g, b, a, str) do { if (COLOR_EQUAL(color, (r), (g), (b), (a))) return (str); } while (0)
295
296 COLOR_CASE(1, 1, 1, 1, @"white");
297 COLOR_CASE(0, 0, 0, 1, @"black");
298 COLOR_CASE(0, 0, 0, 0, @"clear");
299 COLOR_CASE(1, 0, 0, 1, @"red");
300 COLOR_CASE(0, 1, 0, 1, @"green");
301 COLOR_CASE(0, 0, 1, 1, @"blue");
302 COLOR_CASE(0, 1, 1, 1, @"cyan");
303 COLOR_CASE(1, 0, 1, 1, @"magenta");
304 COLOR_CASE(1, 1, 0, 1, @"yellow");
305
306 return [NSString stringWithFormat:@"(%.2ff, %.2ff, %.2ff, %.2ff)", color[0], color[1], color[2], color[3]];
307}
308
309
310static void GLDumpLightState(unsigned lightIdx)
311{
312 BOOL enabled;
313 GLenum lightID = GL_LIGHT0 + lightIdx;
314 GLfloat color[4];
315
317
318 OOGL(enabled = glIsEnabled(lightID));
319 OOLog(kOOLogOpenGLStateDump, @"Light %u: %@", lightIdx, OOGLFlagToString(enabled));
320
321 if (enabled)
322 {
323 OOLogIndent();
324
325 OOGL(glGetLightfv(GL_LIGHT1, GL_AMBIENT, color));
326 OOLog(kOOLogOpenGLStateDump, @"Ambient: %@", OOGLColorToString(color));
327 OOGL(glGetLightfv(GL_LIGHT1, GL_DIFFUSE, color));
328 OOLog(kOOLogOpenGLStateDump, @"Diffuse: %@", OOGLColorToString(color));
329 OOGL(glGetLightfv(GL_LIGHT1, GL_SPECULAR, color));
330 OOLog(kOOLogOpenGLStateDump, @"Specular: %@", OOGLColorToString(color));
331
332 OOLogOutdent();
333 }
334}
335
336
337static void GLDumpMaterialState(void)
338{
339 GLfloat color[4];
340 GLfloat shininess;
341 GLint shadeModel,
342 blendSrc,
343 blendDst,
344 texMode;
345 BOOL blending;
346
348
349 OOLog(kOOLogOpenGLStateDump, @"%@", @"Material state:");
350 OOLogIndent();
351
352 OOGL(glGetMaterialfv(GL_FRONT, GL_AMBIENT, color));
353 OOLog(kOOLogOpenGLStateDump, @"Ambient: %@", OOGLColorToString(color));
354
355 OOGL(glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color));
356 OOLog(kOOLogOpenGLStateDump, @"Diffuse: %@", OOGLColorToString(color));
357
358 OOGL(glGetMaterialfv(GL_FRONT, GL_EMISSION, color));
359 OOLog(kOOLogOpenGLStateDump, @"Emission: %@", OOGLColorToString(color));
360
361 OOGL(glGetMaterialfv(GL_FRONT, GL_SPECULAR, color));
362 OOLog(kOOLogOpenGLStateDump, @"Specular: %@", OOGLColorToString(color));
363
364 OOGL(glGetMaterialfv(GL_FRONT, GL_SHININESS, &shininess));
365 OOLog(kOOLogOpenGLStateDump, @"Shininess: %g", shininess);
366
367 OOGL(OOLog(kOOLogOpenGLStateDump, @"Colour material: %@", OOGLFlagToString(glIsEnabled(GL_COLOR_MATERIAL))));
368
369 OOGL(glGetFloatv(GL_CURRENT_COLOR, color));
370 OOLog(kOOLogOpenGLStateDump, @"Current color: %@", OOGLColorToString(color));
371
372 OOGL(glGetIntegerv(GL_SHADE_MODEL, &shadeModel));
373 OOLog(kOOLogOpenGLStateDump, @"Shade model: %@", OOGLEnumToString(shadeModel));
374
375 OOGL(blending = glIsEnabled(GL_BLEND));
376 OOLog(kOOLogOpenGLStateDump, @"Blending: %@", OOGLFlagToString(blending));
377 if (blending)
378 {
379 OOGL(glGetIntegerv(GL_BLEND_SRC, &blendSrc));
380 OOGL(glGetIntegerv(GL_BLEND_DST, &blendDst));
381 OOLog(kOOLogOpenGLStateDump, @"Blend function: %@, %@", OOGLEnumToString(blendSrc), OOGLEnumToString(blendDst));
382 }
383
384 OOGL(glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texMode));
385 OOLog(kOOLogOpenGLStateDump, @"Texture env mode: %@", OOGLEnumToString(texMode));
386
387#if OO_MULTITEXTURE
388 if ([[OOOpenGLExtensionManager sharedManager] textureUnitCount] > 1)
389 {
390 GLint textureUnit;
391 OOGL(glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &textureUnit));
392 OOLog(kOOLogOpenGLStateDump, @"Active texture unit: %@", OOGLEnumToString(textureUnit));
393
394 OOGL(glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &textureUnit));
395 OOLog(kOOLogOpenGLStateDump, @"Active client texture unit: %@", OOGLEnumToString(textureUnit));
396 }
397#endif
398
399 OOLogOutdent();
400}
401
402
403static void GLDumpCullingState(void)
404{
406
407 bool enabled;
408 OOGL(enabled = glIsEnabled(GL_CULL_FACE));
409 OOLog(kOOLogOpenGLStateDump, @"Face culling: %@", OOGLFlagToString(enabled));
410 if (enabled)
411 {
412 GLint value;
413
414 OOLogIndent();
415
416 OOGL(glGetIntegerv(GL_CULL_FACE_MODE, &value));
417 OOLog(kOOLogOpenGLStateDump, @"Cull face mode: %@", OOGLEnumToString(value));
418
419 OOGL(glGetIntegerv(GL_FRONT_FACE, &value));
420 OOLog(kOOLogOpenGLStateDump, @"Front face direction: %@", OOGLEnumToString(value));
421
422 OOLogOutdent();
423 }
424}
425
426
427static void GLDumpFogState(void)
428{
429 BOOL enabled;
430 GLint value;
431 GLfloat start,
432 end,
433 density,
434 index;
435 GLfloat color[4];
436
438
439 OOGL(enabled = glIsEnabled(GL_FOG));
440 OOLog(kOOLogOpenGLStateDump, @"Fog: %@", OOGLFlagToString(enabled));
441 if (enabled)
442 {
443 OOLogIndent();
444
445 OOGL(glGetIntegerv(GL_FOG_MODE, &value));
446 OOLog(kOOLogOpenGLStateDump, @"Fog mode: %@", OOGLEnumToString(value));
447
448 OOGL(glGetFloatv(GL_FOG_COLOR, color));
449 OOLog(kOOLogOpenGLStateDump, @"Fog colour: %@", OOGLColorToString(color));
450
451 OOGL(glGetFloatv(GL_FOG_START, &start));
452 OOGL(glGetFloatv(GL_FOG_END, &end));
453 OOLog(kOOLogOpenGLStateDump, @"Fog start, end: %g, %g", start, end);
454
455 OOGL(glGetFloatv(GL_FOG_DENSITY, &density));
456 OOLog(kOOLogOpenGLStateDump, @"Fog density: %g", density);
457
458 OOGL(glGetFloatv(GL_FOG_DENSITY, &index));
459 OOLog(kOOLogOpenGLStateDump, @"Fog index: %g", index);
460
461 OOLogOutdent();
462 }
463}
464
465
466static void GLDumpStateFlags(void)
467{
469
470#define DUMP_STATE_FLAG(x) OOLog(kOOLogOpenGLStateDump, @ #x ": %@", OOGLFlagToString(glIsEnabled(x)))
471#define DUMP_GET_FLAG(x) do { GLboolean flag; glGetBooleanv(x, &flag); OOLog(kOOLogOpenGLStateDump, @ #x ": %@", OOGLFlagToString(flag)); } while (0)
472
473 OOLog(kOOLogOpenGLStateDump, @"%@", @"Selected state flags:");
474 OOLogIndent();
475
476 DUMP_STATE_FLAG(GL_VERTEX_ARRAY);
477 DUMP_STATE_FLAG(GL_NORMAL_ARRAY);
478 DUMP_STATE_FLAG(GL_TEXTURE_COORD_ARRAY);
479 DUMP_STATE_FLAG(GL_COLOR_ARRAY);
480 DUMP_STATE_FLAG(GL_TEXTURE_2D);
481 DUMP_STATE_FLAG(GL_DEPTH_TEST);
482 DUMP_GET_FLAG(GL_DEPTH_WRITEMASK);
483
484 OOLogOutdent();
485
486#undef DUMP_STATE_FLAG
487}
488
489
490#define CASE(x) case x: return @#x
491
492NSString *OOGLEnumToString(GLenum value)
493{
494 switch (value)
495 {
496 // ShadingModel
497 CASE(GL_FLAT);
498 CASE(GL_SMOOTH);
499
500 // BlendingFactorSrc/BlendingFactorDest
501 CASE(GL_ZERO);
502 CASE(GL_ONE);
503 CASE(GL_DST_COLOR);
504 CASE(GL_SRC_COLOR);
505 CASE(GL_ONE_MINUS_DST_COLOR);
506 CASE(GL_ONE_MINUS_SRC_COLOR);
507 CASE(GL_SRC_ALPHA);
508 CASE(GL_DST_ALPHA);
509 CASE(GL_ONE_MINUS_SRC_ALPHA);
510 CASE(GL_ONE_MINUS_DST_ALPHA);
511 CASE(GL_SRC_ALPHA_SATURATE);
512
513 // TextureEnvMode
514 CASE(GL_MODULATE);
515 CASE(GL_DECAL);
516 CASE(GL_BLEND);
517 CASE(GL_REPLACE);
518
519 // FrontFaceDirection
520 CASE(GL_CW);
521 CASE(GL_CCW);
522
523 // CullFaceMode
524 CASE(GL_FRONT);
525 CASE(GL_BACK);
526 CASE(GL_FRONT_AND_BACK);
527
528 // FogMode
529 CASE(GL_LINEAR);
530 CASE(GL_EXP);
531 CASE(GL_EXP2);
532
533#if OO_MULTITEXTURE
534 // Texture units
535#ifdef GL_TEXTURE0
536#define TEXCASE CASE
537#else
538#define TEXCASE(x) CASE(x##_ARB)
539#endif
540 TEXCASE(GL_TEXTURE0);
541 TEXCASE(GL_TEXTURE1);
542 TEXCASE(GL_TEXTURE2);
543 TEXCASE(GL_TEXTURE3);
544 TEXCASE(GL_TEXTURE4);
545 TEXCASE(GL_TEXTURE5);
546 TEXCASE(GL_TEXTURE6);
547 TEXCASE(GL_TEXTURE7);
548 TEXCASE(GL_TEXTURE8);
549 TEXCASE(GL_TEXTURE9);
550 TEXCASE(GL_TEXTURE10);
551 TEXCASE(GL_TEXTURE11);
552 TEXCASE(GL_TEXTURE12);
553 TEXCASE(GL_TEXTURE13);
554 TEXCASE(GL_TEXTURE14);
555 TEXCASE(GL_TEXTURE15);
556#endif
557
558 default: return [NSString stringWithFormat:@"unknown: %u", value];
559 }
560}
561
562
563NSString *OOGLFlagToString(bool value)
564{
565 return value ? @"ENABLED" : @"disabled";
566}
567
568#else
569
570void LogOpenGLState(void)
571{
572
573}
574
575#endif
#define EXPECT_NOT(x)
NSString *const kOOLogOpenGLError
Definition OOLogging.m:654
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
Definition OOLogging.m:144
void OOLogOutdent(void)
Definition OOLogging.m:376
#define OOLog(class, format,...)
Definition OOLogging.h:88
void OOLogIndent(void)
Definition OOLogging.m:366
#define OO_ENTER_OPENGL()
#define M_PI
Definition OOMaths.h:73
#define OOGLBEGIN
Definition OOOpenGL.h:253
#define OOGL(statement)
Definition OOOpenGL.h:251
#define OOGLEND
Definition OOOpenGL.h:254
NSString * OOGLEnumToString(GLenum value)
Definition OOOpenGL.m:492
void OOGLWireframeModeOn(void)
Definition OOOpenGL.m:87
static void GLDumpMaterialState(void)
Definition OOOpenGL.m:337
static void GLDumpStateFlags(void)
Definition OOOpenGL.m:466
static void GLDrawOvalPoints(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
Definition OOOpenGL.m:136
void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
Definition OOOpenGL.m:165
static void GLDumpCullingState(void)
Definition OOOpenGL.m:403
void OOGLWireframeModeOff(void)
Definition OOOpenGL.m:103
NSString * OOGLColorToString(GLfloat color[4])
Definition OOOpenGL.m:291
static GLfloat sDisplayScaleFactor
Definition OOOpenGL.m:36
void GLDrawPoints(OOGLVector *points, int n)
Definition OOOpenGL.m:174
static void GLDumpLightState(unsigned lightIdx)
Definition OOOpenGL.m:310
void GLDrawQuadStrip(OOGLVector *points, int n)
Definition OOOpenGL.m:203
#define CASE(x)
Definition OOOpenGL.m:490
BOOL OOCheckOpenGLErrors(NSString *format,...)
Definition OOOpenGL.m:39
void GLScaledLineWidth(GLfloat width)
Definition OOOpenGL.m:218
#define DUMP_GET_FLAG(x)
static NSString *const kOOLogOpenGLStateDump
Definition OOOpenGL.m:33
void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
Definition OOOpenGL.m:155
void GLSetDisplayScaleFactor(GLfloat factor)
Definition OOOpenGL.m:238
void GLDrawBallBillboard(GLfloat radius, GLfloat step, GLfloat z_distance)
Definition OOOpenGL.m:111
static void GLDumpFogState(void)
Definition OOOpenGL.m:427
void LogOpenGLState(void)
Definition OOOpenGL.m:256
void GLScaledPointSize(GLfloat size)
Definition OOOpenGL.m:225
#define COLOR_CASE(r, g, b, a, str)
void GLDrawFilledPoints(OOGLVector *points, int n)
Definition OOOpenGL.m:188
NSString * OOGLFlagToString(bool value)
Definition OOOpenGL.m:563
#define DUMP_STATE_FLAG(x)
GLfloat GLGetDisplayScaleFactor(void)
Definition OOOpenGL.m:232
return nil
float y
float x
voidpf void uLong size
Definition ioapi.h:134
GLfloat y
Definition OOOpenGL.h:205
GLfloat x
Definition OOOpenGL.h:204
GLfloat z
Definition OOOpenGL.h:206