Problems rendering to FP texture

Hi,

I have a PBuffer created with a pixel format chosen using the following attributes:

{
WGL_RED_BITS_ARB, 32,
WGL_GREEN_BITS_ARB, 32,
WGL_BLUE_BITS_ARB, 32,
WGL_ALPHA_BITS_ARB, 32,
WGL_STENCIL_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_FLOAT_COMPONENTS_NV, GL_TRUE,
WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV, GL_TRUE,
0,
};

and the following buffer attributes:

{
WGL_PBUFFER_LARGEST_ARB, TRUE,
WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_FLOAT_RGBA_NV,
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_RECTANGLE_NV,
0
};

and finally a texture object with the following parameters:

	glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

The problem is that when I try to render to it nothing shows up, the following code doesn’t seen to produce any results:

HDC previousDC = wglGetCurrentDC();
HGLRC previousRC = wglGetCurrentContext();
wglMakeCurrent(m_bufferDC, m_bufferRC);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);

glViewport(0, 0, m_width, m_height);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, m_width, 0.0f, m_height, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);

glBegin(GL_TRIANGLES);
{
glVertex2f(0.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);

glVertex2f(float(m_width) * 2.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);		

glVertex2f(0.0, float(m_height) * 2.0f);
glColor3f(0.0f, 0.0f, 1.0f);

}
glEnd();

glMatrixMode(GL_MODELVIEW);
glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();

wglMakeCurrent(previousDC, previousRC);

When I test the texture by drawing a rectangle in the middle of the viewport I only get a black rectangle:

glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_texture);	
glEnable(GL_TEXTURE_RECTANGLE_NV);

glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_program);
glEnable(GL_FRAGMENT_PROGRAM_ARB);	

wglBindTexImageARB(m_buffer, WGL_FRONT_LEFT_ARB);
glDisable(GL_BLEND);	

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(-float(m_width) * 0.5f, m_width * 1.5f, -float(m_height) * 0.5f, m_height * 1.5f, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();	

glBegin(GL_QUADS);	
{			
	glVertex2f(0.0f, 0.0f);
	glTexCoord2f(0.0f, 0.0f);
	
	glVertex2f(float(m_width), 0.0f);
	glTexCoord2f(float(m_width), 0.0f);		
	
	glVertex2f(float(m_width), float(m_height));
	glTexCoord2f(float(m_width), float(m_height));				
	
	glVertex2f(0.0f, float(m_height));
	glTexCoord2f(0.0f, float(m_height));		
}
glEnd();

glMatrixMode(GL_PROJECTION);
glPopMatrix();	

glMatrixMode(GL_MODELVIEW);	
glPopMatrix();	

wglReleaseTexImageARB(m_buffer, WGL_FRONT_LEFT_ARB);	

glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);	
glDisable(GL_TEXTURE_RECTANGLE_NV);	

glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);    
glEnable(GL_FRAGMENT_PROGRAM_ARB);    

The program looks like this:

!!ARBfp1.0
TEX result.color, fragment.texcoord[0], texture[0], RECT;
END

The actual FP texture seems to work because if I change the glClearColor the rendered rectangle also changes to the same value.

(All buffers, programs, texture handles etc. seems to be ok)

Any clues?

Regards

/A.B.

I also added:

glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);

in the test render code but nothing still shows up.

/A.B.

Hi Andreas, (is that the right spelling?)

Jeff Juliano suggested I check to see if your draw_buffer is GL_BACK, but you’re binding FRONT_LEFT to the texture. Also, you might try ReadPixels or CopyTexImage from the pbuffer to verify rendering to it.

Thanks -
Cass

Hi Cass,

yes, you got the spelling right :wink: I don’t think the problem is related to wglBindTexImageARB (though the white paper by Chris Wynn that I read seems to be lacking some information here, it says ‘Set <iBuffer> to WGL_FRONT_LEFT_ARB or WGL_BACK_LEFT_ARB depending upon which buffer was used for rendering the texture’. Where does one specify which buffer to use? Should I call wglSetPBufferAttribARB or something?).

I added a glReadPixels call and wrote the pixels to disk as a bmp. The image gets filled with the current clear color but my triangle doesn’t show up.

<update>

I also added drew some pixels:

std::vector<float> pixels(32 * 32 * 4, 1.0f);
glRasterPos2i(0, 0);
glDrawPixels(32, 32, GL_RGBA, GL_FLOAT, &pixels[0]);

and they also correctly shows up in my saved bmp. (And in my rendered rectangle, though I seem to have screwed up the texture coordinates for the x-axis)

</update>

Regards

/A.B.

You neeed to bind a fragment program (NV_fragment_program, ARB_fragment_program, or ARB_fragment_shader) when writing into a floating point pbuffer when using the NV_float_buffer extension. See the issues section of the NV_float_buffer extension for details.

Thanks, now the actual rendering to the texture works. What I’m now having problem with is blitting the buffer to my main rendering context.

The texture works, but I’m having problem with the texture coordinate (I’m aware of the different mapping on non square textures). The blitting code looks like this:

glBegin(GL_QUADS);	
{			
	glVertex2f(0.0f, 0.0f);
	glTexCoord2f(0.0f, 0.0f);
	
	glVertex2f(float(m_width), 0.0f);
	glTexCoord2f(float(m_width), 0.0f);
	
	glVertex2f(float(m_width), float(m_height));
	glTexCoord2f(float(m_width), float(m_height));
	
	glVertex2f(0.0f, float(m_height));
	glTexCoord2f(0.0f, float(m_height));
}
glEnd();

I see some of my texture but it’s sheared and stretched in a funny way. I also tried to blit it the same way as I used to do on the xbox:

glBegin(GL_TRIANGLES);	
{			
	glVertex2f(0.0f, 0.0f);
	glTexCoord2f(0.0f, 0.0f);
	
	glVertex2f(float(m_width) * 2.0f, 0.0f);
	glTexCoord2f(float(m_width) * 2.0f, 0.0f);
	
	glVertex2f(0.0f, float(m_height) * 2.0f);
	glTexCoord2f(0.0f, float(m_height) * 2.0f);
}
glEnd();

but it doesn’t work either. Clues? I also have the following code in my blitting routine:

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, m_width, 0.0f, m_height, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();	

glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();

(Of course with matching glPopMatrix())

Regards

A.B.

> The texture works, but I’m having problem with the texture coordinate

glBegin(GL_QUADS);
{
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);

– snip –

You use the wrong order of commands. You have to use glTexCoord first and then send the vertex. A texcoord defines an attribute of a vertex and has to be defined before glVertex is called. The call to glVertex takes all the current vertex attributes like texture coordinates, color etc. and associates them with that vertex. Order matters.

Michael

Doh!