[vlc-devel] [PATCH 4/6] opengl.c: handle movie transformations.

Rémi Denis-Courmont remi at remlab.net
Fri Feb 28 17:36:35 CET 2014


Le jeudi 27 février 2014, 23:36:00 Matthias Keiser a écrit :
> ---
>  modules/video_output/opengl.c | 91
> +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87
> insertions(+), 4 deletions(-)
> 
> diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
> index 33db19d..99b35c0 100644
> --- a/modules/video_output/opengl.c
> +++ b/modules/video_output/opengl.c
> @@ -35,6 +35,7 @@
>  #include <vlc_opengl.h>
> 
>  #include "opengl.h"
> +#include "math.h"
> 
>  #ifndef GL_CLAMP_TO_EDGE
>  # define GL_CLAMP_TO_EDGE 0x812F
> @@ -49,6 +50,7 @@
>  #   define PFNGLGETATTRIBLOCATIONPROC        typeof(glGetAttribLocation)*
>  #   define PFNGLVERTEXATTRIBPOINTERPROC      typeof(glVertexAttribPointer)*
> #   define PFNGLENABLEVERTEXATTRIBARRAYPROC 
> typeof(glEnableVertexAttribArray)* +#   define PFNGLUNIFORMMATRIX4FVPROC   
>      typeof(glUniformMatrix4fv)* #   define PFNGLUNIFORM4FVPROC            
>   typeof(glUniform4fv)* #   define PFNGLUNIFORM4FPROC               
> typeof(glUniform4f)* #   define PFNGLUNIFORM1IPROC               
> typeof(glUniform1i)* @@ -146,9 +148,10 @@ struct vout_display_opengl_t {
>      PFNGLVERTEXATTRIBPOINTERPROC     VertexAttribPointer;
>      PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
> 
> -    PFNGLUNIFORM4FVPROC   Uniform4fv;
> -    PFNGLUNIFORM4FPROC    Uniform4f;
> -    PFNGLUNIFORM1IPROC    Uniform1i;
> +    PFNGLUNIFORMMATRIX4FVPROC   UniformMatrix4fv;
> +    PFNGLUNIFORM4FVPROC         Uniform4fv;
> +    PFNGLUNIFORM4FPROC          Uniform4f;
> +    PFNGLUNIFORM1IPROC          Uniform1i;
> 
>      /* Shader command */
>      PFNGLCREATESHADERPROC CreateShader;
> @@ -222,11 +225,12 @@ static void BuildVertexShader(vout_display_opengl_t
> *vgl, "varying vec4 TexCoord0,TexCoord1, TexCoord2;"
>          "attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
>          "attribute vec4 VertexPosition;"
> +        "uniform mat4 RotationMatrix;"
>          "void main() {"
>          " TexCoord0 = MultiTexCoord0;"
>          " TexCoord1 = MultiTexCoord1;"
>          " TexCoord2 = MultiTexCoord2;"
> -        " gl_Position = VertexPosition;"
> +        " gl_Position = vec4(RotationMatrix * VertexPosition);"
>          "}";
> 
>      *shader = vgl->CreateShader(GL_VERTEX_SHADER);
> @@ -432,6 +436,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, vgl->GetAttribLocation  =
> glGetAttribLocation;
>      vgl->VertexAttribPointer= glVertexAttribPointer;
>      vgl->EnableVertexAttribArray = glEnableVertexAttribArray;
> +    vgl->UniformMatrix4fv = glUniformMatrix4fv;
>      vgl->Uniform4fv    = glUniform4fv;
>      vgl->Uniform4f     = glUniform4f;
>      vgl->Uniform1i     = glUniform1i;
> @@ -458,6 +463,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, vgl->GetAttribLocation  =
> (PFNGLGETATTRIBLOCATIONPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glGetAttribLocation"); vgl->VertexAttribPointer=
> (PFNGLVERTEXATTRIBPOINTERPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glVertexAttribPointer"); vgl->EnableVertexAttribArray =
> (PFNGLENABLEVERTEXATTRIBARRAYPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glEnableVertexAttribArray"); +    vgl->UniformMatrix4fv   =
> (PFNGLUNIFORMMATRIX4FVPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniformMatrix4f
> v"); vgl->Uniform4fv    =
> (PFNGLUNIFORM4FVPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform4fv");
> vgl->Uniform4f     =
> (PFNGLUNIFORM4FPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform4f");
> vgl->Uniform1i     =
> (PFNGLUNIFORM1IPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform1i"); @@ -947,6
> +953,65 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
> return VLC_SUCCESS;
>  }
> 
> +static const float identity[] = {
> +    1.0f, 0.0f, 0.0f, 0.0f,
> +    0.0f, 1.0f, 0.0f, 0.0f,
> +    0.0f, 0.0f, 1.0f, 0.0f,
> +    0.0f, 0.0f, 0.0f, 1.0f
> +};
> +
> +static void orientationTransformMatrix(float matrix[static 16],
> video_orientation_t orientation) { +
> +    memcpy(matrix, identity, sizeof(identity));
> +
> +    float angle = 0.0;
> +    bool rotate = false;
> +
> +    switch (orientation) {
> +
> +        case ORIENT_ROTATED_90:
> +            angle = M_PI_2;
> +            rotate = true;
> +            break;
> +        case ORIENT_ROTATED_180:
> +            angle = M_PI;
> +            rotate = true;
> +            break;
> +        case ORIENT_ROTATED_270:
> +            angle = -M_PI_2;
> +            rotate = true;
> +            break;
> +        case ORIENT_HFLIPPED:
> +            matrix[0 * 4 + 0] = -1;
> +            break;
> +        case ORIENT_VFLIPPED:
> +            matrix[1 * 4 + 1] = -1;
> +            break;
> +        case ORIENT_TRANSPOSED:
> +            matrix[0 * 4 + 0] = 0;
> +            matrix[0 * 4 + 1] = -1;
> +            matrix[1 * 4 + 0] = -1;
> +            matrix[1 * 4 + 1] = 0;
> +            break;
> +        case ORIENT_ANTI_TRANSPOSED:
> +            matrix[0 * 4 + 0] = 0;
> +            matrix[0 * 4 + 1] = 1;
> +            matrix[1 * 4 + 0] = 1;
> +            matrix[1 * 4 + 1] = 0;
> +            break;
> +        default:
> +            break;
> +    }

Zeroing the matrix and filling the two +/-1 in each case would be simpler and 
more efficient. Most probably.

> +
> +    if(rotate) {
> +
> +        matrix[0 * 4 + 0] = cosf(angle);
> +        matrix[0 * 4 + 1] = -sinf(angle);
> +        matrix[1 * 4 + 0] = sinf(angle);
> +        matrix[1 * 4 + 1] = cosf(angle);
> +    }

Trigonometric functions seem way overkill for rectangular angles (and 
otherwise, I think -lm would be missing).

> +}
> +
>  #ifdef SUPPORTS_FIXED_PIPELINE
>  static void DrawWithoutShaders(vout_display_opengl_t *vgl,
>                                 float *left, float *top, float *right, float
> *bottom) @@ -965,6 +1030,13 @@ static void
> DrawWithoutShaders(vout_display_opengl_t *vgl, right[0], top[0]
>      };
> 
> +    float transformMatrix[16];
> +    orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
> +
> +    glPushMatrix();
> +    glMatrixMode(GL_MODELVIEW);
> +    glLoadMatrixf(transformMatrix);
> +
>      glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
>      glEnable(vgl->tex_target);
>      glActiveTexture(GL_TEXTURE0 + 0);
> @@ -983,6 +1055,9 @@ static void DrawWithoutShaders(vout_display_opengl_t
> *vgl, glDisableClientState(GL_TEXTURE_COORD_ARRAY);
>      glDisableClientState(GL_VERTEX_ARRAY);
>      glDisable(vgl->tex_target);
> +
> +    glPopMatrix();
> +
>  }
>  #endif
> 
> @@ -1035,6 +1110,11 @@ static void DrawWithShaders(vout_display_opengl_t
> *vgl,
> vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program],
> "VertexPosition"));
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program],
> "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
> 
> +    float transformMatrix[16];
> +    orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
> +   
> vgl->EnableVertexAttribArray(vgl->GetUniformLocation(vgl->program[program],
> "RotationMatrix")); +   
> vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program],
> "RotationMatrix"), 1, GL_FALSE, transformMatrix); +
>      glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
>  }
>  #endif
> @@ -1138,6 +1218,9 @@ int vout_display_opengl_Display(vout_display_opengl_t
> *vgl, vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1],
> "MultiTexCoord0"), 2, GL_FLOAT, 0, 0, textureCoord);
> vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1],
> "VertexPosition"));
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1],
> "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord); +           
> //Subpictures have the correct orientation:
> +           
> vgl->EnableVertexAttribArray(vgl->GetUniformLocation(vgl->program[1],
> "RotationMatrix")); +           
> vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[1],
> "RotationMatrix"), 1, GL_FALSE, identity); #endif
>          } else {
>  #ifdef SUPPORTS_FIXED_PIPELINE

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list