summaryrefslogtreecommitdiff
path: root/cad/src/graphics/drawing/drawing_globals.py
blob: 5cd27cfe94525c587bbbbee64844ae956d7006f2 (plain)
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
# Copyright 2004-2009 Nanorex, Inc.  See LICENSE file for details. 
"""
drawing_globals.py - A module containing global state within the
graphics.drawing suite (which is, in principle, mostly specific to
one "GL resource context" (display list namespace, etc)). For historical
reasons, a lot of its state is assigned from outside, and some of it
is not in principle specific to a resource context but is either a
constant or ought to be part of an argument passed to drawing routines.

@version: $Id$
@copyright: 2004-2009 Nanorex, Inc.  See LICENSE file for details. 

WARNINGS:

Variables can be (and are) dynamically added to this module at runtime.
Note: Setting globals here should not be (but, unfortunately, is presently)
done as a side effect of loading other modules. It makes the imports of those
modules falsely appear unnecessary, since nothing defined in them is used.
It also confuses tools which import the module in which the assignment is
used, but not the one which makes the assignment.

Some of the variables contained here are mode control for the whole drawing
package, including the ColorSorter suite.  Other parts are communication between
the phases of setup and operations, which is only incidentally about OpenGL.
Other things are just geometric constants useful for setting up display lists,
e.g. a list of vertices of a diamond grid.

Usage:

Import it this way to show that it is a module:

  import graphics.drawing.drawing_globals as drawing_globals

Access variables as drawing_globals.varname .

TODO:

Desireable refactoring: Note that most of this state really belongs
in an object that corresponds to each "GL display list namespace"
aka "GL resource context",
i.e. each OpenGL shared resource pool of display lists, textures,
shaders, VBOs, etc.

In current code, we require all OpenGL drawing
contexts to share that state, so we can get away with keeping it
as globals in a module. Even so, this ought to be refactored, since
this way it makes the code less clear, causes import cycles and
dependencies on import order, confuses pylint, etc.

(Bruce 090303 is doing related cleanup by introducing ShaderGlobals
and moving shader prefs into GLPrefs, but the fundamental change
is still needed.)
"""

from graphics.drawing.glprefs import GLPrefs

# more imports are kept below, since they will be refactored into a separate module

# ==

# A singleton instance of the GLPrefs class.
# This is used in only these ways:
# - by old code (perhaps all being refactored away circa 090304)
# - to initialize glpane.glprefs when there is no other source.
# It must be initialized during import of this module,
# or some code would risk importing a value for it from before
# it was initialized.
# If this causes an import cycle, it can be moved to another module,
# since it's not otherwise used in this module.

# [review: rename it to avoid confusion, once all old uses are removed?]

glprefs = GLPrefs()

# =====

# these are assigned by external code (incomplete list;
# defined here to partly mollify pylint; not yet classified
# into how to distribute them after refactoring; to find lots more,
# use pylint on various modules in graphics/drawing)

drawing_phase = None

# =====

# Everything below here should be something that belongs in an object
# that corresponds to a "GL resource context"' someday we will refactor
# this module into such an object (owned by each glpane) and other things.
# For example, fixed-use OpenGL display lists (like sphereList) belong here.
# (Presently many such things are stored here by external code, like setup_draw.
#  That should be changed too.)
# [bruce 090304]

from graphics.drawing.ShaderGlobals import SphereShaderGlobals
from graphics.drawing.ShaderGlobals import CylinderShaderGlobals

sphereShaderGlobals = SphereShaderGlobals()
cylinderShaderGlobals = CylinderShaderGlobals()

# for use by test_drawing.py only, shares no state with other globals
test_sphereShader = None

# ==

def setup_desired_shaders(glprefs): #bruce 090303
    """
    Setup shaders within our state, according to shader-use desires of glprefs.

    @note: does not check glpane.permit_shaders.
    """
    if glprefs.sphereShader_desired():
        sphereShaderGlobals.setup_if_needed_and_not_failed()
        
    if glprefs.cylinderShader_desired():
        cylinderShaderGlobals.setup_if_needed_and_not_failed()

    return

def sphereShader_available(): #bruce 090306
    return sphereShaderGlobals.shader_available()

def cylinderShader_available():
    return cylinderShaderGlobals.shader_available()

coneShader_available = cylinderShader_available

# ==

def enabled_shaders(glpane): #bruce 090303
    """
    Return a list of the shaders that are enabled for use during this
    drawing frame (in a deterministic order), in this glpane.
    
    "enabled" means three things are true:
    * desired for its types of primitives in CSDLs (re glpane.glprefs),
    * available for use (re shader setup errors; see shader_available),
    * permitted for use (glpane.permit_shaders).

    @note: the result is currently [090303] one of the values

    []
    [sphereShader]
    [cylinderShader]
    [sphereShader, cylinderShader]

    where sphereShader and cylinderShader are instances of subclasses
    of GLShaderObject which are enabled for current use in the
    GL resource context represented by this (singleton) module.

    Note that prefs might request a shader without it being enabled (due to
    error or to its not yet being created), or it might exist and be useable
    without prefs wanting to use it (if they were turned off during the
    session).
    """
    glprefs = glpane.glprefs
    res = []
    if glpane.permit_shaders and glprefs._use_batched_primitive_shaders:
        # note: testing _use_batched_primitive_shaders is just
        # an optimization (and a kluge) (so nevermind that it's private)
        for desired, shaderGlobals in [
            (glprefs.sphereShader_desired(), sphereShaderGlobals),
            (glprefs.cylinderShader_desired(), cylinderShaderGlobals),
         ]:
            if desired and shaderGlobals.shader_available():
                res += [ shaderGlobals.shader ]
            continue
    return res

# end