PDA

View Full Version : how to manage multiple pbuffers correctly?



foollove
02-14-2004, 05:51 PM
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.

V-man
02-14-2004, 06:49 PM
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.

foollove
02-14-2004, 07:19 PM
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?

V-man
02-15-2004, 08:55 AM
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 --

foollove
02-15-2004, 09:22 PM
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("..\\test1.fp", ShaderID1);
LoadFragmentProgramFromFile("..\\test2.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("..\\tex0-1.txt", tex0_id);
output("..\\tex1-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("..\\tex0-2.txt", tex0_id);
output("..\\tex1-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,"..\\tex0----%d.txt", i);
output(filename, tex0_id);
///Here if target = tex0_id, the data of tex1_id is changed arbitrarily(i>0)
sprintf(filename,"..\\tex1----%d.txt", i);
output(filename, tex1_id);

whichone++;
whichone = whichone%2;
}
}


Thanks for any idea.

V-man
02-17-2004, 08:00 PM
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).]