I need to display YV12 video onto an OpenGL texture, and I have
found this fragment program that allegedly accomplishes this using
multitexturing (one texture for each input color plane, Y, U and V):
!!ARBfp1.0
ATTRIB position = fragment.texcoord[0];
TEMP R0, R1;
TEX R0, position, texture[0], 2D;
MAD R0, R0, 1.164, -0.073;
TEX R1.r, position, texture[1], 2D;
TEX R1.g, position, texture[2], 2D;
SUB R1.rg, R1, { 0.5, 0.5 };
MAD R0.rgb, { 0, -0.391, 2.018 }, R1.rrra, R0;
MAD R0.rgb, { 1.596, -0.813, 0 }, R1.ggga, R0;
MUL result.color, fragment.color, R0;
END
Unfortunately, I hardly know anything about OpenGL, so I have no
idea how to integrate this into my application. What I have now is
a method that handles RGB textures (minimalistic sample given below).
Is it easy to rewrite this so that it loads a picture in YV12
format, uploads the three color planes into three different
textures, runs the fragment program to generate a single RGB texture
based on the three Y,U,V textures, and display that?
A huge thank you to anyone who can help me with this!
//
/* Example program that needs to be rewritten to use the fragment shader. */
//
#include <stdio.h>
#include <unistd.h>
#include <SDL.h>
#include <SDL_opengl.h>
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
return 1;
SDL_Surface *screen = SDL_SetVideoMode(0,0,24,SDL_OPENGL|SDL_FULLSCREEN);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, screen->w, screen->h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 1, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
SDL_Surface *img = SDL_LoadBMP(argv[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, img->w, img->h, 0,
GL_BGR, GL_UNSIGNED_BYTE, img->pixels);
SDL_FreeSurface(img);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
{
glTexCoord2i(0, 0);
glVertex3f(0, 0, 0);
glTexCoord2i(1, 0);
glVertex3f(1, 0, 0);
glTexCoord2i(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2i(0, 1);
glVertex3f(0, 1, 0);
}
glEnd();
SDL_GL_SwapBuffers();
sleep(5);
glDeleteTextures(1, &texture);
SDL_Quit();
return 0;
}
/*****************************************************************************/–
Haakon