Line data Source code
1 0 : /*
2 :
3 : OOOpenGL.h
4 :
5 : Do whatever is appropriate to get gl.h, glu.h and glext.h included.
6 :
7 : Also declares OpenGL-related utility functions.
8 :
9 :
10 : Oolite
11 : Copyright (C) 2004-2013 Giles C Williams and contributors
12 :
13 : This program is free software; you can redistribute it and/or
14 : modify it under the terms of the GNU General Public License
15 : as published by the Free Software Foundation; either version 2
16 : of the License, or (at your option) any later version.
17 :
18 : This program is distributed in the hope that it will be useful,
19 : but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : GNU General Public License for more details.
22 :
23 : You should have received a copy of the GNU General Public License
24 : along with this program; if not, write to the Free Software
25 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 : MA 02110-1301, USA.
27 :
28 : */
29 :
30 : #import "OOCocoa.h"
31 : #import "OOOpenGLOnly.h"
32 :
33 :
34 0 : typedef enum
35 : {
36 : // NOTE: numerical values are available to scripts.
37 : SHADERS_NOT_SUPPORTED = 0,
38 : SHADERS_OFF = 1,
39 : SHADERS_SIMPLE = 2,
40 : SHADERS_FULL = 3
41 : } OOShaderSetting;
42 :
43 :
44 0 : #define NULL_SHADER ((GLhandleARB)0)
45 :
46 :
47 : // Whether to use state verifier. Will be changed to equal OO_CHECK_GL_HEAVY in future.
48 : #ifdef NDEBUG
49 : #define OO_GL_STATE_VERIFICATION 0
50 : #else
51 0 : #define OO_GL_STATE_VERIFICATION 1
52 : #endif
53 :
54 : /*
55 : OOSetOpenGLState(stateType)
56 :
57 : Set OpenGL state to one of two standard states.
58 :
59 : In Deployment builds, this only modifies the state that differs between
60 : the two standard states, and only when the last set state is not the same
61 : as the specified target.
62 :
63 : In Debug builds, it tests many different OpenGL state variables, complains
64 : if they aren't in the expected state, and corrects them.
65 :
66 :
67 : The correct procedure for using these functions is:
68 : 1. Call OOSetOpenGLState(<most appropriate state>)
69 : 2. Make any state changes needed
70 : 3. Draw
71 : 4. Reverse state changes from stage 2
72 : 5. Call OOVerifyOpenGLState()
73 : 6. Call OOCheckOpenGLErrors().
74 :
75 :
76 : The states are:
77 : OPENGL_STATE_OPAQUE - standard state for drawing solid objects like OOMesh
78 : and planets. This can be considered the Oolite baseline state.
79 : Differs from standard GL state as follows:
80 : GL_LIGHTING is on
81 : GL_LIGHT1 is on
82 : GL_TEXTURE_2D is on
83 : Blend mode is GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA (but GL_BLEND is off)
84 : GL_FOG may be either on or off (as it's set in Universe's draw loop)
85 : GL_VERTEX_ARRAY is on
86 : GL_NORMAL_ARRAY is on
87 : GL_DEPTH_TEST is on
88 : GL_CULL_FACE is on
89 :
90 : OPENGL_STATE_TRANSLUCENT_PASS is used during the translucent phase of the
91 : universe draw loop. This usage needs to be cleaned up.
92 : Differs from OPENGL_STATE_OPAQUE as follows:
93 : GL_LIGHTING is off
94 : GL_TEXTURE_2D is off
95 : GL_VERTEX_ARRAY is off
96 : GL_NORMAL_ARRAY is off
97 : GL_DEPTH_WRITEMASK is off
98 :
99 : OPENGL_STATE_ADDITIVE_BLENDING is used for glowy special effects.
100 : Differs from OPENGL_STATE_OPAQUE as follows:
101 : GL_LIGHTING is off
102 : GL_TEXTURE_2D is off
103 : GL_BLEND is on
104 : Blend mode is GL_SRC_ALPHA, GL_ONE
105 : GL_NORMAL_ARRAY is off
106 : GL_DEPTH_WRITEMASK is off
107 : GL_CULL_FACE is off
108 :
109 : OPENGL_STATE_OVERLAY is used for UI elements, which are unlit and don't use
110 : z-buffering.
111 : Differs from OPENGL_STATE_OPAQUE as follows:
112 : GL_LIGHTING is off
113 : GL_TEXTURE_2D is off
114 : GL_BLEND is on
115 : GL_FOG is off
116 : GL_NORMAL_ARRAY is off
117 : GL_DEPTH_TEST is off
118 : GL_DEPTH_WRITEMASK is off
119 : GL_CULL_FACE is off
120 : */
121 0 : typedef enum
122 : {
123 : OPENGL_STATE_OPAQUE,
124 : OPENGL_STATE_TRANSLUCENT_PASS,
125 : OPENGL_STATE_ADDITIVE_BLENDING,
126 : OPENGL_STATE_OVERLAY,
127 :
128 : OPENGL_STATE_INTERNAL_USE_ONLY
129 : } OOOpenGLStateID;
130 :
131 :
132 : #if OO_GL_STATE_VERIFICATION
133 0 : void OOSetOpenGLState_(OOOpenGLStateID state, const char *function, unsigned line);
134 0 : void OOVerifyOpenGLState_(const char *function, unsigned line);
135 0 : #define OOSetOpenGLState(STATE) OOSetOpenGLState_(STATE, __FUNCTION__, __LINE__)
136 0 : #define OOVerifyOpenGLState() OOVerifyOpenGLState_(__FUNCTION__, __LINE__)
137 : #else
138 : void OOSetOpenGLState(OOOpenGLStateID state);
139 : #define OOVerifyOpenGLState() do {} while (0)
140 : #endif
141 :
142 :
143 : // Inform the SetState/VerifyState mechanism that the OpenGL context has been reset to its initial state.
144 0 : void OOResetGLStateVerifier(void);
145 :
146 :
147 : /* OOCheckOpenGLErrors()
148 : Check for and log OpenGL errors, and returns YES if an error occurred.
149 : NOTE: this is controlled by the log message class rendering.opengl.error.
150 : If logging is disabled, no error checking will occur. This is done
151 : because glGetError() is quite expensive, requiring a full OpenGL
152 : state sync.
153 : */
154 0 : BOOL OOCheckOpenGLErrors(NSString *format, ...);
155 :
156 : /* LogOpenGLState()
157 : Write a bunch of OpenGL state information to the log.
158 : */
159 0 : void LogOpenGLState(void);
160 :
161 :
162 : /* GLScaledLineWidth()
163 : GLScaledPointSize()
164 : GLGetDisplayScaleFactor()
165 : GLSetDisplayScaleFactor()
166 :
167 : These functions wrap glLineWidth() and glPointSize(), and multiply the
168 : specified size by a "display scale factor". This is currently used to
169 : support Retina display modes in Mac OS X 10.7 and later.
170 :
171 : The default display scale factor is 1.0.
172 : */
173 0 : void GLScaledLineWidth(GLfloat width);
174 0 : void GLScaledPointSize(GLfloat size);
175 0 : GLfloat GLGetDisplayScaleFactor(void);
176 0 : void GLSetDisplayScaleFactor(GLfloat factor);
177 :
178 :
179 : /* OOGLWireframeModeOn()
180 : OOGLWireframeModeOff()
181 : Enable/disable polygon-to-lines wireframe rendering with line width of 1.
182 : */
183 0 : void OOGLWireframeModeOn(void);
184 0 : void OOGLWireframeModeOff(void);
185 :
186 :
187 : /* GLDrawBallBillboard()
188 : Draws a circle corresponding to a sphere of given radius at given distance.
189 : Assumes Z buffering will be disabled.
190 : */
191 0 : void GLDrawBallBillboard(GLfloat radius, GLfloat step, GLfloat z_distance);
192 :
193 : /* GLDrawOval(), GLDrawFilledOval()
194 : Draw axis-alligned ellipses, as outline and fill respectively.
195 : */
196 0 : void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step);
197 0 : void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step);
198 :
199 : /* GLDrawPoints(), GLDrawFilledPoints()
200 : Draw array of points, as outline and fill respectively.
201 : */
202 :
203 0 : typedef struct {
204 0 : GLfloat x;
205 0 : GLfloat y;
206 0 : GLfloat z;
207 : } OOGLVector;
208 :
209 0 : void GLDrawPoints(OOGLVector *points, int n);
210 0 : void GLDrawFilledPoints(OOGLVector *points, int n);
211 0 : void GLDrawQuadStrip(OOGLVector *points, int n);
212 :
213 : /* OO_CHECK_GL_HEAVY and error-checking stuff
214 :
215 : If OO_CHECK_GL_HEAVY is non-zero, the following error-checking facilities
216 : come into play:
217 : OOGL(foo) checks for GL errors before and after performing the statement foo.
218 : OOGLBEGIN(mode) checks for GL errors, then calls glBegin(mode).
219 : OOGLEND() calls glEnd(), then checks for GL errors.
220 : CheckOpenGLErrorsHeavy() checks for errors exactly like OOCheckOpenGLErrors().
221 :
222 : If OO_CHECK_GL_HEAVY is zero, these macros don't perform error checking,
223 : but otherwise continue to work as before, so:
224 : OOGL(foo) performs the statement foo.
225 : OOGLBEGIN(mode) calls glBegin(mode);
226 : OOGLEND() calls glEnd().
227 : CheckOpenGLErrorsHeavy() does nothing (including not performing any parameter side-effects).
228 : */
229 : #ifndef OO_CHECK_GL_HEAVY
230 0 : #define OO_CHECK_GL_HEAVY 0
231 : #endif
232 :
233 :
234 : #if OO_CHECK_GL_HEAVY
235 :
236 : #if OO_GL_STATE_VERIFICATION
237 : void OOGLNoteCurrentFunction(const char *func, unsigned line);
238 : #else
239 : #define OOGLNoteCurrentFunction(FUNC, line) do {} while (0)
240 : #endif
241 :
242 : NSString *OOLogAbbreviatedFileName(const char *inName);
243 : #define OOGL_PERFORM_CHECK(label, code) OOCheckOpenGLErrors(@"%s %@:%u (%s)%s", label, OOLogAbbreviatedFileName(__FILE__), __LINE__, __PRETTY_FUNCTION__, code)
244 : #define OOGL(statement) do { OOGLNoteCurrentFunction(__FUNCTION__, __LINE__); OOGL_PERFORM_CHECK("PRE", " -- " #statement); statement; OOGL_PERFORM_CHECK("POST", " -- " #statement); } while (0)
245 : #define CheckOpenGLErrorsHeavy OOCheckOpenGLErrors
246 : #define OOGLBEGIN(mode) do { OOGLNoteCurrentFunction(__FUNCTION__, __LINE__); OOGL_PERFORM_CHECK("PRE-BEGIN", " -- " #mode); glBegin(mode); } while (0)
247 : #define OOGLEND() do { glEnd(); OOGLNoteCurrentFunction(__FUNCTION__, __LINE__); OOGL_PERFORM_CHECK("POST-END", ""); } while (0)
248 :
249 : #else
250 :
251 0 : #define OOGL(statement) do { statement; } while (0)
252 0 : #define CheckOpenGLErrorsHeavy(...) do {} while (0)
253 0 : #define OOGLBEGIN glBegin
254 0 : #define OOGLEND glEnd
255 :
256 : #endif
257 :
258 :
259 0 : enum
260 : {
261 : kOOShaderSettingDefault = SHADERS_NOT_SUPPORTED
262 : };
263 :
264 : // Programmer-readable shader mode strings.
265 0 : OOShaderSetting OOShaderSettingFromString(NSString *string);
266 0 : NSString *OOStringFromShaderSetting(OOShaderSetting setting);
267 : // Localized shader mode strings.
268 0 : NSString *OODisplayStringFromShaderSetting(OOShaderSetting setting);
269 :
270 :
271 : #ifndef NDEBUG
272 :
273 0 : NSString *OOGLColorToString(GLfloat color[4]);
274 0 : NSString *OOGLEnumToString(GLenum value);
275 0 : NSString *OOGLFlagToString(bool value);
276 :
277 : #endif
|