Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Problems with reading data from FBO to MainMemory

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2005
    Location
    China
    Posts
    11

    Problems with reading data from FBO to MainMemory

    Hi.
    Recently i used GPU to accelerate scientific computing.firstly i wanted to try a simple

    test: computing the summation of 4 floating matrices(texSize*texSize).
    i create 4 floating textures to represent 4 matrices. i attach them to a squre when i draw

    the square in FBO. the summation is implemented in glsl fragment program. and after

    drawing,i use glReadPixels(...) read the computing result from FBO to MainMemory.But the

    values in the MainMemory are all zeros. So would you like to help me?

    to simplify, i used GLEW libs and glsl class written by Martin Christen.

    And the following is the main code:
    Code :
    // GLSLProgram.cpp  
    //
     
    #include "stdafx.h"
    #include "glsl.h"
    #include <gl\wglew.h>
    #include <gl\glut.h> 
    #include <cassert>
     
    using namespace glsl;
    using namespace std;
     
    GLuint fboID;
    GLuint texID;
    GLuint depID;
     
    #define texWidth  256
    #define texHeight 256 
     
    // 4 matrices
    GLuint  inputTexID[4];
    GLfloat texture1[texHeight][texWidth];
    GLfloat texture2[texHeight][texWidth];
    GLfloat texture3[texHeight][texWidth];
    GLfloat texture4[texHeight][texWidth];
     
     
    // for storing the result
    GLfloat result[texHeight][texWidth];
     
     
    glShaderManager SM;
    glShader *shader = NULL;
     
     
    void CheckFramebufferStatus()
    {
    	GLenum status;
    	status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    	switch(status) {
    		case GL_FRAMEBUFFER_COMPLETE_EXT:
    			break;
    		case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
    			printf("Unsupported framebuffer format\n");
    			break;
    		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
    			printf("Framebuffer incomplete, missing attachment\n");
    			break;		 
    		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
    			printf("Framebuffer incomplete, attached images must have same dimensions\n");
    			break;
    		case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
    			printf("Framebuffer incomplete, attached images must have same format\n");
    			break;
    		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
    			printf("Framebuffer incomplete, missing draw buffer\n");
    			break;
    		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
    			printf("Framebuffer incomplete, missing read buffer\n");
    			break;
    		default:
    			assert(0);
    	}
    }
     
     
     
     
    void InitOpengl()
    {
    	glEnable(GL_DEPTH_TEST);
    	glClearColor(0.2,0.2,0.2,1.0);
    	glClearDepth(1.0f);   
     
    	glGenFramebuffersEXT(1,&amp;fboID);
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboID);
     
        //texID is attached to COLOR_ATTACHMENT0  
    	glGenTextures(1,&amp;texID);
    	glBindTexture(GL_TEXTURE_RECTANGLE_NV,texID);
    	glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,NULL);
    	glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    	glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_NV,texID,0);
    	glBindTexture(GL_TEXTURE_RECTANGLE_NV,0);
     
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
     
    }
     
     
     
    void CreatFloatTexture()
    {
    	glDeleteTextures(4,inputTexID);
     
    	glGenTextures(4,inputTexID);
     
     
    	//matrices initialization
    	for (int i = 0; i < texHeight; i ++)
    	{
    		for (int j = 0; j < texWidth; j ++)
    		{
    			texture1[i][j] = 1.1111;
    			texture2[i][j] = 2.2222;
    			texture3[i][j] = 3.3333;
    			texture4[i][j] = 4.4444;
    		}
    	}
     
    	for (int i = 0; i < 4;i ++)
    	{
    		glBindTexture(GL_TEXTURE_RECTANGLE_NV,inputTexID[i]);
    		if(i == 0)
    			glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&amp;texture1[0][0]);
    		else if( i == 1)
    			glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&amp;texture2[0][0]);
    		else if( i == 2)
    			glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&amp;texture3[0][0]);
    		else 
    			glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&amp;texture4[0][0]);
     
    		glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    		glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    		glBindTexture(GL_TEXTURE_RECTANGLE_NV,0);
    	}
     
     
    }
     
     
    void cleanup()
    {	
    	SM.free(shader);
    	glDeleteTextures(4,inputTexID);
    	glDeleteTextures(1, &amp;texID);
    	glDeleteFramebuffersEXT(1, &amp;fboID);
    }
     
     
    void display()
    {
    	 glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
    	 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
    	{		 
    		glPushAttrib(GL_VIEWPORT_BIT); 
    		glViewport(0, 0, texWidth, texHeight);
     
    		glMatrixMode(GL_PROJECTION);
    		glPushMatrix();
    		glLoadIdentity();
    		gluOrtho2D(0,texWidth,0,texHeight);  
     
     
    		glMatrixMode(GL_MODELVIEW);
    		glPushMatrix();
    		glLoadIdentity();	
     
    		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
     
    		shader->begin();
     
    		for(int i = 0; i < 4; i ++)
    		{
     
    			glActiveTexture(GL_TEXTURE0 + i);
    			glEnable(GL_TEXTURE_RECTANGLE_NV);
    			glBindTexture(GL_TEXTURE_RECTANGLE_NV,inputTexID[i]);
    			if(i == 0)
                    shader->setUniform1i("texture1",i);
    			else if(i == 1)
    				shader->setUniform1i("texture2",i);
    			else if(i == 2)
    				shader->setUniform1i("texture3",i);
    			else if(i == 3)
    				shader->setUniform1i("texture4",i);
    		}
     
    		glBegin(GL_QUADS);
    		{
    			glMultiTexCoord2i(GL_TEXTURE0, 0, 0);                 
    			glVertex2i(0,0);
    			glMultiTexCoord2i(GL_TEXTURE0,texWidth, 0);                   
    			glVertex2i(texWidth, 0);          
    			glMultiTexCoord2i(GL_TEXTURE0,texWidth,texHeight);          
    			glVertex2i(texWidth,texHeight);  
    			glMultiTexCoord2i(GL_TEXTURE0,0, texHeight);                  
    			glVertex2i(0,texHeight); 
    		}
    		glEnd();  
     
    		shader->end();
     
    		glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    		glReadPixels(0,0,texWidth,texHeight,GL_RGBA32F_ARB,GL_FLOAT,&amp;result[0][0]);
     
    		glPopMatrix();
    		glPopMatrix();
     
    		glPopAttrib();
     
     
    	}
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
     
    	glutSwapBuffers();
    }
     
    void resize(int w, int h)
    {
    	if (h == 0) h = 1;
     
    	glViewport(0, 0, w, h);
     
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
     
    	gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.1, 1000.0);
     
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
     
    }
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	glutInit(&amp;argc, argv);
    	glutInitWindowSize(512, 512);
    	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
    	glutCreateWindow("FBO & GLSL");
     
     
    	GLenum err = glewInit();
    	if(GLEW_OK != err)
    		std::cout << std::endl << "failed to initialize GLEW!" << std::endl;
     
    	InitOpengl();
     
    	CreatFloatTexture();
     
    	shader = SM.loadfromFile("sum.vert","sum.frag");
    	if (shader==0) 
    		cout << "Error Loading, compiling or linking shader\n";
     
    	glutDisplayFunc(display);
    	glutReshapeFunc(resize);
    	glutMainLoop();	 
     
    	return 0;
    }
    vertex program:
    Code :
     
    void main(void)
    {
       gl_TexCoord[0] = gl_MultiTexCoord0;
       gl_Position = ftransform();
    }
    fragment program:
    Code :
     uniform sampler2D texture1,texture2,texture3,texture4;
     
    void main(void)
    {
         vec4 tex1 = texture2D( texture1, gl_TexCoord[0].st);
        vec4 tex2 = texture2D( texture2, gl_TexCoord[0].st);
       vec4 tex3 = texture2D( texture3, gl_TexCoord[0].st);
        vec4 tex4 = texture2D( texture4, gl_TexCoord[0].st);      
     
        vec4 tex = tex1 + tex2 + tex3 + tex4;        
     
        gl_FragColor = vec4(tex.xyzw);
     }
    thank you

  2. #2
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,527

    Re: Problems with reading data from FBO to MainMemory

    Your glReadPixels format parameter is wrong.
    It should throw an GL_INVALID_ENUM error.
    Use GL_RGBA instead of GL_RGBA32F there.

    Add glGetError calls for debugging for such cases.

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2005
    Location
    China
    Posts
    11

    Re: Problems with reading data from FBO to MainMemory

    thanks to relic.
    i had corrected some mistakes but it still doesn't work. i found if i close fbo i could get right results except alpha component which is 1.0. so i think there maybe something wrong with FBO.

  4. #4
    Junior Member Regular Contributor
    Join Date
    Oct 2002
    Location
    San Diego, CA, USA
    Posts
    211

    Re: Problems with reading data from FBO to MainMemory

    I think for you to get alpha, you might have to turn on blending.

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2005
    Location
    China
    Posts
    11

    Re: Problems with reading data from FBO to MainMemory

    thank you all.
    it can work now ^_^

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •