1'''OpenGL extension ARB.uniform_buffer_object 2 3This module customises the behaviour of the 4OpenGL.raw.GL.ARB.uniform_buffer_object to provide a more 5Python-friendly API 6 7Overview (from the spec) 8 9 This extension introduces the concept of a group of GLSL uniforms 10 known as a "uniform block", and the API mechanisms to store "uniform 11 blocks" in GL buffer objects. 12 13 The extension also defines both a standard cross-platform layout in 14 memory for uniform block data, as well as mechanisms to allow the GL 15 to optimize the data layout in an implementation-defined manner. 16 17 Prior to this extension, the existing interface for modification of 18 uniform values allowed modification of large numbers of values using 19 glUniform* calls, but only for a single uniform name (or a uniform 20 array) at a time. However, updating uniforms in this manner may not 21 map well to heterogenous uniform data structures defined for a GL 22 application and in these cases, the application is forced to either: 23 24 A) restructure their uniform data definitions into arrays 25 or 26 B) make an excessive number of calls through the GL interface 27 to one of the Uniform* variants. 28 29 These solutions have their disadvantages. Solution A imposes 30 considerable development overhead on the application developer. 31 Solution B may impose considerable run-time overhead on the 32 application if the number of uniforms modified in a given frame of 33 rendering is sufficiently large. 34 35 This extension provides a better alternative to either (A) or (B) by 36 allowing buffer object backing for the storage associated with all 37 uniforms of a given GLSL program. 38 39 Storing uniform blocks in buffer objects enables several key use 40 cases: 41 42 - sharing of uniform data storage between program objects and 43 between program stages 44 45 - rapid swapping of sets of previously defined uniforms by storing 46 sets of uniform data on the GL server 47 48 - rapid updates of uniform data from both the client and the server 49 50 The data storage for a uniform block can be declared to use one of 51 three layouts in memory: packed, shared, or std140. 52 53 - "packed" uniform blocks have an implementation-dependent data 54 layout for efficiency, and unused uniforms may be eliminated by 55 the compiler to save space. 56 57 - "shared" uniform blocks, the default layout, have an implementation- 58 dependent data layout for efficiency, but the layout will be uniquely 59 determined by the structure of the block, allowing data storage to be 60 shared across programs. 61 62 - "std140" uniform blocks have a standard cross-platform cross-vendor 63 layout (see below). Unused uniforms will not be eliminated. 64 65 Any uniforms not declared in a named uniform block are said to 66 be part of the "default uniform block". 67 68 While uniforms in the default uniform block are updated with 69 glUniform* entry points and can have static initializers, uniforms 70 in named uniform blocks are not. Instead, uniform block data is updated 71 using the routines that update buffer objects and can not use static 72 initializers. 73 74 Rules and Concepts Guiding this Specification: 75 76 For reference, a uniform has a "uniform index" (subsequently 77 referred to as "u_index) and also a "uniform location" to 78 efficiently identify it in the uniform data store of the 79 implementation. We subsequently refer to this uniform data store of 80 the implementation as the "uniform database". 81 82 A "uniform block" only has a "uniform block index" used for queries 83 and connecting the "uniform block" to a buffer object. A "uniform 84 block" has no "location" because "uniform blocks" are not updated 85 directly. The buffer object APIs are used instead. 86 87 Properties of Uniforms and uniform blocks: 88 89 a) A uniform is "active" if it exists in the database and has a valid 90 u_index. 91 b) A "uniform block" is "active" if it exists in the database and 92 has a valid ub_index. 93 c) Uniforms and "uniform blocks" can be inactive because they don't 94 exist in the source, or because they have been removed by dead 95 code elimination. 96 d) An inactive uniform has u_index == INVALID_INDEX. 97 e) An inactive uniform block has ub_index == INVALID_INDEX. 98 f) A u_index or ub_index of INVALID_INDEX generates the 99 INVALID_VALUE error if given as a function argument. 100 g) The default uniform block, which is not assigned any ub_index, uses a 101 private, internal data storage, and does not have any buffer object 102 associated with it. 103 h) An active uniform that is a member of the default uniform block has 104 location >= 0 and it has offset == stride == -1. 105 i) An active uniform that is a member of a named uniform block has 106 location == -1. 107 j) A uniform location of -1 is silently ignored if given as a function 108 argument. 109 k) Uniform block declarations may not be nested 110 111The official definition of this extension is available here: 112http://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt 113''' 114from OpenGL import platform, constant, arrays 115from OpenGL import extensions, wrapper 116import ctypes 117from OpenGL.raw.GL import _types, _glgets 118from OpenGL.raw.GL.ARB.uniform_buffer_object import * 119from OpenGL.raw.GL.ARB.uniform_buffer_object import _EXTENSION_NAME 120 121def glInitUniformBufferObjectARB(): 122 '''Return boolean indicating whether this extension is available''' 123 from OpenGL import extensions 124 return extensions.hasGLExtension( _EXTENSION_NAME ) 125 126# INPUT glGetUniformIndices.uniformNames size not checked against 'uniformCount' 127glGetUniformIndices=wrapper.wrapper(glGetUniformIndices).setOutput( 128 'uniformIndices',size=_glgets._glget_size_mapping,pnameArg='uniformCount',orPassIn=True 129).setInputArraySize( 130 'uniformNames', None 131) 132# OUTPUT glGetActiveUniformsiv.params COMPSIZE(uniformCount, pname) 133# INPUT glGetActiveUniformsiv.uniformIndices size not checked against uniformCount 134glGetActiveUniformsiv=wrapper.wrapper(glGetActiveUniformsiv).setInputArraySize( 135 'uniformIndices', None 136) 137glGetActiveUniformName=wrapper.wrapper(glGetActiveUniformName).setOutput( 138 'length',size=(1,),orPassIn=True 139).setOutput( 140 'uniformName',size=lambda x:(x,),pnameArg='bufSize',orPassIn=True 141) 142# INPUT glGetUniformBlockIndex.uniformBlockName size not checked against '' 143glGetUniformBlockIndex=wrapper.wrapper(glGetUniformBlockIndex).setInputArraySize( 144 'uniformBlockName', None 145) 146# OUTPUT glGetActiveUniformBlockiv.params COMPSIZE(program, uniformBlockIndex, pname) 147glGetActiveUniformBlockName=wrapper.wrapper(glGetActiveUniformBlockName).setOutput( 148 'length',size=(1,),orPassIn=True 149).setOutput( 150 'uniformBlockName',size=lambda x:(x,),pnameArg='bufSize',orPassIn=True 151) 152glGetIntegeri_v=wrapper.wrapper(glGetIntegeri_v).setOutput( 153 'data',size=_glgets._glget_size_mapping,pnameArg='target',orPassIn=True 154) 155### END AUTOGENERATED SECTION