1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 /* OpenGLGState:
14  *  Encapsulates OpenGL rendering state information.
15  */
16 
17 #ifndef BZF_OPENGL_GSTATE_H
18 #define BZF_OPENGL_GSTATE_H
19 
20 #include "common.h"
21 #include "bzfgl.h"
22 
23 class OpenGLMaterial;
24 class OpenGLGStateRep;
25 class OpenGLGStateState;
26 class RenderNode;
27 
28 typedef void        (*OpenGLContextFunction)(void* userData);
29 
30 class OpenGLGState
31 {
32     friend class OpenGLGStateBuilder;
33     friend class ContextInitializer;
34 public:
35     OpenGLGState();
36     OpenGLGState(const OpenGLGState&);
37     OpenGLGState(const OpenGLGStateState&);
38     ~OpenGLGState();
39     OpenGLGState&   operator=(const OpenGLGState& state);
40     void        setState() const;
41     bool        getNeedsSorting() const;
42     bool        isBlended() const;
43     bool        isTextured() const;
44     bool        isTextureMatrix() const;
45     bool        isSphereMap() const;
46     bool        isLighted() const;
47     void        addRenderNode(RenderNode* node) const;
48     static void     resetState();
49     static void     clearLists();
50     static void     renderLists();
51     static void     setStipple(GLfloat alpha);
52     static void     setStippleIndex(int index);
53     static int      getStippleIndex(float alpha);
54     static int      getOpaqueStippleIndex();
55     static int      getMaxSamples();
56 
57     static void     init();
58     static bool     haveGLContext();
59 
60     // these are in OpenGLGState for lack of a better place.  register...
61     // is for clients to add a function to call when the OpenGL context
62     // has been destroyed and must be recreated.  the function is called
63     // by initContext() and initContext() will call all initializers in
64     // the order they were registered, plus reset the OpenGLGState state.
65     //
66 
67     //
68     // The freeFunc()'s job is to make sure that all references that the
69     // owning object might use are invalidated. It should also deallocate
70     // any GL objects that it might have collected. If the references are
71     // not invalidated, then the owner may end up deleting GL objects that
72     // it does not own, because the references have been changed during the
73     // context switch (ex: another routine might have received the same
74     // references when making new objects.)
75     //
76     // The initFunc()'s job is to reallocate GL objects for its owner.
77     //
78     // Destroying and recreating the OpenGL context is only necessary on
79     // platforms that cannot abstract the graphics system sufficiently.
80     // for example, on win32, changing the display bit depth will cause
81     // most OpenGL drivers to crash unless we destroy the context before
82     // the switch and recreate it afterwards.
83     //
84     static void     registerContextInitializer(
85         OpenGLContextFunction freeFunc,
86         OpenGLContextFunction initFunc,
87         void* userData);
88 
89     static void     unregisterContextInitializer(
90         OpenGLContextFunction freeFunc,
91         OpenGLContextFunction initFunc,
92         void* userData);
93 
94     static void     initContext();
95     static bool     getExecutingFreeFuncs();
96     static bool     getExecutingInitFuncs();
97 
98 private:
99     static void     initGLState();
100     static bool     initGLExtensions();
101     static void     freeStipple(void*);
102     static void     initStipple(void*);
103 
104     class ContextInitializer
105     {
106     public:
107         friend class OpenGLGState;
108         ContextInitializer(OpenGLContextFunction freeFunc,
109                            OpenGLContextFunction initFunc,
110                            void* data);
111         ~ContextInitializer();
112 
113         static void executeFreeFuncs();
114         static void executeInitFuncs();
115 
116         static ContextInitializer* find(OpenGLContextFunction freeFunc,
117                                         OpenGLContextFunction initFunc,
118                                         void* data);
119 
120     public:
121         OpenGLContextFunction freeCallback;
122         OpenGLContextFunction initCallback;
123         void* userData;
124 
125         ContextInitializer* prev;
126         ContextInitializer* next;
127         static ContextInitializer* head;
128         static ContextInitializer* tail;
129     };
130 
131 private:
132     OpenGLGStateRep*    rep;
133     static GLuint   stipples;
134     static int maxSamples;
135 public:
136     static bool executingFreeFuncs;
137     static bool executingInitFuncs;
138     static bool hasAnisotropicFiltering;
139 };
140 
getExecutingFreeFuncs()141 inline bool OpenGLGState::getExecutingFreeFuncs()
142 {
143     return executingFreeFuncs;
144 }
getExecutingInitFuncs()145 inline bool OpenGLGState::getExecutingInitFuncs()
146 {
147     return executingInitFuncs;
148 }
149 
150 
151 class OpenGLGStateBuilder
152 {
153 public:
154     OpenGLGStateBuilder();
155     OpenGLGStateBuilder(const OpenGLGState&);
156     ~OpenGLGStateBuilder();
157     OpenGLGStateBuilder &operator=(const OpenGLGState&);
158 
159     void        reset();
160     void        enableTexture(bool = true);
161     void        enableTextureMatrix(bool = true);
162     void        enableSphereMap(bool = true);
163     void        enableMaterial(bool = true);
164     void        resetBlending();
165     void        resetSmoothing();
166     void        resetAlphaFunc();
167     void        setTexture(const int texture);
168     void        setTextureMatrix(const GLfloat* matrix);
169     void        setTextureEnvMode(GLenum mode = GL_MODULATE);
170     void        setMaterial(const OpenGLMaterial& material);
171     void        setBlending(GLenum sFactor = GL_SRC_ALPHA,
172                             GLenum dFactor = GL_ONE_MINUS_SRC_ALPHA);
173     void        setStipple(float alpha);
174     void        setSmoothing(bool smooth = true);
175     void        setCulling(GLenum culling);
176     void        disableCulling();
177     void        setShading(GLenum shading = GL_SMOOTH);
178     void        setAlphaFunc(GLenum func = GL_GEQUAL,
179                              GLclampf ref = 0.1f);
180     void        setNeedsSorting(bool);
181     OpenGLGState    getState() const;
182 
183 private:
184     void        init(const OpenGLGState&);
185 
186 private:
187     OpenGLGStateState*  state;
188 };
189 
190 
191 #endif // BZF_OPENGL_GSTATE_H
192 
193 // Local Variables: ***
194 // mode: C++ ***
195 // tab-width: 4 ***
196 // c-basic-offset: 4 ***
197 // indent-tabs-mode: nil ***
198 // End: ***
199 // ex: shiftwidth=4 tabstop=4
200