J'essaie actuellement de mettre en œuvre des algorithmes de traitement d'image OpenGL.Traitement d'image sur les shaders successifs GPU pour les filtres - FBO
Je souhaiterais utiliser successivement plusieurs shaders pour réaliser plusieurs filtres (Sobel Gaussian, ...). J'ai compris que pour cela je devais rendre à la texture grâce à un FBO. J'ai lu beaucoup de choses à ce sujet et j'ai écrit un code. Mais je n'obtiens pas le résultat que je m'attendais.
Pour l'instant, j'essaie juste d'utiliser deux shaders. J'ai donc une image originale qui est l'entrée de mon premier shader. Ensuite, je veux rendre la sortie du shader à une texture qui sera alors l'entrée de mon second shader (technique de ping-pong). Et enfin, je veux afficher la sortie du second shader. Mais en conséquence, je reçois l'image originale.
Mon code est le suivant:
/******************** Shaders Function *******************************/
void setupShaders(char *vert, char *frag, GLuint p) {
GLuint v, f;
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead(vert);
fs = textFileRead(frag);
const char * ff = fs;
const char * vv = vs;
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glLinkProgram(p);
glUseProgram(p);
}
/******************** Texture Function ***********************************/
void setupTexture(void) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
/******************** Quad Drawing Function ******************************/
void ShaderDraw(void){
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, height, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(width, height, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(width, height, 0.0);
glEnd();
}
/******************** Initialization Function ***************************/
void init(void)
{
//Checking GLSL
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
exit(1);
}
// Init
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
}
/******************** Display Function **********************************/
void display(void)
{
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-4.0, -4.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-4.0, 4.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(4.0, 4.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(4.0, -4.0, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
/******************** Reshape Function *********************************/
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -7.0);
}
/******************** Main Function *************************************/
int main(int argc, char** argv)
{
// Glut Initialisation
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
// Window Generation
glutInitWindowSize(1000,800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Night Vision");
// Initialisation Function
init();
// Downloading Image
data = cLoadBitmap("lena.bmp", &height, &width);
checkGLErrors ("Downloading Image");
int read_tex = 0;
int write_tex = 1;
// Generating Texture
glEnable(GL_TEXTURE_2D);
glGenTextures(2, texImg);
// Init Texture0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
checkGLErrors ("InitTexture0");
// Init Texture1
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkGLErrors ("InitTexture1");
// Setup Framebuffer Object
GLuint fb;
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
checkGLErrors ("Framebuffer->fb");
GLenum att_point[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[read_tex], GL_TEXTURE_2D, texImg[read_tex], 0);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[write_tex], GL_TEXTURE_2D, texImg[write_tex], 0);
checkFramebufferStatus();
//set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shader
setupShaders("filter.vert", "sobel_filter_3.frag", p1);
checkGLErrors ("Shaders 1");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
GLuint texLoc;
texLoc = glGetUniformLocation(p1,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// swap the buffers
read_tex = 1;
write_tex = 0;
// Delete program 1
glDeleteProgram(p1);
// set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shaders
setupShaders("filter.vert", "gaussian7.frag", p2);
checkGLErrors ("Shaders 2");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
texLoc = glGetUniformLocation(p2,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// Delete program 2 & disable the FBO
glDeleteProgram(p2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glUseProgram(0);
// Bind the texture to display
glBindTexture(GL_TEXTURE_2D,texImg[0]);
// Glut Functions: Display, Reshape, Keyboard
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
// Calling Main
glutMainLoop();
return 0;
}
ce que quelqu'un a une idée de ce qui ne va pas ???
salut zenna je suis utilisateur de openFrameworks et je suis en train de réaliser quelque chose de vraiment la même chose que vous. un simple shader ping-pong enchaînant à l'intérieur d'un fbo. avez-vous résolu ce problème? pourriez-vous me signaler une solution? pourrait vous écrire un courriel à eloi {at} telenoika [dot] net s'il vous plaît ... je ne sais pas comment faire un PM à votre message ... merci beaucoup! –
Avez-vous entendu parler d'OpenCL et de CUDA? Je pense que c'est l'état de l'art pour effectuer ces opérations d'une manière maintenable – fabrizioM