File: OpenGLGState.h

package info (click to toggle)
bzflag 2.4.30-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 26,488 kB
  • sloc: cpp: 150,376; ansic: 3,463; sh: 2,535; makefile: 2,194; perl: 486; python: 260; objc: 246; php: 206
file content (199 lines) | stat: -rw-r--r-- 6,445 bytes parent folder | download
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
/* bzflag
 * Copyright (c) 1993-2025 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* OpenGLGState:
 *  Encapsulates OpenGL rendering state information.
 */

#ifndef BZF_OPENGL_GSTATE_H
#define BZF_OPENGL_GSTATE_H

#include "common.h"
#include "bzfgl.h"

class OpenGLMaterial;
class OpenGLGStateRep;
class OpenGLGStateState;
class RenderNode;

typedef void        (*OpenGLContextFunction)(void* userData);

class OpenGLGState
{
    friend class OpenGLGStateBuilder;
    friend class ContextInitializer;
public:
    OpenGLGState();
    OpenGLGState(const OpenGLGState&);
    OpenGLGState(const OpenGLGStateState&);
    ~OpenGLGState();
    OpenGLGState&   operator=(const OpenGLGState& state);
    void        setState() const;
    bool        getNeedsSorting() const;
    bool        isBlended() const;
    bool        isTextured() const;
    bool        isTextureMatrix() const;
    bool        isSphereMap() const;
    bool        isLighted() const;
    void        addRenderNode(RenderNode* node) const;
    static void     resetState();
    static void     clearLists();
    static void     renderLists();
    static void     setStipple(GLfloat alpha);
    static void     setStippleIndex(int index);
    static int      getStippleIndex(float alpha);
    static int      getOpaqueStippleIndex();
    static int      getMaxSamples();

    static void     init();
    static bool     haveGLContext();

    // these are in OpenGLGState for lack of a better place.  register...
    // is for clients to add a function to call when the OpenGL context
    // has been destroyed and must be recreated.  the function is called
    // by initContext() and initContext() will call all initializers in
    // the order they were registered, plus reset the OpenGLGState state.
    //

    //
    // The freeFunc()'s job is to make sure that all references that the
    // owning object might use are invalidated. It should also deallocate
    // any GL objects that it might have collected. If the references are
    // not invalidated, then the owner may end up deleting GL objects that
    // it does not own, because the references have been changed during the
    // context switch (ex: another routine might have received the same
    // references when making new objects.)
    //
    // The initFunc()'s job is to reallocate GL objects for its owner.
    //
    // Destroying and recreating the OpenGL context is only necessary on
    // platforms that cannot abstract the graphics system sufficiently.
    // for example, on win32, changing the display bit depth will cause
    // most OpenGL drivers to crash unless we destroy the context before
    // the switch and recreate it afterwards.
    //
    static void     registerContextInitializer(
        OpenGLContextFunction freeFunc,
        OpenGLContextFunction initFunc,
        void* userData);

    static void     unregisterContextInitializer(
        OpenGLContextFunction freeFunc,
        OpenGLContextFunction initFunc,
        void* userData);

    static void     initContext();
    static bool     getExecutingFreeFuncs();
    static bool     getExecutingInitFuncs();

private:
    static void     initGLState();
    static bool     initGLExtensions();
    static void     freeStipple(void*);
    static void     initStipple(void*);

    class ContextInitializer
    {
    public:
        friend class OpenGLGState;
        ContextInitializer(OpenGLContextFunction freeFunc,
                           OpenGLContextFunction initFunc,
                           void* data);
        ~ContextInitializer();

        static void executeFreeFuncs();
        static void executeInitFuncs();

        static ContextInitializer* find(OpenGLContextFunction freeFunc,
                                        OpenGLContextFunction initFunc,
                                        void* data);

    public:
        OpenGLContextFunction freeCallback;
        OpenGLContextFunction initCallback;
        void* userData;

        ContextInitializer* prev;
        ContextInitializer* next;
        static ContextInitializer* head;
        static ContextInitializer* tail;
    };

private:
    OpenGLGStateRep*    rep;
    static GLuint   stipples;
    static int maxSamples;
public:
    static bool executingFreeFuncs;
    static bool executingInitFuncs;
    static bool hasAnisotropicFiltering;
};

inline bool OpenGLGState::getExecutingFreeFuncs()
{
    return executingFreeFuncs;
}
inline bool OpenGLGState::getExecutingInitFuncs()
{
    return executingInitFuncs;
}


class OpenGLGStateBuilder
{
public:
    OpenGLGStateBuilder();
    OpenGLGStateBuilder(const OpenGLGState&);
    ~OpenGLGStateBuilder();
    OpenGLGStateBuilder &operator=(const OpenGLGState&);

    void        reset();
    void        enableTexture(bool = true);
    void        enableTextureMatrix(bool = true);
    void        enableSphereMap(bool = true);
    void        enableMaterial(bool = true);
    void        resetBlending();
    void        resetSmoothing();
    void        resetAlphaFunc();
    void        setTexture(const int texture);
    void        setTextureMatrix(const GLfloat* matrix);
    void        setTextureEnvMode(GLenum mode = GL_MODULATE);
    void        setMaterial(const OpenGLMaterial& material);
    void        setBlending(GLenum sFactor = GL_SRC_ALPHA,
                            GLenum dFactor = GL_ONE_MINUS_SRC_ALPHA);
    void        setStipple(float alpha);
    void        setSmoothing(bool smooth = true);
    void        setCulling(GLenum culling);
    void        disableCulling();
    void        setShading(GLenum shading = GL_SMOOTH);
    void        setAlphaFunc(GLenum func = GL_GEQUAL,
                             GLclampf ref = 0.1f);
    void        setNeedsSorting(bool);
    OpenGLGState    getState() const;

private:
    void        init(const OpenGLGState&);

private:
    OpenGLGStateState*  state;
};


#endif // BZF_OPENGL_GSTATE_H

// Local Variables: ***
// mode: C++ ***
// tab-width: 4 ***
// c-basic-offset: 4 ***
// indent-tabs-mode: nil ***
// End: ***
// ex: shiftwidth=4 tabstop=4