OpenGL learning diary-2015.3.13 -- Multi-instance rendering, opengl-2015.3.13

Source: Internet
Author: User
Tags clear screen

OpenGL learning diary-2015.3.13 -- Multi-instance rendering, opengl-2015.3.13
Instancing or instancd rendering is a method for continuously executing multiple identical rendering commands. The rendering results produced by each command are slightly different. It is a very effective method that uses a small number of api calls to render a large number of ry. OpenGL provides multiple mechanisms to allow the shader to assign different vertex attributes to different rendering instances. Several simple multi-instance rendering commands: 1. void glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primCount) this function is a multi-instance version of glDrawArrays (). The parameters are completely equivalent, only a primCount is added. This parameter is used to set the number of rendering instances. 2. void glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, void * indices, GLsizei primcount) this function is a multi-instance version of glDrawElements, the parameter primCount is also used to set the number of rendering instances. 3. void Merge (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instanceCount, GLuint baseVertex) Multi-instance version of glDrawElementsBaseVertex, instanceCount indicates the number of rendered instances.
Multi-instance rendering vertex attribute control: 1. void glVertexAttribDivisor (GLenum index, GLuint divisor) index corresponds to the location of the input variable in the shader. Divisor: indicates the update frequency of vertex attributes. This attribute is reset for every number of instances. For example, if this attribute is set to 1, the attributes of each instance are different, if it is set to 2, each two instances are the same, and 3 changes the attributes of each three instances. The attribute array size of this attribute will be (instance/divisor), and instance will be the number of rendering instances (primCount) previously set. Assume that the instance color is changed in Multi-instance rendering, if divisor is set to 2, instance is 100, and the color array is at least 100/2 = 50 sets of rgba data, each instance can have its own color value, otherwise it will be black. Finally, if the divisor is set to 0, it indicates that it is not instantiated. The rendering result is that all instances are black, and the result may not be inevitable, I guess the input color of the colorant is set to the default value (0.0, 0.0, 0.0, 1.0,), so it is black.
Vertex coloring tool analysis: # version 410
// Input variable position, vertex coordinate layout (location = 0) in vec4 position; // calculate the normal vertex normal layout (location = 1) in vec3 normal; // vertex color layout (location = 2) in vec4 color;
// Note that the location of the input variable of the mat4 type set here is 3, but a mat4 type occupies four consecutive positions. // Therefore, model_matrix occupies 3, 4, five or six index locations. Layout (location = 3) in mat4 model_matrix;
// In the rendering process of the program, it is the constant view matrix, and the projection matrix (the just program is a constant) uniform mat4 view_matrix; uniform mat4 projection_matrix; // input variable, a simple struct, normal, and color. Out VERTEX {vec3 normal; vec4 color;} vertex;
Void main (void) {// calculate the Model View matrix mat4 model_view_matrix = view_matrix * model_matrix; // calculate the vertex coordinate gl_Position = projection_matrix * (model_view_matrix * position ); // calculate the normal and color, and output vertex. normal = mat3 (model_view_matrix) * normal; vertex. color = color ;}
Analysis of the Cell Coloring tool: # version 410
// Layout (location = 0) out vec4 color output by the cell color palette;
// The input of the bitwise coloring machine is almost the same as that of the vertex coloring machine. in/out must be matched. In VERTEX {vec3 normal; vec4 color;} vertex;
Void main (void) {// calculate the final color = vertex based on the normal. color * (0.1 + abs (vertex. normal. z) + vec4 (0.8, 0.9, 0.7, 1.0) * pow (abs (vertex. normal. z), 40.0 );}
Application code: the Code does not have much analysis. It mainly uses the previous functions for multi-instance rendering settings. The Code has more or less comments in key areas. Paste the code as much as possible here. The vbm format model data is used in the Code. It is probably a format defined by the author. In the source code, the vbm management class has been changed, and the new version cannot read the old version of data. By the way, the eighth version of source code is provided here: http://www.opengl-redbook.com/should be easy to get down. Thank you for your hard work.

# Include "instancing_1.h" # include "vutils. h "# include" vmath. h "# include" inline "namespace instancing1 {float shade_aspect = 800/600; GLuint color_buffer; GLuint model_matrix_buffer; GLuint render_prog; GLuint success; VBObject object; # define INSTANCE_COUNT 100 GLenum gl_err = 0; static const GLubyte * errorStr = NULL ;}; using namespa Ce instancing1; void instancing1Init () {int n; // create the coloring program render_prog = glCreateProgram (); // The colorator string static const char render_vs [] = "# version 410 \ n" "\ n" "// 'position' and 'normal' are regular vertex attributes \ n" "layout (location = 0) in vec4 position; \ n "" layout (location = 1) in vec3 normal; \ n "" \ n "" // Color is a per-instance attribute \ n "" layout (location = 2) in vec4 color; \ n "" \ n "" // model_matrix will be Used as a per-instance transformation \ n "// matrix. note that a mat4 consumes 4 consecutive locations, so \ n "" // this will actually sit in locations, 3, 4, 5, and 6. \ n "" layout (location = 3) in mat4 model_matrix; \ n "" \ n "" // The view matrix and the projection matrix are constant internal ss a draw \ n "" uniform mat4 view_matrix; \ n "" uniform mat4 projection_matrix; \ n "" \ n "" // The output of the vertex shader (m Atched to the fragment shader) \ n "" out VERTEX \ n "" {\ n "" vec3 normal; \ n "" vec4 color; \ n ""} vertex; \ n "" \ n "" // OK, go! \ N "" void main (void) \ n "" {\ n "" // Construct a model-view matrix from the uniform view matrix \ n "" // and the per-instance model matrix. \ n "" mat4 model_view_matrix = view_matrix * model_matrix; \ n "" \ n "" // Transform position by the model-view matrix, then by the \ n "" // projection matrix. \ n "" gl_Position = projection_matrix * (model_view_matrix * position); \ n "" // Transform the normal by the upper-left-3 X3-submatrix of the \ n "" // model-view matrix \ n "" vertex. normal = mat3 (model_view_matrix) * normal; \ n "" // Pass the per-instance color through to the fragment shader. \ n "" vertex. color = color; \ n ""} \ n "; static const char render_fs [] =" # version 410 \ n "" \ n "" layout (location = 0) out vec4 color; \ n "" \ n "" in VERTEX \ n "" {\ n "" vec3 normal; \ n "" vec4 color; \ n ""} vertex; \ n "" \ n "" void main (void) \ n "" {\ n "" color = ve Rtex. color * (0.1 + abs (vertex. normal. z) + vec4 (0.8, 0.9, 0.7, 1.0) * pow (abs (vertex. normal. z), 40.0); \ n ""} \ n "; // create, compile, and load vglAttachShaderSource (render_prog, GL_VERTEX_SHADER, render_vs); vglAttachShaderSource (render_prog, callback, render_fs); // connect to the colorant program glLinkProgram (render_prog); // activate the colorant glUseProgram (render_prog); // obtain the view matrix Position Scheme = glGetUniformLocation (render_prog, "vi Ew_matrix "); // obtain the projection matrix position projection_matrix_loc = glGetUniformLocation (render_prog," projection_matrix "); // load the vbm model file // @ pram 1 path, 2 vertex location 3 normal location, 4 texture location (color) object. loadFromVBM (".. /8 edlib/media/armadillo_low.vbm ", 0, 1, 2); // bind the vertex array object. bindVertexArray (); // get the in variable locationint position_loc = glGetAttribLocation (render_prog, "position"); int normal_loc = glGetAttribLocation (render_prog ," Normal "); int color_loc = glGetAttribLocation (render_prog," color "); int matrix_loc = glGetAttribLocation (render_prog," model_matrix "); // The color array vmath for each instance :: vec4 colors [INSTANCE_COUNT]; for (n = 0; n <INSTANCE_COUNT; n ++) {float a = float (n)/4.0f; float B = float (n) /5.0f; float c = float (n)/6.0f; colors [n] [0] = 0.5f + 0.25f * (sinf (a + 1.0f) + 1.0f ); colors [n] [1] = 0.5f + 0.25f * (sinf (B + 2.0f) + 1.0f); colors [n] [2] = 0.5f + 0.25f * (sinf (c + 3.0f) + 1.0f); colors [n] [3] = 1.0f ;} // cache object glGenBuffers (1, & color_buffer); glBindBuffer (GL_ARRAY_BUFFER, color_buffer); // three jobs. GlBufferData (GL_ARRAY_BUFFER, sizeof (colors), colors, GL_DYNAMIC_DRAW); // dynamically changes the data glVertexAttribPointer (color_loc, 4, GL_FLOAT, GL_FALSE, 0, NULL) used for plotting ); glEnableVertexAttribArray (color_loc );//!!! Enable multiple instance attributes of vertex attributes. Each instance reads the color value (color_loc, 1); // model matrix data glGenBuffers (1, & model_matrix_buffer); glBindBuffer (GL_ARRAY_BUFFER, model_matrix_buffer ); // NULL reserved memory glBufferData (GL_ARRAY_BUFFER, INSTANCE_COUNT * sizeof (vmath: mat4), NULL, GL_DYNAMIC_DRAW); for (int I = 0; I <4; I ++) {glVertexAttribPointer (matrix_loc + I, 4, GL_FLOAT, GL_FALSE, sizeof (vmath: mat4), (void *) (sizeof (vmath: vec4) * I); glablevertexattribarray (matrix_loc + I); glVertexAttribDivisor (matrix_loc + I, 1);} // unbind vao. Why, my understanding is: this is a good habit. After using it, use OpenGL to restore the default state. GlBindVertexArray (0);} static inline int min (int a, int B) {return a <B? A: B;} void instancing1Display () {float t = float (GetTickCount () & 0x3FFF)/float (0x3FFF); int n; // clear screen glClear (GL_COLOR_BUFFER_BIT | bytes ); // glEnable (GL_CULL_FACE); glable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL); // bind a vbo and modify the glBindBuffer (GL_ARRAY_BUFFER, model_matrix_buffer ); // obtain the OpenGL pointer vmath: mat4 * matrices = (vmath: mat4 *) glMapBuffer (GL_ARRAY_BUFFER, GL_WRITE_ONLY) of the current vbo; fo R (n = 0; n <INSTANCE_COUNT; n ++) {float a = 50366f * float (n)/4.0f; float B = 50366f * float (n)/5.0f; float c = 50366f * float (n)/6.0f; matrices [n] = vmath: rotate (a + t * 360.0f, 1.0f, 0.0f, 0.0f) * vmath :: rotate (a + t * 360.0f, 0.0f, 1.0f, 0.0f) * vmath: rotate (a + t * 360.0f, 0.0f, 0.0f, 1.0f) * vmath :: translate (10.0f + a, 40366f + B, 50366f + c); // pan, rotate again} // The data operation is complete, un ing! Must be glUnmapBuffer (GL_ARRAY_BUFFER); // confirm to activate the required coloring program glUseProgram (render_prog); // generate the view matrix and projection matrix vmath: mat4 view_matrix (vmath :: translate (0.0f, 0.0f,-15000000f) * vmath: rotate (t * 360.0f * 2.0f, 0.0f, 1.0f, 0.0f); vmath: mat4 projection_matrix (vmath :: frustum (-1.0f, 1.0f,-shade_aspect, shade_aspect, 1.0f, 5000.0f); // set the view matrix and Projection Matrix Values (view_matrix_loc, 1, GL_FALSE, view_matrix ); // you have not written the error parameter this time. Can you? I thought I had a problem with my IQ. GlUniformMatrix4fv (projection_matrix_loc, 1, GL_FALSE, projection_matrix); // Render multiple instance objects. Render (0, INSTANCE_COUNT); // you can skip this step .. The following vbm is not compatible with the preceding vbm ..... GLenum error = glGetError (); // const GLubyte * errorStr = gluErrorString (error... Lookat only generates a matrix... // Vmath: lookat (vmath: vec3 (0.0f, 0.0f, 0.0f), vmath: vec3 (1.0f, 0.0f, 0.0f), vmath: vec3 (0.0f, 1.0f, 0.0f); // camera ????????? /} Void instancing1Update (float ){}


Another multi-instance rendering instance is used for texture packaging. The built-in variable gl_InstanceID of the shader is used: instance counter gl_InstanceID: the index value of the current instance can be obtained through the built-in variable gl_InstanceID In the vertex coloring tool. This variable is declared as an integer with an initial value of 0. After each instance is rendered, it will add 1. he always exists in the vertex coloring machine. Even if the multi-instance feature is not enabled, his value remains 0. gl_InstanceID can be used as the index of the uniform array, as a texture search parameter, or as the input of an analysis function. New instance analysis: the new example implements the same screen of the previous instance, but the program implementation method is different. The texture cache object is used here, which is an unused feature for me, it won't seem boring to accept new things .................... Although I am not bored, I am still sleepy. I have To go To work for QAQ tomorrow, To Be Continue ~~~~~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.