Trust me, it works with the GL_ARB_color_buffer_float extension extension. I’ve updated your code, there were a few errors in it like creating the shader as a local variable instead of assigning it to the global variable, forgetting to bind the texture to the shader and uncompilable shader code . Anyway, here it is:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <iostream>
using namespace std;
static int width = 800;
static int height = 600;
static GLuint shader;
static GLuint texid;
static GLuint pboid[8];
const char* vertSource = "void main() {
" \
" gl_Position = ftransform();
" \
" gl_TexCoord[0] = gl_MultiTexCoord0;
" \
"}
";
const char* fragSource = " uniform sampler2D tex;
" \
"void main() {
" \
" vec3 value = texture2D(tex,gl_TexCoord[0].st).rgb;
" \
" if ( value.x == 2.0 && value.y == 2.0 && value.z == 2.0 )
" \
" gl_FragColor = vec4(0.0,1.0,0.0,1.0);
" \
" else
" \
" gl_FragColor = vec4(1.0,0.0,0.0,1.0);
" \
"}
";
void
idle ()
{
glutPostRedisplay ();
}
void
display ()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glBindTexture(GL_TEXTURE_2D,texid);
glUseProgramObjectARB(shader);
GLint texloc1 = glGetUniformLocationARB(shader,"tex");
glUniform1iARB(texloc1,0);
glNormal3f(0.f,0.f,1.f);
glColor3f(1.f,1.f,1.f);
glBegin(GL_TRIANGLES);
glTexCoord2f(0.f,1.f); glVertex3f(-1.f,-1.f,-1.f);
glTexCoord2f(1.f,1.f); glVertex3f(1.f,-1.f,-1.f);
glTexCoord2f(0.f,0.f); glVertex3f(-1.f,1.f,-1.f);
glEnd();
glBegin(GL_TRIANGLES);
glTexCoord2f(1.f,1.f); glVertex3f(1.f,-1.f,-1.f);
glTexCoord2f(1.f,0.f); glVertex3f(1.f,1.f,-1.f);
glTexCoord2f(0.f,0.f); glVertex3f(-1.f,1.f,-1.f);
glEnd();
glUseProgramObjectARB(0);
glutSwapBuffers ();
}
void
initGL ()
{
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
cerr << "[PBO] Ready for OpenGL 2.0" << endl;
else {
cerr << "[PBO] OpenGL 2.0 not supported" << endl;
exit(1);
}
glCullFace( GL_BACK );
glEnable( GL_DEPTH_TEST );
glEnable( GL_CULL_FACE );
glEnable( GL_TEXTURE_2D );
glDisable( GL_LIGHTING );
}
void
initTextureAndShader ()
{
//glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB,GL_FALSE);
const int w = 256;
const int h = 256;
float* gputex = new float[3*w*h];
for ( int i = 0; i < 3*w*h; ++i )
gputex[i] = 2.f;
cerr << "Texture Init OK" << endl;
glGenTextures(1,&texid);
glBindTexture(GL_TEXTURE_2D,texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB16F_ARB,w,h,0,GL_RGB,GL_FLOAT,0);
cerr << "Texture Allocation OK" << endl;
// create PBO ...
glGenBuffers(1,pboid);
cerr << " PBO created ..." << endl;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pboid[0]);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, 3*w*h*sizeof(float), 0,
GL_STREAM_DRAW);
GLvoid* ptr1 = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
GLfloat* tmp = (GLfloat*) ptr1;
for ( int i = 0; i < 3*w*h; ++i )
tmp[i] = gputex[i];
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
glTexSubImage2D( GL_TEXTURE_2D,0,0,0,w,h,GL_RGB,GL_FLOAT,BUFFER_OFFSET(0));
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDeleteBuffers(1,pboid);
delete [] gputex;
cerr << "Texture PBO upload OK" << endl;
GLuint v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
GLuint f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
glShaderSourceARB(v, 1, &vertSource,NULL);
glShaderSourceARB(f, 1, &fragSource,NULL);
glCompileShaderARB(v);
glCompileShaderARB(f);
shader = glCreateProgramObjectARB();
glAttachObjectARB(shader,f);
glAttachObjectARB(shader,v);
glLinkProgramARB(shader);
cerr << "shader OK" << endl;
}
int
main ( int argc, char** argv )
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (width,height);
glutCreateWindow ("PBO");
glutIdleFunc (idle);
glutDisplayFunc (display);
initGL();
initTextureAndShader();
glutMainLoop ();
return EXIT_SUCCESS;
}
Just uncomment
//glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB,GL_FALSE);
to make it work.