[vlc-commits] OpenGL: use 3D coordinates and a vertex index buffer to draw the texture rectangle

Adrien Maglo git at videolan.org
Sun May 29 10:31:49 CEST 2016


vlc | branch: master | Adrien Maglo <magsoft at videolan.org> | Wed May 25 19:55:23 2016 +0200| [ecae60171f02c2ac8c45437aebf704a97942c50e] | committer: Jean-Baptiste Kempf

OpenGL: use 3D coordinates and a vertex index buffer to draw the texture rectangle

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ecae60171f02c2ac8c45437aebf704a97942c50e
---

 modules/video_output/opengl.c |  117 +++++++++++++++++++++++++++++++++--------
 1 file changed, 94 insertions(+), 23 deletions(-)

diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index d6217b5..d14a531 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -143,6 +143,7 @@ struct vout_display_opengl_t {
     GLfloat    local_value[16];
 
     GLuint vertex_buffer_object;
+    GLuint index_buffer_object;
     GLuint texture_buffer_object[PICTURE_PLANE_MAX];
 
     GLuint *subpicture_buffer_object;
@@ -236,13 +237,13 @@ static void BuildVertexShader(vout_display_opengl_t *vgl,
         PRECISION
         "varying vec4 TexCoord0,TexCoord1, TexCoord2;"
         "attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
-        "attribute vec2 VertexPosition;"
-        "uniform mat4 RotationMatrix;"
+        "attribute vec3 VertexPosition;"
+        "uniform mat4 OrientationMatrix;"
         "void main() {"
         " TexCoord0 = MultiTexCoord0;"
         " TexCoord1 = MultiTexCoord1;"
         " TexCoord2 = MultiTexCoord2;"
-        " gl_Position = RotationMatrix * vec4(VertexPosition, 0.0, 1.0);"
+        " gl_Position = OrientationMatrix * vec4(VertexPosition, 1.0);"
         "}";
 
     *shader = vgl->CreateShader(GL_VERTEX_SHADER);
@@ -681,12 +682,13 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     glDisable(GL_BLEND);
     glDisable(GL_DEPTH_TEST);
     glDepthMask(GL_FALSE);
-    glDisable(GL_CULL_FACE);
+    glEnable(GL_CULL_FACE);
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
 
 #ifdef SUPPORTS_SHADERS
     vgl->GenBuffers(1, &vgl->vertex_buffer_object);
+    vgl->GenBuffers(1, &vgl->index_buffer_object);
     vgl->GenBuffers(vgl->chroma->plane_count, vgl->texture_buffer_object);
 
     /* Initial number of allocated buffer objects for subpictures, will grow dynamically. */
@@ -741,6 +743,7 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
                 vgl->DeleteShader(vgl->shader[i]);
         }
         vgl->DeleteBuffers(1, &vgl->vertex_buffer_object);
+        vgl->DeleteBuffers(1, &vgl->index_buffer_object);
         vgl->DeleteBuffers(vgl->chroma->plane_count, vgl->texture_buffer_object);
         if (vgl->subpicture_buffer_object_count > 0)
             vgl->DeleteBuffers(vgl->subpicture_buffer_object_count, vgl->subpicture_buffer_object);
@@ -1116,6 +1119,65 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
 }
 #endif
 
+
+static int BuildRectangle(unsigned nbPlanes,
+                          GLfloat **vertexCoord, GLfloat **textureCoord, unsigned *nbVertices,
+                          GLushort **indices, unsigned *nbIndices,
+                          float *left, float *top, float *right, float *bottom)
+{
+    *nbVertices = 4;
+    *nbIndices = 6;
+
+    *vertexCoord = malloc(*nbVertices * 3 * sizeof(GLfloat));
+    if (*vertexCoord == NULL)
+        return VLC_ENOMEM;
+    *textureCoord = malloc(nbPlanes * *nbVertices * 2 * sizeof(GLfloat));
+    if (*textureCoord == NULL)
+    {
+        free(*vertexCoord);
+        return VLC_ENOMEM;
+    }
+    *indices = malloc(*nbIndices * sizeof(GLushort));
+    if (*indices == NULL)
+    {
+        free(*textureCoord);
+        free(*vertexCoord);
+        return VLC_ENOMEM;
+    }
+
+    static const GLfloat coord[] = {
+       -1.0,    1.0,    -1.0f,
+       -1.0,    -1.0,   -1.0f,
+       1.0,     1.0,    -1.0f,
+       1.0,     -1.0,   -1.0f
+    };
+
+    memcpy(*vertexCoord, coord, *nbVertices * 3 * sizeof(GLfloat));
+
+    for (unsigned p = 0; p < nbPlanes; ++p)
+    {
+        const GLfloat tex[] = {
+            left[p],  top[p],
+            left[p],  bottom[p],
+            right[p], top[p],
+            right[p], bottom[p]
+        };
+
+        memcpy(*textureCoord + p * *nbVertices * 2, tex,
+               *nbVertices * 2 * sizeof(GLfloat));
+    }
+
+    const GLushort ind[] = {
+        0, 1, 2,
+        2, 1, 3
+    };
+
+    memcpy(*indices, ind, *nbIndices * sizeof(GLushort));
+
+    return VLC_SUCCESS;
+}
+
+
 #ifdef SUPPORTS_SHADERS
 static void DrawWithShaders(vout_display_opengl_t *vgl,
                             float *left, float *top, float *right, float *bottom,
@@ -1137,46 +1199,55 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
         vgl->Uniform4f(vgl->GetUniformLocation(vgl->program[1], "FillColor"), 1.0f, 1.0f, 1.0f, 1.0f);
     }
 
-    static const GLfloat vertexCoord[] = {
-        -1.0,  1.0,
-        -1.0, -1.0,
-         1.0,  1.0,
-         1.0, -1.0,
-    };
+    GLfloat *vertexCoord, *textureCoord;
+    GLushort *indices;
+    unsigned nbVertices, nbIndices;
 
-    GLfloat transformMatrix[16];
-    orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
+    int i_ret = BuildRectangle(vgl->chroma->plane_count,
+                               &vertexCoord, &textureCoord, &nbVertices,
+                               &indices, &nbIndices,
+                               left, top, right, bottom);
+
+    if (i_ret != VLC_SUCCESS)
+        return;
+
+    GLfloat projectionMatrix[16], viewMatrix[16],
+            yRotMatrix[16], xRotMatrix[16],
+            zoomMatrix[16], orientationMatrix[16];
+
+    orientationTransformMatrix(orientationMatrix, vgl->fmt.orientation);
 
     for (unsigned j = 0; j < vgl->chroma->plane_count; j++) {
-        const GLfloat textureCoord[] = {
-            left[j],  top[j],
-            left[j],  bottom[j],
-            right[j], top[j],
-            right[j], bottom[j],
-        };
         glActiveTexture(GL_TEXTURE0+j);
         glClientActiveTexture(GL_TEXTURE0+j);
         glBindTexture(vgl->tex_target, vgl->texture[0][j]);
 
         vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->texture_buffer_object[j]);
-        vgl->BufferData(GL_ARRAY_BUFFER, sizeof(textureCoord), textureCoord, GL_STATIC_DRAW);
+        vgl->BufferData(GL_ARRAY_BUFFER, nbVertices * 2 * sizeof(GLfloat),
+                        textureCoord + j * nbVertices * 2, GL_STATIC_DRAW);
 
         char attribute[20];
         snprintf(attribute, sizeof(attribute), "MultiTexCoord%1d", j);
         vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program], attribute));
         vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], attribute), 2, GL_FLOAT, 0, 0, 0);
     }
+    free(textureCoord);
     glActiveTexture(GL_TEXTURE0 + 0);
     glClientActiveTexture(GL_TEXTURE0 + 0);
 
     vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->vertex_buffer_object);
-    vgl->BufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
+    vgl->BufferData(GL_ARRAY_BUFFER, nbVertices * 3 * sizeof(GLfloat), vertexCoord, GL_STATIC_DRAW);
+    free(vertexCoord);
+    vgl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, vgl->index_buffer_object);
+    vgl->BufferData(GL_ELEMENT_ARRAY_BUFFER, nbIndices * sizeof(GLushort), indices, GL_STATIC_DRAW);
+    free(indices);
     vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"));
-    vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"), 2, GL_FLOAT, 0, 0, 0);
+    vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"), 3, GL_FLOAT, 0, 0, 0);
 
-    vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program], "RotationMatrix"), 1, GL_FALSE, transformMatrix);
+    vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program], "OrientationMatrix"), 1, GL_FALSE, orientationMatrix);
 
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    vgl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, vgl->index_buffer_object);
+    glDrawElements(GL_TRIANGLES, nbIndices, GL_UNSIGNED_SHORT, 0);
 }
 #endif
 



More information about the vlc-commits mailing list