PDA

View Full Version : multiple windows once again



ondrej
06-01-2003, 07:59 AM
Helo everybody !!!
I'm trying to realize a program with OpenGL.
I have a Main window and 2 child windows. And I want to have in these child windows 2 different OpenGl graphics. I tried to define rendering context for each child windows, set up the wglMakeCurrent, but still doesn't work. What is appearing in one window, the same is appearing in the second window and I don't know, why.
Please help me !!!
Kind regerds, ondrej.


p.s.
here are the codes

statusu.h:

private: // User declarations
HDC hdc1;
HGLRC hrc1;
int PixelFormat1;
GLfloat w1, h1;

public: // User declarations
void __fastcall IdleLoop1(TObject*, bool& done1);
void __fastcall SetPixelFormatDescriptor1();
void __fastcall RenderGLScene1();
void __fastcall DrawObjects1();
//////////////////////////////////////////

bpmu.h:
private: // User declarations
HDC hdc2;
HGLRC hrc2;
int PixelFormat2;
GLfloat w2, h2;

public: // User declarations
void __fastcall IdleLoop2(TObject*, bool& done2);
void __fastcall SetPixelFormatDescriptor2();
void __fastcall RenderGLScene2();
void __fastcall DrawObjects2();
////////////////////////////////////////


stausu.cpp:

__fastcall TStatusForm::TStatusForm(TComponent* Owner)
: TForm(Owner)
{
Application->OnIdle = IdleLoop1; // Define idle function

}
//---------------------------------------------------------------------------
void __fastcall TStatusForm::BBLoadInputClick(TObject *Sender)
{

if( OpenDialog1->Execute() )
{
FILE *out,*out1;
out= fopen( OpenDialog1->FileName.c_str(),"rt");

int i=0;
while(!feof(out))
{
fscanf(out,"%lf %lf\n",&x1[i],&y1[i]);
i++;
}
i--;
number= i;
fclose(out);

delete [] x1;
delete [] y1;
}

}
//---------------------------------------------------------------------------

void __fastcall TStatusForm::IdleLoop1(TObject*, bool& done1)
{

done1 = false; // request more idle time from the system
RenderGLScene1(); // render the scene to buffer
SwapBuffers(hdc1); // show buffer on screen

}
//---------------------------------------------------------------------------
void __fastcall TStatusForm::SetPixelFormatDescriptor1()
{

PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of the structure
1, // structure version
PFD_DRAW_TO_WINDOW | // draw directly to window
// (not to a bitmap file)
PFD_SUPPORT_OPENGL | // allow DC to support opengl calls
PFD_DOUBLEBUFFER, // use double buffer
PFD_TYPE_RGBA, // use RGBA color mode (A = alpha)
24, // use 24 bit color
0,0,0,0,0,0,0,0,0,0,0,0,0, // not (yet) used
32, // use 32 bit z buffer
0,0, // not (yet) used
PFD_MAIN_PLANE, // draw to main plane
0,0,0, // not (yet) used
};
PixelFormat1 = ChoosePixelFormat(hdc1, &pfd); // choose and set the
SetPixelFormat(hdc1, PixelFormat1, &pfd); // appropriate pixelformat

}
//---------------------------------------------------------------------------
void __fastcall TStatusForm::RenderGLScene1()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawObjects1(); // render all objects to buffer
glFlush(); // show buffer on screen

}
//---------------------------------------------------------------------------
void __fastcall TStatusForm: http://www.opengl.org/discussion_boards/ubb/biggrin.gifrawObjects1()
{

// rendering functions

glLoadIdentity();
glColor3f(0.0,0.0,0.0); // set drawing color to black
glBegin(GL_LINES);
glVertex2f(-1.03,0.0); // draw x-axis
glVertex2f(1.03,0.0);
glVertex2f(0.0,0.0); // draw y-axis
glVertex2f(0.0,1.03);
glEnd();

glBegin(GL_TRIANGLES);
glVertex2f(1.04,0.0); // right x-axis arrow
glVertex2f(1.01,0.02);
glVertex2f(1.01,-0.02);

glVertex2f(-1.04,0.0); // left x-axis arrow
glVertex2f(-1.01,-0.02);
glVertex2f(-1.01,0.02);

glVertex2f(0.0,1.04); // y-axis arrow
glVertex2f(-0.02,1.01);
glVertex2f(0.02,1.01);
glEnd();

glBegin(GL_LINES);
for(float i=-1.0;i<=1.0;i+=0.1)
{ // draw x-grid
glVertex2f(i,0.0);
glVertex2f(i,-0.015);
for(float j=0.01;j<=0.09;j+=0.01)
{ // draw 9 smaller marks between
glVertex2f(i+j,0.0); // 2 bigger marks
glVertex2f(i+j,-0.008);
}
}
for(float i=0.0;i<=1.0;i+=0.1)
{ // draw y-grid
glVertex2f(0.01,i);
glVertex2f(-0.01,i);
for(float j=0.01;j<=0.09;j+=0.01)
{ // draw 9 smaller marks between
glVertex2f(0.005,i+j); // 2 bigger marks
glVertex2f(-0.005,i+j);
}
}
glEnd();

glColor3f(0.0,0.0,1.0); // set drawing color to red
glBegin(GL_POINTS); // draw input distribution

for(int i=0; i < StatusForm->number ; i++ )
glVertex2f( StatusForm->x1[i],StatusForm->y1[i] );

// for(float i=-1.0;i<1.0;i+=0.01)
// glVertex2f(i,exp(-i*i*9.0));

glEnd();
}
void __fastcall TStatusForm::FormCreate(TObject *Sender)
{

hdc1 = GetDC(StatusForm->Panel1->Handle); // get device context from main window
SetPixelFormatDescriptor1(); // define opengl parameters
hrc1 = wglCreateContext(hdc1); // use device context to create
// a rendering context
if(hrc1 == NULL) // couldn't get rendering context ?
ShowMessage("Creating Rendering Context failed.");

wglMakeCurrent(hdc1,hrc1); // tell windows to use hdc and hrc


if(wglMakeCurrent( hdc1, hrc1) == false) // couldn't activate hdc/hrc ?
ShowMessage("MakeCurrent of rendering context failed.");

glEnable(GL_DEPTH_TEST); // hidden surface removal
glEnable(GL_CULL_FACE); // don't show backside of polygons

glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // clear background to black

Panel1->Left = 10;
Panel1->Top = 176;
Panel1->Width = 220;
Panel1->Height = 95;

GLfloat nRange = 1.0;

w1 = Panel1->Width; // check new client width of the main window
h1 = Panel1->Height; // check new client height of the main window

if(h1 == 0) // prevent a division by zero, by making sure that
h1 = 1; // windows height is at least 1

glViewport(0, 0, w1, h1); // reset viewport

glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix
glLoadIdentity(); // restore matrix to original state
glOrtho(-1.05,1.05,-0.05,1.05,0.0,1.05);
glMatrixMode(GL_MODELVIEW); // the following operations affect the modelview matrix

}
//---------------------------------------------------------------------------

void __fastcall TStatusForm::FormResize(TObject *Sender)
{

Panel1->Left = 10;
Panel1->Top = 176;
Panel1->Width = 220;
Panel1->Height = 95;

wglMakeCurrent(hdc1,hrc1); // tell windows to use hdc and hrc
GLfloat nRange = 1.0;

w1 = Panel1->Width; // check new client width of the main window
h1 = Panel1->Height; // check new client height of the main window

if(h1 == 0) // prevent a division by zero, by making sure that
h1 = 1; // windows height is at least 1

glViewport(0, 0, w1, h1); // reset viewport

glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix
glLoadIdentity(); // restore matrix to original state
glOrtho(-1.05,1.05,-0.05,1.05,0.0,1.05);

// if (w <= h)
// glOrtho (-nRange, nRange, 0.0, nRange*h/w, -nRange, nRange);
// else
// glOrtho (-nRange*w/h, nRange*w/h, 0.0, nRange, -nRange, nRange);

// glMatrixMode(GL_MODELVIEW); // the following operations affect the modelview matrix

}
//---------------------------------------------------------------------------

void __fastcall TStatusForm::Timer1Timer(TObject *Sender)
{
/*
BPMForm->Timer1->Enabled = false;
wglMakeCurrent( hdc1, hrc1);
BPMForm->Timer1->Enabled = true;
*/
}
//---------------------------------------------------------------------------


void __fastcall TStatusForm::FormPaint(TObject *Sender)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
DrawObjects1();

}
//---------------------------------------------------------------------------


void __fastcall TStatusForm::FormActivate(TObject *Sender)
{
wglMakeCurrent( hdc1, hrc1);
SwapBuffers(hrc1);
}
//---------------------------------------------------------------------------
/////////////////////////////////////


bpmu.cpp:

__fastcall TBPMForm::TBPMForm(TComponent* Owner)
: TForm(Owner)
{

Application->OnIdle = IdleLoop2; // Define idle function

}
void __fastcall TBPMForm::IdleLoop2(TObject*, bool& done2)
{

done2 = false; // request more idle time from the system
RenderGLScene2(); // render the scene to buffer
SwapBuffers(hdc2); // show buffer on screen

}
//---------------------------------------------------------------------------
void __fastcall TBPMForm::SetPixelFormatDescriptor2()
{

PIXELFORMATDESCRIPTOR pfd1 =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of the structure
1, // structure version
PFD_DRAW_TO_WINDOW | // draw directly to window
// (not to a bitmap file)
PFD_SUPPORT_OPENGL | // allow DC to support opengl calls
PFD_DOUBLEBUFFER, // use double buffer
PFD_TYPE_RGBA, // use RGBA color mode (A = alpha)
24, // use 24 bit color
0,0,0,0,0,0,0,0,0,0,0,0,0, // not (yet) used
32, // use 32 bit z buffer
0,0, // not (yet) used
PFD_MAIN_PLANE, // draw to main plane
0,0,0, // not (yet) used
};
PixelFormat2 = ChoosePixelFormat(hdc2, &pfd1); // choose and set the
SetPixelFormat(hdc2, PixelFormat2, &pfd1); // appropriate pixelformat

}
//---------------------------------------------------------------------------
void __fastcall TBPMForm::RenderGLScene2()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawObjects2(); // render all objects to buffer
glFlush(); // show buffer on screen

}
//---------------------------------------------------------------------------
void __fastcall TBPMForm: http://www.opengl.org/discussion_boards/ubb/biggrin.gifrawObjects2()
{

// rendering functions

glLoadIdentity();
glColor3f(0.0,1.0,0.0); // set drawing color to black
glBegin(GL_LINES);
glVertex2f(-1.03,0.0); // draw x-axis
glVertex2f(1.03,0.0);
glVertex2f(0.0,0.0); // draw y-axis
glVertex2f(0.0,1.03);
glEnd();

glBegin(GL_TRIANGLES);
glVertex2f(1.04,0.0); // right x-axis arrow
glVertex2f(1.01,0.02);
glVertex2f(1.01,-0.02);

glVertex2f(-1.04,0.0); // left x-axis arrow
glVertex2f(-1.01,-0.02);
glVertex2f(-1.01,0.02);

glVertex2f(0.0,1.04); // y-axis arrow
glVertex2f(-0.02,1.01);
glVertex2f(0.02,1.01);
glEnd();

glBegin(GL_LINES);
for(float i=-1.0;i<=1.0;i+=0.1)
{ // draw x-grid
glVertex2f(i,0.0);
glVertex2f(i,-0.015);
for(float j=0.01;j<=0.09;j+=0.01)
{ // draw 9 smaller marks between
glVertex2f(i+j,0.0); // 2 bigger marks
glVertex2f(i+j,-0.008);
}
}
for(float i=0.0;i<=1.0;i+=0.1)
{ // draw y-grid
glVertex2f(0.01,i);
glVertex2f(-0.01,i);
for(float j=0.01;j<=0.09;j+=0.01)
{ // draw 9 smaller marks between
glVertex2f(0.005,i+j); // 2 bigger marks
glVertex2f(-0.005,i+j);
}
}
glEnd();

glColor3f(1.0,0.0,0.0); // set drawing color to red
glBegin(GL_LINE_STRIP); // draw input distribution

// for(int i=0; i < StatusForm->number ; i++ )
// glVertex2f( StatusForm->x1[i],StatusForm->y1[i]+5 );


for(float i=-1.0;i<1.0;i+=0.01)
glVertex2f(i,exp(-i*i*9.0));

glEnd();
}
void __fastcall TBPMForm::FormCreate(TObject *Sender)
{

hdc2 = GetDC(BPMForm->Panel1->Handle); // get device context from main window
SetPixelFormatDescriptor2(); // define opengl parameters
hrc2 = wglCreateContext(hdc2); // use device context to create
// a rendering context
if(hrc2 == NULL) // couldn't get rendering context ?
ShowMessage("Creating Rendering Context failed.");

wglMakeCurrent(hdc2,hrc2); // tell windows to use hdc and hrc

if(wglMakeCurrent( hdc2, hrc2) == false) // couldn't activate hdc/hrc ?
ShowMessage("MakeCurrent of rendering context failed.");

glEnable(GL_DEPTH_TEST); // hidden surface removal
glEnable(GL_CULL_FACE); // don't show backside of polygons

glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // clear background to black

Panel1->Left = 10;
Panel1->Top = 10;
Panel1->Width = BPMForm->Width-40;
Panel1->Height = BPMForm->Height-70;

Label1->Left=20;
Label1->Top = BPMForm->Height-50;

Label2->Left=300;
Label2->Top = BPMForm->Height-50;

ProgressBar1->Left = 140;
ProgressBar1->Top = BPMForm->Height-50;

GLfloat nRange = 1.0;

w2 = Panel1->Width; // check new client width of the main window
h2 = Panel1->Height; // check new client height of the main window

if(h2 == 0) // prevent a division by zero, by making sure that
h2 = 1; // windows height is at least 1

glViewport(0, 0, w2, h2); // reset viewport

glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix
glLoadIdentity(); // restore matrix to original state
glOrtho(-1.05,1.05,-0.05,1.05,0.0,1.05);
glMatrixMode(GL_MODELVIEW); // the following operations affect the modelview matrix

}
//---------------------------------------------------------------------------

void __fastcall TBPMForm::FormResize(TObject *Sender)
{

Panel1->Left = 10;
Panel1->Top = 10;
Panel1->Width = BPMForm->Width-30;
Panel1->Height = BPMForm->Height-70;

Label1->Left=20;
Label1->Top = BPMForm->Height-50;

Label2->Left=300;
Label2->Top = BPMForm->Height-50;

ProgressBar1->Left = 140;
ProgressBar1->Top = BPMForm->Height-50;

wglMakeCurrent(hdc2,hrc2); // tell windows to use hdc and hrc
GLfloat nRange = 1.0;

w2 = Panel1->Width; // check new client width of the main window
h2 = Panel1->Height; // check new client height of the main window

if(h2 == 0) // prevent a division by zero, by making sure that
h2 = 1; // windows height is at least 1

glViewport(0, 0, w2, h2); // reset viewport

glMatrixMode(GL_PROJECTION); // the following operations affect the projection matrix
glLoadIdentity(); // restore matrix to original state
glOrtho(-1.05,1.05,-0.05,1.05,0.0,1.05);

// if (w <= h)
// glOrtho (-nRange, nRange, 0.0, nRange*h/w, -nRange, nRange);
// else
// glOrtho (-nRange*w/h, nRange*w/h, 0.0, nRange, -nRange, nRange);

// glMatrixMode(GL_MODELVIEW); // the following operations affect the modelview matrix

}
//---------------------------------------------------------------------------

void __fastcall TBPMForm::Timer1Timer(TObject *Sender)
{
/*
StatusForm->Timer1->Enabled = false;
wglMakeCurrent( hdc2, hrc2);
StatusForm->Timer1->Enabled = true;
*/
}
//---------------------------------------------------------------------------

void __fastcall TBPMForm::FormPaint(TObject *Sender)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
DrawObjects2();

}
//---------------------------------------------------------------------------

void __fastcall TBPMForm::FormActivate(TObject *Sender)
{
wglMakeCurrent( hdc2, hrc2);
SwapBuffers(hrc2);
}
//---------------------------------------------------------------------------

Rog
06-01-2003, 08:59 PM
It looks like you're using C++ Builder? At first glance, I can see that your problem may be to do with the OnIdle function. As far as I know, this is set at the Application level so you only ever have *one* idle function. In your code, you are just switching to a different idle function in the constructor of the child forms - so whichever got instantiated last will determine what is shown on both screens.

Try using a single OnIdle function that handles the rendering to both children.

ondrej
06-01-2003, 09:56 PM
Hi there !!

Yes, I'm using Builder 6.0.

How do you mean, set the rendering context in both children window ?
I have defined two OnIdle functions in the header files of the children windows.

void __fastcall IdleLoop1(TObject*, bool& done1);
void __fastcall IdleLoop2(TObject*, bool& done2);
Or did you mean something else ??

Please don't forget, I am a beginner also in C++

Thanx a lot