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:
// 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
");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
printf("Framebuffer incomplete, missing attachment
");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
printf("Framebuffer incomplete, attached images must have same dimensions
");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
printf("Framebuffer incomplete, attached images must have same format
");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
printf("Framebuffer incomplete, missing draw buffer
");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
printf("Framebuffer incomplete, missing read buffer
");
break;
default:
assert(0);
}
}
void InitOpengl()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.2,0.2,0.2,1.0);
glClearDepth(1.0f);
glGenFramebuffersEXT(1,&fboID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboID);
//texID is attached to COLOR_ATTACHMENT0
glGenTextures(1,&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,&texture1[0][0]);
else if( i == 1)
glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&texture2[0][0]);
else if( i == 2)
glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&texture3[0][0]);
else
glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_RGBA32F_ARB,texWidth,texHeight,0,GL_RGBA,GL_FLOAT,&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, &texID);
glDeleteFramebuffersEXT(1, &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,&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(&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
";
glutDisplayFunc(display);
glutReshapeFunc(resize);
glutMainLoop();
return 0;
}
vertex program:
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
fragment program:
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