[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