how to manage multiple pbuffers correctly?

Hi,every one here,
I am really confused with the usage of multiple pbuffer. When I use them to render to texture with Fragment Program, also with multiple texture units, I can not get the correct result.
How to manage the OpenGL states correctly with pbuffers?
Would some one here like to provide a example or a link?

Thanks in advance.

Kind of vague isn’t it?

Each p-buffer has it’s own context and all states are default as usual until you change them.

Each p-buffer has it’s own context and all states are default as usual until you change them

Yes. But I am really confused with it when I use multiple textures units with Fragment program.
For example, I render something to one texture with one pbuffer which I have set to share texture objects. And when I use this result texture in another pbuffer or in the same pbuffer, there are problems. This texture has been cleared to zero.

Hope to find a clear outway. Thanks a lot.

Lefohn had mentioned in his turtorial Dynamic Volume Computation and Visualization
On the GPU. But he didnot provide the technical details what I really need.
Does he come here?

If this thread is related to the other thread, I didn’t respond because it’s not clear what you are doing.

That said, there are things the spec isn’t clear about … but that’a another matter.

#1 Make sure wglShareList is returning TRUE
for both p-buffers.

The calls should be like this

wglShareLists(GLRC_PBuffer1, GLRC_MainWindow);
wglShareLists(GLRC_PBuffer2, GLRC_MainWindow);

You could try
wglShareLists(GLRC_PBuffer1, GLRC_MainWindow);
wglShareLists(GLRC_PBuffer2, GLRC_PBuffer1);

but I wouldn’t

#2 Which GLRC is current when you are calling the gl functions?

#3 It’s probably not a good idea to create a self-dependency if that is what you are doing.
If the p-buffer is a RTT and this RTT is created in GLRC_MainWindow and at the same time wglShareLists is used on these.

#4 I don’t know what happens if you use 2 tex ID with 1 p-buffer : releasing the p-buffer binding to another tex object, then released, binding to another.

– Try to remain on the safe side –

Thanks for your kindness. But the problem is still there.


#1 Make sure wglShareList is returning TRUE
for both p-buffers.

Yes, there is no problem about this.


wglShareLists(GLRC_PBuffer1, GLRC_MainWindow);
wglShareLists(GLRC_PBuffer2, GLRC_MainWindow);
You could try
wglShareLists(GLRC_PBuffer1, GLRC_MainWindow);
wglShareLists(GLRC_PBuffer2, GLRC_PBuffer1);

I tyied both of them, not work


#2 Which GLRC is current when you are calling the gl functions?

Yes, I have to make it current, otherwise errors occur.

#3 It’s probably not a good idea to create a self-dependency if that is what you are doing.
If the p-buffer is a RTT and this RTT is created in GLRC_MainWindow and at the same time wglShareLists is used on these.

#4 I don’t know what happens if you use 2 tex ID with 1 p-buffer : releasing the p-buffer binding to another tex object, then released, binding to another.

– Try to remain on the safe side --[/b][/QUOTE]

Here I provide an example to illustrate my prblem, and hope to have a discussion here. Thanks for joining.

#include “pbuffer.h”
int Width = 16;
int Height = 16;
unsigned int ShaderID1;
unsigned int ShaderID2;
unsigned int tex0_id;
unsigned int tex1_id;
void testtwopbuffer()
{
int i;
///////////////////////////////////////////////////////
///// Bind the Fragment Program to current drawing
LoadFragmentProgramFromFile(“…\ est1.fp”, ShaderID1);
LoadFragmentProgramFromFile(“…\ est2.fp”, ShaderID2);

///Setup two pbuffers, and the class CFloatPBuffer from RTT of Harris
CFloatPBuffer* pbuffer[2];
for(i=0;i<2;i++)
{
pbuffer[i] = new CFloatPBuffer(Width, Height);
///Here I have set to share resource contexts
pbuffer[i]->Initialize();
pbuffer[i]->BeginCapture();

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	

  glViewport(0,0,Width,Height);
  glMatrixMode ( GL_PROJECTION );
  glLoadIdentity();
  glOrtho( 0, Width, 0, Height, -1.0, 1.0 );
  glMatrixMode ( GL_MODELVIEW );
  glLoadIdentity();
  glEnable(GL_FRAGMENT_PROGRAM_NV);

  pbuffer[i]->EndCapture();

}

int whichone=0;

///Here I have to make one pbuffer current, so the texture data can be correctly used in the following program
pbuffer[whichone]->BeginCapture();
LoadData(tex0_id);
LoadData(tex1_id);
pbuffer[whichone]->EndCapture();
whichone++;
whichone = whichone%2;

char filename[20];

///Output the textures, the result is correct.
output(“…\ ex0-1.txt”, tex0_id);
output(“…\ ex1-1.txt”, tex1_id);

////Set the tex1_id as the target of RTT
for(i=0;i<3;i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex1_id);
pbuffer[whichone]->BeginCapture();
glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID1);

  glActiveTextureARB(GL_TEXTURE0_ARB);
  glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex0_id);

  /// The target can also be used as an input texture
  glActiveTextureARB(GL_TEXTURE1_ARB);
  glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex1_id);

  glBegin(GL_QUADS);
  	glVertex2i(0,0);
  	glVertex2i(Width,0);
  	glVertex2i(Width,Height);
  	glVertex2i(0,Height);
  glEnd();

  glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex1_id);
  pbuffer[whichone]->EndCapture();
  
  ////In order to get correct result, two pbuffers must be used and swapped in turn.		
  whichone++;
  whichone = whichone%2;

}

///output to have check, no problems here!
output(“…\ ex0-2.txt”, tex0_id);
output(“…\ ex1-2.txt”, tex1_id);

///Here is important to show my problem.
///If the target of RTT is same to the above one, NO errors.
///But if I change it to other textures, error occurs.
///That’s to say
///target = tex1_id, NO Wrong.
///target = tex0_id, no error to the first pass(i=0),
///but in the next pass, the texture data of tex1_id has been changed.
unsigned int target = tex0_id;
for(i=0;i<2;i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE_NV, target );
pbuffer[whichone]->BeginCapture();
glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID2);

  glActiveTextureARB(GL_TEXTURE0_ARB);
  glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex0_id);

  glActiveTextureARB(GL_TEXTURE1_ARB);
  glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex1_id);

  glBegin(GL_QUADS);
  	glVertex2i(0,0);
  	glVertex2i(Width,0);
  	glVertex2i(Width,Height);
  	glVertex2i(0,Height);
  glEnd();

  ///Here will be changed accordingly.
  glBindTexture(GL_TEXTURE_RECTANGLE_NV, target );
  pbuffer[whichone]->EndCapture();
  
  //// TO check the immediate texture data
  sprintf(filename,"..\	ex0----%d.txt", i);
  output(filename, tex0_id);
  ///Here if target = tex0_id, the data of tex1_id is changed arbitrarily(i>0)
  sprintf(filename,"..\	ex1----%d.txt", i);
  output(filename, tex1_id);

  whichone++;
  whichone = whichone%2;

}
}

Thanks for any idea.

You have to be careful which context is current when you are calling gl functions like in this case.

///////////////
for(i=0;i<2;i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE_NV, target );
pbuffer[whichone]->BeginCapture();
///////////////

I don’t know what BeginCapture and EndCapture does.

If BeginCapture is
wglReleaseTexImageARB(HDC_PBUFFER, WGL_FRONT_LEFT_ARB);
wglMakeCurrent(HDC_PBUFFER, GLRC_PBUFFER);

and EndCapture
wglBindTexImageARB(HDC_PBUFFER, GL_FRONT_LEFT_ARB);

then it should be fine. But before you call EndCapture, be sure to have the right context current (probably the main window)

//////////////////////Warning!
glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex1_id);
pbuffer[whichone]->EndCapture();
//////////////////////

maybe you should make something downloadable. I’ll have a look when I have time.

[This message has been edited by V-man (edited 02-17-2004).]

[This message has been edited by V-man (edited 02-17-2004).]