[vlc-commits] Make opengl.c handle movie rotations.
Matthias Keiser
git at videolan.org
Mon Mar 24 17:53:32 CET 2014
vlc | branch: master | Matthias Keiser <matthias at tristan-inc.com> | Tue Mar 18 22:53:27 2014 +0100| [54560cc8727a5b4ac84ee286c3bc5a0342272a5d] | committer: Felix Abecassis
Make opengl.c handle movie rotations.
Signed-off-by: Felix Abecassis <felix.abecassis at gmail.com>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=54560cc8727a5b4ac84ee286c3bc5a0342272a5d
---
modules/video_output/opengl.c | 102 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 97 insertions(+), 5 deletions(-)
diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index 33db19d..512429e 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -49,6 +49,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 +147,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;
@@ -221,12 +223,13 @@ static void BuildVertexShader(vout_display_opengl_t *vgl,
PRECISION
"varying vec4 TexCoord0,TexCoord1, TexCoord2;"
"attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
- "attribute vec4 VertexPosition;"
+ "attribute vec2 VertexPosition;"
+ "uniform mat4 RotationMatrix;"
"void main() {"
" TexCoord0 = MultiTexCoord0;"
" TexCoord1 = MultiTexCoord1;"
" TexCoord2 = MultiTexCoord2;"
- " gl_Position = VertexPosition;"
+ " gl_Position = RotationMatrix * vec4(VertexPosition, 0.0, 1.0);"
"}";
*shader = vgl->CreateShader(GL_VERTEX_SHADER);
@@ -432,6 +435,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 +462,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,"glUniformMatrix4fv");
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 +952,76 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
return VLC_SUCCESS;
}
+static const GLfloat 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(GLfloat matrix[static 16], video_orientation_t orientation) {
+
+ memcpy(matrix, identity, sizeof(identity));
+
+ const int k_cos_pi = -1;
+ const int k_cos_pi_2 = 0;
+ const int k_cos_n_pi_2 = 0;
+
+ const int k_sin_pi = 0;
+ const int k_sin_pi_2 = 1;
+ const int k_sin_n_pi_2 = -1;
+
+ bool rotate = false;
+ int cos = 0, sin = 0;
+
+ switch (orientation) {
+
+ case ORIENT_ROTATED_90:
+ cos = k_cos_pi_2;
+ sin = k_sin_pi_2;
+ rotate = true;
+ break;
+ case ORIENT_ROTATED_180:
+ cos = k_cos_pi;
+ sin = k_sin_pi;
+ rotate = true;
+ break;
+ case ORIENT_ROTATED_270:
+ cos = k_cos_n_pi_2;
+ sin = k_sin_n_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;
+ }
+
+ if (rotate) {
+
+ matrix[0 * 4 + 0] = cos;
+ matrix[0 * 4 + 1] = -sin;
+ matrix[1 * 4 + 0] = sin;
+ matrix[1 * 4 + 1] = cos;
+ }
+}
+
#ifdef SUPPORTS_FIXED_PIPELINE
static void DrawWithoutShaders(vout_display_opengl_t *vgl,
float *left, float *top, float *right, float *bottom)
@@ -965,6 +1040,13 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
right[0], top[0]
};
+ GLfloat 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 +1065,9 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(vgl->tex_target);
+
+ glPopMatrix();
+
}
#endif
@@ -1014,6 +1099,9 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
1.0, -1.0,
};
+ GLfloat transformMatrix[16];
+ orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
+
for (unsigned j = 0; j < vgl->chroma->plane_count; j++) {
const GLfloat textureCoord[] = {
left[j], top[j],
@@ -1035,6 +1123,8 @@ 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);
+ vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program], "RotationMatrix"), 1, GL_FALSE, transformMatrix);
+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
#endif
@@ -1138,6 +1228,8 @@ 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->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[1], "RotationMatrix"), 1, GL_FALSE, identity);
#endif
} else {
#ifdef SUPPORTS_FIXED_PIPELINE
More information about the vlc-commits
mailing list