PBuffer not working

I want to create a pbuffer to render something into it and use it as a texture for a quad but all I get is a black quad.

I create the pbuffer with 512x512 size

  
			int [] iCPAttribs	= {
									  Tao.Platform.Windows.Wgl.WGL_DRAW_TO_PBUFFER_ARB, Gl.GL_TRUE,
									  Tao.Platform.Windows.Wgl.WGL_DEPTH_BITS_ARB, 24,
									  Tao.Platform.Windows.Wgl.WGL_COLOR_BITS_ARB, 32,
									  Tao.Platform.Windows.Wgl.WGL_ALPHA_BITS_ARB, 8,
									  //Tao.Platform.Windows.Wgl.WGL_STENCIL_BITS_ARB, this.StencilBits,
									  Tao.Platform.Windows.Wgl.WGL_RED_BITS_ARB, 8,
									  Tao.Platform.Windows.Wgl.WGL_GREEN_BITS_ARB, 8,
									  Tao.Platform.Windows.Wgl.WGL_BLUE_BITS_ARB, 8,
									  Tao.Platform.Windows.Wgl.WGL_SUPPORT_OPENGL_ARB, 1, //necessary for non nvidia hardware
									  Tao.Platform.Windows.Wgl.WGL_BIND_TO_TEXTURE_RGB_ARB, Gl.GL_TRUE,
									  0
								  };

			float [] fvAttribs = {0.0f};
			int [] iPBAttribs = {
									Wgl.WGL_PBUFFER_LARGEST_ARB, 1,
									Wgl.WGL_TEXTURE_FORMAT_ARB, Wgl.WGL_TEXTURE_RGB_ARB,
									Wgl.WGL_TEXTURE_TARGET_ARB, Wgl.WGL_TEXTURE_2D_ARB,
									0
								};
			int iErr = 0;
			//obtain dc for this glrc
			System.IntPtr hdc = Tao.Platform.Windows.Wgl.wglGetCurrentDC();
			if(hdc.Equals(System.IntPtr.Zero))
				return (-1);

			//until now no non-power-of-2 textures
			if((iErr = CBHelp.sPBuffer.createPBuffer(out this.pBuffer, hdc, iCPAttribs, fvAttribs, 512, 512, iPBAttribs)) != 0)
				return (iErr);

			if((this.pWglBindTexImageARB = Wgl.wglGetProcAddress(CBHelp.CGLHelper.WGL_BIND_TEX_IMAGE_ARB)) == System.IntPtr.Zero)
				return (-3);

			if((this.pWglReleaseTexImageARB = Wgl.wglGetProcAddress(CBHelp.CGLHelper.WGL_RELEASE_TEX_IMAGE_ARB)) == System.IntPtr.Zero)
				return (-4);

			return (Gl.glGetError());
		}

where createPBuffer does all the necessary calls to wglChoosePixelFormat, create the pbuffer, get a dc and create a rc for it. this function returns a valid “pbuffer”.

I set up a texture object

			Gl.glGenTextures(1, out this.iPBufferTexture);
			Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.iPBufferTexture);
			//Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE);
			Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
			Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
			Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP/*_TO_EDGE*/);
			Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP/*_TO_EDGE*/);  

I did glEnable(GL_TEXTURE_2D)

my main rendering loop looks like this

			this.renderSceneToPBuffer();

			Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT | Gl.GL_COLOR_BUFFER_BIT);
			Gl.glLoadIdentity();

			Glu.gluLookAt(0, 15, 25,  0,0,0,  0,1,0);

			CBHelp.CGLHelper.ShowGrid();

			//bind texture
			Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.iPBufferTexture);
			Wgl.wglBindTexImageARB(this.pWglBindTexImageARB, this.pBuffer.PBuffer, Wgl.WGL_FRONT_LEFT_ARB);

			Gl.glColor3f(1.0f, 1.0f, 1.0f);
			Gl.glBegin(Gl.GL_QUADS);
				Gl.glTexCoord2f(0.0f, 0.0f);
				Gl.glVertex2f(-10.0f , -10.0f);
	    
				Gl.glTexCoord2f(1.0f, 0.0f);
				Gl.glVertex2f( 10.0f, -10.0f);

				Gl.glTexCoord2f(1.0f, 1.0f);
				Gl.glVertex2f(10.0f, 10.0f);

				Gl.glTexCoord2f(0.0f, 1.0f);
				Gl.glVertex2f(-10.0f, 10.0f);
			Gl.glEnd();

			//release to render next frame
			Wgl.wglReleaseTexImageARB(this.pWglReleaseTexImageARB, this.pBuffer.PBuffer, Wgl.WGL_FRONT_LEFT_ARB);

where show grid simply shows the main coordinate axes and renderSceneToPBuffer looks as follows

			if(Wgl.wglMakeCurrent(this.pBuffer.HDC, this.pBuffer.HRC) == false)
				System.Console.WriteLine("failed to make pbuffer current");

			Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT | Gl.GL_COLOR_BUFFER_BIT);
			Gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f);

			Gl.glLoadIdentity();
			Glu.gluLookAt(0, 15, 15,  0, 0, 0,  0, 1, 0);
			Gl.glRotatef(this.fRotY, 0.0f, 1.0f, 0.0f);

			Gl.glColor3f(1.0f, 1.0f, 1.0f);
			Gl.glBegin(Gl.GL_TRIANGLES);
				Gl.glVertex3f(-10.0f,  0.0f, 0.0f);
				Gl.glVertex3f( 10.0f,  0.0f, 0.0f);
				Gl.glVertex3f(  0.0f, 10.0f, 0.0f);
			Gl.glEnd();

			Gl.glFlush();
			Wgl.wglMakeCurrent(this.hDC, this.HGLRC);

So as you can see I want to render a triangle with white color into the pbuffer and use this as a texture for the quad in the main loop.

But as I have said there is only a black quad.

I have no clue why. Could someone please help and point me to my misunderstanding.

I used the articly on pBuffers from the Nvidia Site so please don’t tell me that I should look there.

thanks in advance

  1. put glGetError() everywhere and check it.
  2. on my web page I have some working C source code on pbuffers. Code is ugly but works.

I looked at your code and there seems to be no big difference.

I tried to call glViewPort like this

wglMakeCurrent(pBuffer.HDC, pBuffer.HRC);
glViewport(0, 0, pBuffer.Width, pBuffer.Height);
wglMakeCurrent(HDC, hGLRC);

but glGetError() says that glViewport is an invalid operation at this position.

I checked for other calls and it looks like I can’t
issue any opengl call after I make the pbuffers context the current one.
Because than OpenGL says invalid operation

I tried to find the position in my code that produces the error and ended in the function where my pBuffer gets created. But the error don’t occur
everytime.

it seems that this line causes the trouble

			if((ext = Tao.Platform.Windows.Wgl.wglGetProcAddress(CBHelp.CGLHelper.WGL_GET_PBUFFER_DC_ARB)) == System.IntPtr.Zero)
				return (CBHelp.CGLHelper.ERR_GET_ADDR_WGL_GET_PBUFFER_DC_ARB);

			if((iLastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error()) != 0)
			{
				System.Console.WriteLine("iLE "+iLastError);
				return (iLastError);
			}
			//System.Console.WriteLine("iLEa "+iLastError);

			//get pbuffers dc
			if((pb.pHDC = Tao.Platform.Windows.Wgl.wglGetPbufferDCARB(ext, pb.pPBuffer)) == IntPtr.Zero)
				return (CBHelp.CGLHelper.ERR_WGL_GET_PBUFFER_DC_ARB);

			if((iLastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error()) != 0)
			{
				System.Console.WriteLine("iLE "+iLastError);
				return (iLastError);
			}
			System.Console.WriteLine("iLEa "+iLastError);

the error says that it is an invalid handle and what is quite interesting is that the error only pops up if I leave the last WriteLine in, if I comment it out nothing happens - no error

I was finally able to do (huh after 2 days) and will wrap these damn functions