]> git.cworth.org Git - apitrace/blobdiff - glstate.py
Silence warnings due to unused variables.
[apitrace] / glstate.py
index 8a515f47864f90325b1b28f319c89b9340ec75b4..38084151979f6ad62aaed2381efc687b1738cfaa 100644 (file)
 ##########################################################################/
 
 
+'''Generate code to dump most GL state into JSON.'''
+
+
 from stdapi import *
 
-from glenum import GLenum
-
-
-
-I = Int
-F = Float
-
-parameters = [
-    (F,        1,      "GL_POINT_SIZE"),       # 0x0B11
-    (F,        2,      "GL_POINT_SIZE_RANGE"), # 0x0B12
-    (F,        1,      "GL_POINT_SIZE_GRANULARITY"),   # 0x0B13
-    (I,        1,      "GL_LINE_SMOOTH"),      # 0x0B20
-    (F,        1,      "GL_LINE_WIDTH"),       # 0x0B21
-    (F,        2,      "GL_LINE_WIDTH_RANGE"), # 0x0B22
-    (F,        1,      "GL_LINE_WIDTH_GRANULARITY"),   # 0x0B23
-    (I,        1,      "GL_POLYGON_SMOOTH"),   # 0x0B41
-    (I,        1,      "GL_CULL_FACE"),        # 0x0B44
-    (I,        1,      "GL_CULL_FACE_MODE"),   # 0x0B45
-    (I,        1,      "GL_FRONT_FACE"),       # 0x0B46
-    (F,        2,      "GL_DEPTH_RANGE"),      # 0x0B70
-    (I,        1,      "GL_DEPTH_TEST"),       # 0x0B71
-    (I,        1,      "GL_DEPTH_WRITEMASK"),  # 0x0B72
-    (F,        1,      "GL_DEPTH_CLEAR_VALUE"),        # 0x0B73
-    (I,        1,      "GL_DEPTH_FUNC"),       # 0x0B74
-    (I,        1,      "GL_STENCIL_TEST"),     # 0x0B90
-    (I,        1,      "GL_STENCIL_CLEAR_VALUE"),      # 0x0B91
-    (I,        1,      "GL_STENCIL_FUNC"),     # 0x0B92
-    (I,        1,      "GL_STENCIL_VALUE_MASK"),       # 0x0B93
-    (I,        1,      "GL_STENCIL_FAIL"),     # 0x0B94
-    (I,        1,      "GL_STENCIL_PASS_DEPTH_FAIL"),  # 0x0B95
-    (I,        1,      "GL_STENCIL_PASS_DEPTH_PASS"),  # 0x0B96
-    (I,        1,      "GL_STENCIL_REF"),      # 0x0B97
-    (I,        1,      "GL_STENCIL_WRITEMASK"),        # 0x0B98
-    (I,        4,      "GL_VIEWPORT"), # 0x0BA2
-    (I,        1,      "GL_DITHER"),   # 0x0BD0
-    (I,        1,      "GL_BLEND_DST"),        # 0x0BE0
-    (I,        1,      "GL_BLEND_SRC"),        # 0x0BE1
-    (I,        1,      "GL_BLEND"),    # 0x0BE2
-    (I,        1,      "GL_LOGIC_OP_MODE"),    # 0x0BF0
-    (I,        1,      "GL_COLOR_LOGIC_OP"),   # 0x0BF2
-    (I,        1,      "GL_DRAW_BUFFER"),      # 0x0C01
-    (I,        1,      "GL_READ_BUFFER"),      # 0x0C02
-    (I,        4,      "GL_SCISSOR_BOX"),      # 0x0C10
-    (I,        1,      "GL_SCISSOR_TEST"),     # 0x0C11
-    (F,        4,      "GL_COLOR_CLEAR_VALUE"),        # 0x0C22
-    (I,        4,      "GL_COLOR_WRITEMASK"),  # 0x0C23
-    (I,        1,      "GL_DOUBLEBUFFER"),     # 0x0C32
-    (I,        1,      "GL_STEREO"),   # 0x0C33
-    (I,        1,      "GL_LINE_SMOOTH_HINT"), # 0x0C52
-    (I,        1,      "GL_POLYGON_SMOOTH_HINT"),      # 0x0C53
-    (I,        1,      "GL_UNPACK_SWAP_BYTES"),        # 0x0CF0
-    (I,        1,      "GL_UNPACK_LSB_FIRST"), # 0x0CF1
-    (I,        1,      "GL_UNPACK_ROW_LENGTH"),        # 0x0CF2
-    (I,        1,      "GL_UNPACK_SKIP_ROWS"), # 0x0CF3
-    (I,        1,      "GL_UNPACK_SKIP_PIXELS"),       # 0x0CF4
-    (I,        1,      "GL_UNPACK_ALIGNMENT"), # 0x0CF5
-    (I,        1,      "GL_PACK_SWAP_BYTES"),  # 0x0D00
-    (I,        1,      "GL_PACK_LSB_FIRST"),   # 0x0D01
-    (I,        1,      "GL_PACK_ROW_LENGTH"),  # 0x0D02
-    (I,        1,      "GL_PACK_SKIP_ROWS"),   # 0x0D03
-    (I,        1,      "GL_PACK_SKIP_PIXELS"), # 0x0D04
-    (I,        1,      "GL_PACK_ALIGNMENT"),   # 0x0D05
-    (I,        1,      "GL_MAX_TEXTURE_SIZE"), # 0x0D33
-    (F,        2,      "GL_MAX_VIEWPORT_DIMS"),        # 0x0D3A
-    (I,        1,      "GL_SUBPIXEL_BITS"),    # 0x0D50
-    (I,        1,      "GL_TEXTURE_1D"),       # 0x0DE0
-    (I,        1,      "GL_TEXTURE_2D"),       # 0x0DE1
-    (F,        1,      "GL_POLYGON_OFFSET_UNITS"),     # 0x2A00
-    (I,        1,      "GL_POLYGON_OFFSET_POINT"),     # 0x2A01
-    (I,        1,      "GL_POLYGON_OFFSET_LINE"),      # 0x2A02
-    (I,        1,      "GL_POLYGON_OFFSET_FILL"),      # 0x8037
-    (F,        1,      "GL_POLYGON_OFFSET_FACTOR"),    # 0x8038
-    (I,        1,      "GL_TEXTURE_BINDING_1D"),       # 0x8068
-    (I,        1,      "GL_TEXTURE_BINDING_2D"),       # 0x8069
-    (F,        4,      "GL_CURRENT_COLOR"),    # 0x0B00
-    (F,        1,      "GL_CURRENT_INDEX"),    # 0x0B01
-    (F,        3,      "GL_CURRENT_NORMAL"),   # 0x0B02
-    (F,        4,      "GL_CURRENT_TEXTURE_COORDS"),   # 0x0B03
-    (F,        4,      "GL_CURRENT_RASTER_COLOR"),     # 0x0B04
-    (F,        1,      "GL_CURRENT_RASTER_INDEX"),     # 0x0B05
-    (F,        4,      "GL_CURRENT_RASTER_TEXTURE_COORDS"),    # 0x0B06
-    (F,        4,      "GL_CURRENT_RASTER_POSITION"),  # 0x0B07
-    (I,        1,      "GL_CURRENT_RASTER_POSITION_VALID"),    # 0x0B08
-    (F,        1,      "GL_CURRENT_RASTER_DISTANCE"),  # 0x0B09
-    (I,        1,      "GL_POINT_SMOOTH"),     # 0x0B10
-    (I,        1,      "GL_LINE_STIPPLE"),     # 0x0B24
-    (I,        1,      "GL_LINE_STIPPLE_PATTERN"),     # 0x0B25
-    (I,        1,      "GL_LINE_STIPPLE_REPEAT"),      # 0x0B26
-    (I,        1,      "GL_LIST_MODE"),        # 0x0B30
-    (I,        1,      "GL_MAX_LIST_NESTING"), # 0x0B31
-    (I,        1,      "GL_LIST_BASE"),        # 0x0B32
-    (I,        1,      "GL_LIST_INDEX"),       # 0x0B33
-    (I,        2,      "GL_POLYGON_MODE"),     # 0x0B40
-    (I,        1,      "GL_POLYGON_STIPPLE"),  # 0x0B42
-    (I,        1,      "GL_EDGE_FLAG"),        # 0x0B43
-    (I,        1,      "GL_LIGHTING"), # 0x0B50
-    (I,        1,      "GL_LIGHT_MODEL_LOCAL_VIEWER"), # 0x0B51
-    (I,        1,      "GL_LIGHT_MODEL_TWO_SIDE"),     # 0x0B52
-    (F,        4,      "GL_LIGHT_MODEL_AMBIENT"),      # 0x0B53
-    (I,        1,      "GL_SHADE_MODEL"),      # 0x0B54
-    (I,        1,      "GL_COLOR_MATERIAL_FACE"),      # 0x0B55
-    (I,        1,      "GL_COLOR_MATERIAL_PARAMETER"), # 0x0B56
-    (I,        1,      "GL_COLOR_MATERIAL"),   # 0x0B57
-    (I,        1,      "GL_FOG"),      # 0x0B60
-    (I,        1,      "GL_FOG_INDEX"),        # 0x0B61
-    (F,        1,      "GL_FOG_DENSITY"),      # 0x0B62
-    (F,        1,      "GL_FOG_START"),        # 0x0B63
-    (F,        1,      "GL_FOG_END"),  # 0x0B64
-    (I,        1,      "GL_FOG_MODE"), # 0x0B65
-    (F,        4,      "GL_FOG_COLOR"),        # 0x0B66
-    (F,        4,      "GL_ACCUM_CLEAR_VALUE"),        # 0x0B80
-    (I,        1,      "GL_MATRIX_MODE"),      # 0x0BA0
-    (I,        1,      "GL_NORMALIZE"),        # 0x0BA1
-    (I,        1,      "GL_MODELVIEW_STACK_DEPTH"),    # 0x0BA3
-    (I,        1,      "GL_PROJECTION_STACK_DEPTH"),   # 0x0BA4
-    (I,        1,      "GL_TEXTURE_STACK_DEPTH"),      # 0x0BA5
-    (F,        16,     "GL_MODELVIEW_MATRIX"), # 0x0BA6
-    (F,        16,     "GL_PROJECTION_MATRIX"),        # 0x0BA7
-    (F,        16,     "GL_TEXTURE_MATRIX"),   # 0x0BA8
-    (I,        1,      "GL_ATTRIB_STACK_DEPTH"),       # 0x0BB0
-    (I,        1,      "GL_CLIENT_ATTRIB_STACK_DEPTH"),        # 0x0BB1
-    (I,        1,      "GL_ALPHA_TEST"),       # 0x0BC0
-    (I,        1,      "GL_ALPHA_TEST_FUNC"),  # 0x0BC1
-    (F,        1,      "GL_ALPHA_TEST_REF"),   # 0x0BC2
-    (I,        1,      "GL_INDEX_LOGIC_OP"),   # 0x0BF1
-    (I,        1,      "GL_LOGIC_OP"), # 0x0BF1
-    (I,        1,      "GL_AUX_BUFFERS"),      # 0x0C00
-    (I,        1,      "GL_INDEX_CLEAR_VALUE"),        # 0x0C20
-    (I,        1,      "GL_INDEX_WRITEMASK"),  # 0x0C21
-    (I,        1,      "GL_INDEX_MODE"),       # 0x0C30
-    (I,        1,      "GL_RGBA_MODE"),        # 0x0C31
-    (I,        1,      "GL_RENDER_MODE"),      # 0x0C40
-    (I,        1,      "GL_PERSPECTIVE_CORRECTION_HINT"),      # 0x0C50
-    (I,        1,      "GL_POINT_SMOOTH_HINT"),        # 0x0C51
-    (I,        1,      "GL_FOG_HINT"), # 0x0C54
-    (I,        1,      "GL_TEXTURE_GEN_S"),    # 0x0C60
-    (I,        1,      "GL_TEXTURE_GEN_T"),    # 0x0C61
-    (I,        1,      "GL_TEXTURE_GEN_R"),    # 0x0C62
-    (I,        1,      "GL_TEXTURE_GEN_Q"),    # 0x0C63
-    (I,        1,      "GL_PIXEL_MAP_I_TO_I_SIZE"),    # 0x0CB0
-    (I,        1,      "GL_PIXEL_MAP_S_TO_S_SIZE"),    # 0x0CB1
-    (I,        1,      "GL_PIXEL_MAP_I_TO_R_SIZE"),    # 0x0CB2
-    (I,        1,      "GL_PIXEL_MAP_I_TO_G_SIZE"),    # 0x0CB3
-    (I,        1,      "GL_PIXEL_MAP_I_TO_B_SIZE"),    # 0x0CB4
-    (I,        1,      "GL_PIXEL_MAP_I_TO_A_SIZE"),    # 0x0CB5
-    (I,        1,      "GL_PIXEL_MAP_R_TO_R_SIZE"),    # 0x0CB6
-    (I,        1,      "GL_PIXEL_MAP_G_TO_G_SIZE"),    # 0x0CB7
-    (I,        1,      "GL_PIXEL_MAP_B_TO_B_SIZE"),    # 0x0CB8
-    (I,        1,      "GL_PIXEL_MAP_A_TO_A_SIZE"),    # 0x0CB9
-    (I,        1,      "GL_MAP_COLOR"),        # 0x0D10
-    (I,        1,      "GL_MAP_STENCIL"),      # 0x0D11
-    (I,        1,      "GL_INDEX_SHIFT"),      # 0x0D12
-    (I,        1,      "GL_INDEX_OFFSET"),     # 0x0D13
-    (F,        1,      "GL_RED_SCALE"),        # 0x0D14
-    (F,        1,      "GL_RED_BIAS"), # 0x0D15
-    (F,        1,      "GL_ZOOM_X"),   # 0x0D16
-    (F,        1,      "GL_ZOOM_Y"),   # 0x0D17
-    (F,        1,      "GL_GREEN_SCALE"),      # 0x0D18
-    (F,        1,      "GL_GREEN_BIAS"),       # 0x0D19
-    (F,        1,      "GL_BLUE_SCALE"),       # 0x0D1A
-    (F,        1,      "GL_BLUE_BIAS"),        # 0x0D1B
-    (F,        1,      "GL_ALPHA_SCALE"),      # 0x0D1C
-    (F,        1,      "GL_ALPHA_BIAS"),       # 0x0D1D
-    (F,        1,      "GL_DEPTH_SCALE"),      # 0x0D1E
-    (F,        1,      "GL_DEPTH_BIAS"),       # 0x0D1F
-    (I,        1,      "GL_MAX_EVAL_ORDER"),   # 0x0D30
-    (I,        1,      "GL_MAX_LIGHTS"),       # 0x0D31
-    (I,        1,      "GL_MAX_CLIP_PLANES"),  # 0x0D32
-    (I,        1,      "GL_MAX_PIXEL_MAP_TABLE"),      # 0x0D34
-    (I,        1,      "GL_MAX_ATTRIB_STACK_DEPTH"),   # 0x0D35
-    (I,        1,      "GL_MAX_MODELVIEW_STACK_DEPTH"),        # 0x0D36
-    (I,        1,      "GL_MAX_NAME_STACK_DEPTH"),     # 0x0D37
-    (I,        1,      "GL_MAX_PROJECTION_STACK_DEPTH"),       # 0x0D38
-    (I,        1,      "GL_MAX_TEXTURE_STACK_DEPTH"),  # 0x0D39
-    (I,        1,      "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH"),    # 0x0D3B
-    (I,        1,      "GL_INDEX_BITS"),       # 0x0D51
-    (I,        1,      "GL_RED_BITS"), # 0x0D52
-    (I,        1,      "GL_GREEN_BITS"),       # 0x0D53
-    (I,        1,      "GL_BLUE_BITS"),        # 0x0D54
-    (I,        1,      "GL_ALPHA_BITS"),       # 0x0D55
-    (I,        1,      "GL_DEPTH_BITS"),       # 0x0D56
-    (I,        1,      "GL_STENCIL_BITS"),     # 0x0D57
-    (I,        1,      "GL_ACCUM_RED_BITS"),   # 0x0D58
-    (I,        1,      "GL_ACCUM_GREEN_BITS"), # 0x0D59
-    (I,        1,      "GL_ACCUM_BLUE_BITS"),  # 0x0D5A
-    (I,        1,      "GL_ACCUM_ALPHA_BITS"), # 0x0D5B
-    (I,        1,      "GL_NAME_STACK_DEPTH"), # 0x0D70
-    (I,        1,      "GL_AUTO_NORMAL"),      # 0x0D80
-    (I,        1,      "GL_MAP1_COLOR_4"),     # 0x0D90
-    (I,        1,      "GL_MAP1_INDEX"),       # 0x0D91
-    (I,        1,      "GL_MAP1_NORMAL"),      # 0x0D92
-    (I,        1,      "GL_MAP1_TEXTURE_COORD_1"),     # 0x0D93
-    (I,        1,      "GL_MAP1_TEXTURE_COORD_2"),     # 0x0D94
-    (I,        1,      "GL_MAP1_TEXTURE_COORD_3"),     # 0x0D95
-    (I,        1,      "GL_MAP1_TEXTURE_COORD_4"),     # 0x0D96
-    (I,        1,      "GL_MAP1_VERTEX_3"),    # 0x0D97
-    (I,        1,      "GL_MAP1_VERTEX_4"),    # 0x0D98
-    (I,        1,      "GL_MAP2_COLOR_4"),     # 0x0DB0
-    (I,        1,      "GL_MAP2_INDEX"),       # 0x0DB1
-    (I,        1,      "GL_MAP2_NORMAL"),      # 0x0DB2
-    (I,        1,      "GL_MAP2_TEXTURE_COORD_1"),     # 0x0DB3
-    (I,        1,      "GL_MAP2_TEXTURE_COORD_2"),     # 0x0DB4
-    (I,        1,      "GL_MAP2_TEXTURE_COORD_3"),     # 0x0DB5
-    (I,        1,      "GL_MAP2_TEXTURE_COORD_4"),     # 0x0DB6
-    (I,        1,      "GL_MAP2_VERTEX_3"),    # 0x0DB7
-    (I,        1,      "GL_MAP2_VERTEX_4"),    # 0x0DB8
-    (F,        2,      "GL_MAP1_GRID_DOMAIN"), # 0x0DD0
-    (I,        1,      "GL_MAP1_GRID_SEGMENTS"),       # 0x0DD1
-    (F,        4,      "GL_MAP2_GRID_DOMAIN"), # 0x0DD2
-    (I,        2,      "GL_MAP2_GRID_SEGMENTS"),       # 0x0DD3
-    (I,        1,      "GL_FEEDBACK_BUFFER_SIZE"),     # 0x0DF1
-    (I,        1,      "GL_FEEDBACK_BUFFER_TYPE"),     # 0x0DF2
-    (I,        1,      "GL_SELECTION_BUFFER_SIZE"),    # 0x0DF4
-    (I,        1,      "GL_VERTEX_ARRAY"),     # 0x8074
-    (I,        1,      "GL_NORMAL_ARRAY"),     # 0x8075
-    (I,        1,      "GL_COLOR_ARRAY"),      # 0x8076
-    (I,        1,      "GL_INDEX_ARRAY"),      # 0x8077
-    (I,        1,      "GL_TEXTURE_COORD_ARRAY"),      # 0x8078
-    (I,        1,      "GL_EDGE_FLAG_ARRAY"),  # 0x8079
-    (I,        1,      "GL_VERTEX_ARRAY_SIZE"),        # 0x807A
-    (I,        1,      "GL_VERTEX_ARRAY_TYPE"),        # 0x807B
-    (I,        1,      "GL_VERTEX_ARRAY_STRIDE"),      # 0x807C
-    (I,        1,      "GL_NORMAL_ARRAY_TYPE"),        # 0x807E
-    (I,        1,      "GL_NORMAL_ARRAY_STRIDE"),      # 0x807F
-    (I,        1,      "GL_COLOR_ARRAY_SIZE"), # 0x8081
-    (I,        1,      "GL_COLOR_ARRAY_TYPE"), # 0x8082
-    (I,        1,      "GL_COLOR_ARRAY_STRIDE"),       # 0x8083
-    (I,        1,      "GL_INDEX_ARRAY_TYPE"), # 0x8085
-    (I,        1,      "GL_INDEX_ARRAY_STRIDE"),       # 0x8086
-    (I,        1,      "GL_TEXTURE_COORD_ARRAY_SIZE"), # 0x8088
-    (I,        1,      "GL_TEXTURE_COORD_ARRAY_TYPE"), # 0x8089
-    (I,        1,      "GL_TEXTURE_COORD_ARRAY_STRIDE"),       # 0x808A
-    (I,        1,      "GL_EDGE_FLAG_ARRAY_STRIDE"),   # 0x808C
+from gltypes import *
+from glparams import *
+
+
+texture_targets = [
+    ('GL_TEXTURE_1D', 'GL_TEXTURE_BINDING_1D'),
+    ('GL_TEXTURE_2D', 'GL_TEXTURE_BINDING_2D'),
+    ('GL_TEXTURE_3D', 'GL_TEXTURE_BINDING_3D'),
+    ('GL_TEXTURE_RECTANGLE', 'GL_TEXTURE_BINDING_RECTANGLE'),
+    ('GL_TEXTURE_CUBE_MAP', 'GL_TEXTURE_BINDING_CUBE_MAP')
 ]
 
 
+class GetInflector:
+    '''Objects that describes how to inflect.'''
+
+    reduced_types = {
+        B: I,
+        E: I,
+        I: F,
+    }
+
+    def __init__(self, radical, inflections, suffix = ''):
+        self.radical = radical
+        self.inflections = inflections
+        self.suffix = suffix
+
+    def reduced_type(self, type):
+        if type in self.inflections:
+            return type
+        if type in self.reduced_types:
+            return self.reduced_type(self.reduced_types[type])
+        raise NotImplementedError
+
+    def inflect(self, type):
+        return self.radical + self.inflection(type) + self.suffix
+
+    def inflection(self, type):
+        type = self.reduced_type(type)
+        assert type in self.inflections
+        return self.inflections[type]
+
+    def __str__(self):
+        return self.radical + self.suffix
+
+
+class StateGetter(Visitor):
+    '''Type visitor that is able to extract the state via one of the glGet*
+    functions.
+
+    It will declare any temporary variable
+    '''
+
+    def __init__(self, radical, inflections, suffix=''):
+        self.inflector = GetInflector(radical, inflections)
+        self.suffix = suffix
+
+    def __call__(self, *args):
+        pname = args[-1]
+
+        for function, type, count, name in parameters:
+            if type is X:
+                continue
+            if name == pname:
+                if count != 1:
+                    type = Array(type, str(count))
+
+                return type, self.visit(type, args)
+
+        raise NotImplementedError
+
+    def temp_name(self, args):
+        '''Return the name of a temporary variable to hold the state.'''
+        pname = args[-1]
+
+        return pname[3:].lower()
+
+    def visit_const(self, const, args):
+        return self.visit(const.type, args)
+
+    def visit_scalar(self, type, args):
+        temp_name = self.temp_name(args)
+        elem_type = self.inflector.reduced_type(type)
+        inflection = self.inflector.inflect(type)
+        if inflection.endswith('v'):
+            print '    %s %s = 0;' % (elem_type, temp_name)
+            print '    %s(%s, &%s);' % (inflection + self.suffix, ', '.join(args), temp_name)
+        else:
+            print '    %s %s = %s(%s);' % (elem_type, temp_name, inflection + self.suffix, ', '.join(args))
+        return temp_name
+
+    def visit_string(self, string, args):
+        temp_name = self.temp_name(args)
+        inflection = self.inflector.inflect(string)
+        assert not inflection.endswith('v')
+        print '    %s %s = (%s)%s(%s);' % (string, temp_name, string, inflection + self.suffix, ', '.join(args))
+        return temp_name
+
+    def visit_alias(self, alias, args):
+        return self.visit_scalar(alias, args)
+
+    def visit_enum(self, enum, args):
+        return self.visit(GLint, args)
+
+    def visit_bitmask(self, bitmask, args):
+        return self.visit(GLint, args)
+
+    def visit_array(self, array, args):
+        temp_name = self.temp_name(args)
+        if array.length == '1':
+            return self.visit(array.type)
+        elem_type = self.inflector.reduced_type(array.type)
+        inflection = self.inflector.inflect(array.type)
+        assert inflection.endswith('v')
+        print '    %s %s[%s];' % (elem_type, temp_name, array.length)
+        print '    memset(%s, 0, %s * sizeof *%s);' % (temp_name, array.length, temp_name)
+        print '    %s(%s, %s);' % (inflection + self.suffix, ', '.join(args), temp_name)
+        return temp_name
+
+    def visit_opaque(self, pointer, args):
+        temp_name = self.temp_name(args)
+        inflection = self.inflector.inflect(pointer)
+        assert inflection.endswith('v')
+        print '    GLvoid *%s;' % temp_name
+        print '    %s(%s, &%s);' % (inflection + self.suffix, ', '.join(args), temp_name)
+        return temp_name
+
+
+glGet = StateGetter('glGet', {
+    B: 'Booleanv',
+    I: 'Integerv',
+    F: 'Floatv',
+    D: 'Doublev',
+    S: 'String',
+    P: 'Pointerv',
+})
+
+glGetMaterial = StateGetter('glGetMaterial', {I: 'iv', F: 'fv'})
+glGetLight = StateGetter('glGetLight', {I: 'iv', F: 'fv'})
+glGetVertexAttrib = StateGetter('glGetVertexAttrib', {I: 'iv', F: 'fv', D: 'dv', P: 'Pointerv'})
+glGetTexParameter = StateGetter('glGetTexParameter', {I: 'iv', F: 'fv'})
+glGetTexEnv = StateGetter('glGetTexEnv', {I: 'iv', F: 'fv'})
+glGetTexLevelParameter = StateGetter('glGetTexLevelParameter', {I: 'iv', F: 'fv'})
+glGetShader = StateGetter('glGetShaderiv', {I: 'iv'})
+glGetProgram = StateGetter('glGetProgram', {I: 'iv'})
+glGetProgramARB = StateGetter('glGetProgram', {I: 'iv', F: 'fv', S: 'Stringv'}, 'ARB')
+
+
+class JsonWriter(Visitor):
+    '''Type visitor that will dump a value of the specified type through the
+    JSON writer.
+    
+    It expects a previously declared JSONWriter instance named "json".'''
+
+    def visit_literal(self, literal, instance):
+        if literal.format == 'Bool':
+            print '    json.writeBool(%s);' % instance
+        elif literal.format in ('SInt', 'Uint', 'Float', 'Double'):
+            print '    json.writeNumber(%s);' % instance
+        else:
+            raise NotImplementedError
+
+    def visit_string(self, string, instance):
+        assert string.length is None
+        print '    json.writeString((const char *)%s);' % instance
+
+    def visit_enum(self, enum, instance):
+        if enum.expr == 'GLenum':
+            print '    dumpEnum(json, %s);' % instance
+        else:
+            print '    json.writeNumber(%s);' % instance
+
+    def visit_bitmask(self, bitmask, instance):
+        raise NotImplementedError
+
+    def visit_alias(self, alias, instance):
+        self.visit(alias.type, instance)
+
+    def visit_opaque(self, opaque, instance):
+        print '    json.writeNumber((size_t)%s);' % instance
+
+    __index = 0
+
+    def visit_array(self, array, instance):
+        index = '__i%u' % JsonWriter.__index
+        JsonWriter.__index += 1
+        print '    json.beginArray();'
+        print '    for (unsigned %s = 0; %s < %s; ++%s) {' % (index, index, array.length, index)
+        self.visit(array.type, '%s[%s]' % (instance, index))
+        print '    }'
+        print '    json.endArray();'
+
+
+
 class StateDumper:
+    '''Class to generate code to dump all GL state in JSON format via
+    stdout.'''
 
     def __init__(self):
-        self.level = 0
+        pass
 
     def dump(self):
         print '#include <string.h>'
         print
         print '#include "json.hpp"'
-        print '#include "glimports.hpp"'
+        print '#include "glproc.hpp"'
+        print '#include "glsize.hpp"'
         print '#include "glstate.hpp"'
         print
-        print 'void state_dump(std::ostream &os)'
+        print 'namespace glstate {'
+        print
+
+        print 'const char *'
+        print 'enumToString(GLenum pname)'
         print '{'
-        print '    JSONWriter json(os);'
-        self.dump_parameters()
+        print '    switch(pname) {'
+        for name in GLenum.values:
+            print '    case %s:' % name
+            print '        return "%s";' % name
+        print '    default:'
+        print '        return NULL;'
+        print '    }'
+        print '}'
+        print
 
+        print 'void'
+        print 'dumpEnum(JSONWriter &json, GLenum pname)'
+        print '{'
+        print '    const char *s = enumToString(pname);'
+        print '    if (s) {'
+        print '        json.writeString(s);'
+        print '    } else {'
+        print '        json.writeNumber(pname);'
+        print '    }'
         print '}'
         print
 
-    def dump_parameters(self):
-        print '    GLint iparams[16];'
-        print '    GLfloat fparams[16];'
+        print 'void dumpParameters(JSONWriter &json)'
+        print '{'
         print '    json.beginMember("parameters");'
         print '    json.beginObject();'
-        for type, count, name in parameters:
-            print '    json.beginMember("%s");' % name
-            if type is I:
-                print '    memset(iparams, 0, %u * sizeof *iparams);' % count
-                print '    glGetIntegerv(%s, iparams);' % name
-                if count == 1:
-                    print '    json.writeNumber(iparams[0]);'
-                else:
-                    print '    json.beginArray();'
-                    for i in range(count):
-                        print '    json.writeNumber(iparams[%u]);' % i
-                    print '    json.endArray();'
-            else:
-                print '    memset(fparams, 0, %u * sizeof *fparams);' % count
-                print '    glGetFloatv(%s, fparams);' % name
-                if count == 1:
-                    print '    json.writeNumber(fparams[0]);'
-                else:
-                    print '    json.beginArray();'
-                    for i in range(count):
-                        print '    json.writeNumber(fparams[%u]);' % i
-                    print '    json.endArray();'
-            print '    json.endMember();'
+        
+        self.dump_atoms(glGet)
+        
+        self.dump_material_params()
+        self.dump_light_params()
+        self.dump_vertex_attribs()
+        self.dump_texenv_params()
+        self.dump_program_params()
+        self.dump_texture_parameters()
+
         print '    json.endObject();'
         print '    json.endMember(); // parameters'
+        print '}'
         print
-            
-    def write_line(s):
-        self.write('  '*self.level + s + '\n')
+        
+        print '} /*namespace glstate */'
 
-    def write(self, s):
-        sys.stdout.write(s)
+    def dump_material_params(self):
+        for face in ['GL_FRONT', 'GL_BACK']:
+            print '    json.beginMember("%s");' % face
+            print '    json.beginObject();'
+            self.dump_atoms(glGetMaterial, face)
+            print '    json.endObject();'
+        print
 
-    def indent(self):
-        self.level += 1
+    def dump_light_params(self):
+        print '    GLint max_lights = 0;'
+        print '    __glGetIntegerv(GL_MAX_LIGHTS, &max_lights);'
+        print '    for (GLint index = 0; index < max_lights; ++index) {'
+        print '        GLenum light = GL_LIGHT0 + index;'
+        print '        if (glIsEnabled(light)) {'
+        print '            char name[32];'
+        print '            snprintf(name, sizeof name, "GL_LIGHT%i", index);'
+        print '            json.beginMember(name);'
+        print '            json.beginObject();'
+        self.dump_atoms(glGetLight, '    GL_LIGHT0 + index')
+        print '            json.endObject();'
+        print '            json.endMember(); // GL_LIGHTi'
+        print '        }'
+        print '    }'
+        print
 
-    def dedent(self):
-        self.level -= 1
+    def dump_texenv_params(self):
+        for target in ['GL_TEXTURE_ENV', 'GL_TEXTURE_FILTER_CONTROL', 'GL_POINT_SPRITE']:
+            if target != 'GL_TEXTURE_FILTER_CONTROL':
+                print '    if (glIsEnabled(%s)) {' % target
+            else:
+                print '    {'
+            print '        json.beginMember("%s");' % target
+            print '        json.beginObject();'
+            self.dump_atoms(glGetTexEnv, target)
+            print '        json.endObject();'
+            print '    }'
+
+    def dump_vertex_attribs(self):
+        print '    GLint max_vertex_attribs = 0;'
+        print '    __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);'
+        print '    for (GLint index = 0; index < max_vertex_attribs; ++index) {'
+        print '        char name[32];'
+        print '        snprintf(name, sizeof name, "GL_VERTEX_ATTRIB_ARRAY%i", index);'
+        print '        json.beginMember(name);'
+        print '        json.beginObject();'
+        self.dump_atoms(glGetVertexAttrib, 'index')
+        print '        json.endObject();'
+        print '        json.endMember(); // GL_VERTEX_ATTRIB_ARRAYi'
+        print '    }'
+        print
+
+    program_targets = [
+        'GL_FRAGMENT_PROGRAM_ARB',
+        'GL_VERTEX_PROGRAM_ARB',
+    ]
+
+    def dump_program_params(self):
+        for target in self.program_targets:
+            print '    if (glIsEnabled(%s)) {' % target
+            print '        json.beginMember("%s");' % target
+            print '        json.beginObject();'
+            self.dump_atoms(glGetProgramARB, target)
+            print '        json.endObject();'
+            print '    }'
+
+    def dump_texture_parameters(self):
+        print '    {'
+        print '        GLint active_texture = GL_TEXTURE0;'
+        print '        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
+        print '        GLint max_texture_coords = 0;'
+        print '        glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
+        print '        GLint max_combined_texture_image_units = 0;'
+        print '        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);'
+        print '        GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);'
+        print '        for (GLint unit = 0; unit < max_units; ++unit) {'
+        print '            char name[32];'
+        print '            snprintf(name, sizeof name, "GL_TEXTURE%i", unit);'
+        print '            json.beginMember(name);'
+        print '            glActiveTexture(GL_TEXTURE0 + unit);'
+        print '            json.beginObject();'
+        print '            GLint texture;'
+        print
+        for target, binding in texture_targets:
+            print '            // %s' % target
+            print '            texture = 0;'
+            print '            glGetIntegerv(%s, &texture);' % binding
+            print '            if (glIsEnabled(%s) || texture) {' % target
+            print '                json.beginMember("%s");' % target
+            print '                json.beginObject();'
+            self.dump_atoms(glGetTexParameter, target)
+            # We only dump the first level parameters
+            self.dump_atoms(glGetTexLevelParameter, target, "0")
+            print '                json.endObject();'
+            print '                json.endMember(); // %s' % target
+            print '            }'
+            print
+        print '            json.endObject();'
+        print '            json.endMember(); // GL_TEXTUREi'
+        print '        }'
+        print '        glActiveTexture(active_texture);'
+        print '    }'
+        print
 
+    def dump_atoms(self, getter, *args):
+        for function, type, count, name in parameters:
+            inflection = getter.inflector.radical + getter.suffix
+            if inflection not in function.split(','):
+                continue
+            if type is X:
+                continue
+            print '        // %s' % name
+            print '        {'
+            type, value = getter(*(args + (name,)))
+            print '            if (glGetError() != GL_NO_ERROR) {'
+            #print '                std::cerr << "warning: %s(%s) failed\\n";' % (inflection, name)
+            print '            } else {'
+            print '                json.beginMember("%s");' % name
+            JsonWriter().visit(type, value)
+            print '                json.endMember();'
+            print '            }'
+            print '        }'
+            print
 
 
 if __name__ == '__main__':