Virtual Reality, Visualization and Imaging Research Centre |
Department of Computer Science & Engineering, CUHK. |
|
|
Yongming Xie |
Demo Geometry Shader Tutorials by Xie Yongming 15/11 2006
Introduction Nvidia opened the geometry shader at November 13, 2006 , A geometry shader begins with a single primitive (point, line, triangle). It can read the attributes of any of the vertices in the primitive and use them to generate new primitives. A geometry shader has a fixed output primitive type (point, line strip, or triangle strip) and emits vertices to define a new primitive. A geometry shader can emit multiple disconnected primitives. The primitives emitted by the geometry shader are clipped and then processed like an equivalent OpenGL primitive specified by the application. Thanks for Nvidia's developer great work! Geometry shader fit into Opengl pipeline
First, vertex attributes are specified via immediate-mode commands or through vertex arrays. They can be conventional attributes (e.g., glVertex, glColor, glTexCoord) or generic (numbered) attributes. Vertices are then transformed, either using a vertex shader or fixed-function vertex processing. Fixed-function vertex processing includes position transformation (modelview and projection matrices), lighting, texture coordinate generation, and other calculations. The results of either method are a "transformed vertex", which has a position (in clip coordinates), front and back colors, texture coordinates, generic attributes (vertex shader only), and so on. Note that on many current GL implementations, vertex processing is performed by executing a "fixed function vertex shader" generated by the driver. After vertex transformation, vertices are assembled into primitives, according to the topology (e.g., TRIANGLES, QUAD_STRIP) provided by the call to glBegin(). Primitives are points, lines, triangles, quads, or polygons, but instead decompose them into triangles as permitted by the spec. After initial primitive assembly, a geometry shader is executed on eachindividual point, line, or triangle primitive, if one is active. It can read the attributes of each transformed vertex, perform arbitrary computations, and emit new transformed vertices. These emitted vertices are themselves assembled into primitives according to the output primitive type of the geometry shader. Then, the colors of the vertices of each primitive are clamped to [0,1](if color clamping is enabled), and flat shading may be performed by taking the color from the provoking vertex of the primitive. Each primitive is clipped to the view volume, and to any enabled user-defined clip planes. Color, texture coordinate, and other attribute values are computed for each new vertex introduced by clipping. After clipping, the position of each vertex (in clip coordinates) is converted to normalized device coordinates in the perspective division (divide by w) step, and to window coordinates in the viewport transformation step. At the same time, color values may be converted to normalized fixed-point values according to the "Final Color Processing" portion of the specification. After the vertices of the primitive are transformed to window coordinate, the GL determines if the primitive is front- or back-facing. That information is used for two-sided color selection, where a single set of colors is selected from either the front or back colors associated with each transformed vertex. When all this is done, the final transformed position, colors (primary and secondary), and other attributes are used for rasterization (Chapter 3 in the OpenGL 2.0 Specification). When the raster position is specified (via glRasterPos), it goes through the entire vertex processing pipeline as though it were a point. However, geometry shaders are never run on the raster position.
Geometry shader setup for GLSL Nvidia's NVemulate allows you to emulate the functionality of various GPUs (very slowly) in software. In addition, you can use it to control GLSL Support. New in this version of NVemulate:
GLSL support is enabled by default in Nvidia's Release 95 drivers, but you can enable/disable the enhanced GLSL support as well as manipulate software emulation of GPU feature sets and control the dumping of GLSL source and assembly text for debugging, The NVemulate control panel looks like this:
here three extensions are required:
Creating a Program The figure bellow shows the necessary steps (in OpenGL 2.0 syntax) to create the geometry shader, the functions used will be detailed in latter sections.
The first step is creating an object which will act as a program container. The function available for this purpose returns a handle for the container. The syntax for this function, in OpenGL 2.0 syntax is as follows: GLhandleARB glCreateProgramObjectARB(void); void glProgramParameteriEXT(GLhandleARB program, enum pname, int value); Geometry shader Input Primitives glProgramParameteriEXT with <pname> set to GEOMETRY_INPUT_TYPE_EXT and <value> set to one of POINTS, LINES, glProgramParameteriEXT(GLhandleARB program,GL_GEOMETRY_INPUT_TYPE_EXT ,GL_LINES_ADJACENCY_EXT); Geometry Shader Output Primitives The output primitive type is a parameter of the program object, and can be set by calling glProgramParameteriEXT with <pname> set to GL_GEOMETRY_OUTPUT_TYPE_EXT and <value> set to one of GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP. glProgramParameteriEXT(GLhandleARB program,GL_GEOMETRY_OUTPUT_TYPE_EXT ,GL_LINE_STRIP); Geometry Shader outputs glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp); glProgramParameteriEXT(GLhandleARB program,GL_GEOMETRY_VERTICES_OUT_EXT,<temp) To attach a shader to a program use the OpenGL 2.0 function: void glAttachObjectARB(GLhandleARB program, GLhandleARB shader); Parameters:
The syntax for the link function, in OpenGL 2.0, is as follows: void glLinkProgramARB(GLhandleARB program); Parameters:
After the link operation the shader's source can be modified, and the shaders recompiled without affecting the program. As shown in the figure above, after linking the program, there is a function to actually load and use the program, (ARB extension) glUseProgramObjectARB, or (OpenGL 2.0) glUseProgram. Each program is assigned an handler, and you can have as many programs linked and ready to use as you want (and your hardware allows). The syntax for this function is as follows (OpenGL 2.0 notation): void glUseProgramObjectARB(GLhandleARB prog); Parameters:
Creating a shader The first step is creating an object which will act as a shader container. The function available for this purpose returns a handle for the container. The OpenGL 2.0 syntax for this function is as follows: GLhandleARB glCreateShaderObjectARB(GLenum shaderType); Parameter:
You can create as many shaders as you want to add to a program, but remember that there can only be a main function for the set of vertex shaders and one main function for the set of fragment shaders in each single program. The following step is to add some source code. The source code for a shader is a string array. void glShaderSourceARB(GLhandleARB shader, int numOfStrings, const char **strings, int *lenOfStrings); Parameters:
Finally, the shader must be compiled. The function to achieve this using OpenGL 2.0 is: void glCompileShaderARB(GLhandleARB shader); Parameters:
Creating a geometry shader #version 120 where number must be a version of the language, following the same convention as __VERSION__ above. The directive “#version 120” is required in any shader that uses version 1.20 of the language. #extension GL_EXT_geometry_shader4 : enable where extension_name is the name of an extension. Extension names are not documented in this specification. Geometry language built-in outputs:varying out vec4 gl_FrontColor; varying out vec4 gl_BackColor; varying out vec4 gl_FrontSecondaryColor; varying out vec4 gl_BackSecondaryColor; varying out vec4 gl_TexCoord[]; // at most gl_MaxTextureCoords varying out float gl_FogFragCoord;
The function EndPrimitive() specifies that the current output primitive is completed and a new output primitive (of the same type) should be started. This function does not emit a vertex. The effect of EndPrimitive() is roughly equivalent to calling End followed by a new Begin, where the primitive mode is taken from the program object parameter GEOMETRY_OUTPUT_TYPE_EXT. If the output primitive type is POINTS, calling EndPrimitive() is optional.
Demo&source code. Demo :
Download Demo: Demo.zip for windows XP. source code: EMAIL to ymxie@cse.cuhk.edu.hk References http://developer.nvidia.com/object/nvemulate.html http://developer.nvidia.com/object/nvidia_opengl_specs.html
|