# glOtho2d and multi viewports problem

## Recommended Posts

dagmare    122
Hey, I have another question. This time regarding glOtho2d. I have wrote a code that produces me 18 different viewports, for 18 different things to be ploted. But it seems like the last 2 vieports (loop nr 16 and 17) are in a wrong place! and also the coordinates run from 0 to 1 (for x and y) insted of 0 ClientWidth/2 (for x) and from 0 to ClientHeight (for y). Could somebody have a look on this code, and indicate please what did I do wrong? also is there any easier/faster way to produce those viewports?
//---------------------------------------------------------------------------

void __fastcall TFormMain::AnimKepEl(String FName)

{

GLfloat x,y;

if(Open == false)

for (int loop=0; loop<=17; loop++)

{

if (loop==0)

{       // Set The Viewport To The Top Left. e(a)

glViewport (45, 2*ClientHeight/3+28, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("e %f %f", elementMin[0], elementMax[0]);

}

if (loop==1)

{       // Set The Viewport To The Top Right. I(a)

glViewport (ClientWidth/2+35, 2*ClientHeight/3+28, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("I [deg]");

}

if (loop==2)

{

// Set The Viewport To The Midlle Left. OM(a)

glViewport (45, ClientHeight/3+32, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("node [deg]");

}

if (loop==3)

{       // Set The Viewport To The Bottom Left. om(a)

glViewport (ClientWidth/2+35, ClientHeight/3+32, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("omega [deg]");

}

if (loop==4)

{

// Set The Viewport To The Bottom Left. M(a)

glViewport (45, 36, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("M [deg]");

}

// extra place to be use later

if (loop==5)

{

// Set The Viewport To The Bottom Right. Empty at the moment.

glViewport (ClientWidth/2+35, 36, ClientWidth/2-45, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

glRasterPos2f(30, 50);

glRasterPos2f(5.0, ClientHeight/3-10.0);

glPrint("pdf value");

}

if (loop==6)

{

glViewport (45, 2*ClientHeight/3-6, ClientWidth/2-40, 28);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==7)

{

glViewport (ClientWidth/2+35, 2*ClientHeight/3-6, ClientWidth/2-40, 28);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==8)

{

glViewport (45, ClientHeight/3-2, ClientWidth/2-40, 28);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==9)

{

glViewport (ClientWidth/2+35, ClientHeight/3-2, ClientWidth/2-40, 28);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==10)

{

glViewport (45, 1, ClientWidth/2-40, 28);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==11)

{

glViewport (10, 2*ClientHeight/3+28, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==12)

{

glViewport (ClientWidth/2, 2*ClientHeight/3+28, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==13)

{

glViewport (10, ClientHeight/3+32, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==14)

{

glViewport (ClientWidth/2, ClientHeight/3+32, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==15)

{

glViewport (10, 36, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);

}

if (loop==16)

{       glPushMatrix();

glViewport (ClientWidth/2, 36, 30, ClientHeight/3-44);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

glColor3f(0,0,0);
DrawFrame(1,1);

}

if (loop==17)

{

glViewport (ClientWidth/2, 0, ClientWidth/2+100, 65);

glMatrixMode (GL_PROJECTION);

gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);

//DrawObjects();

glColor3f(0,0,0);

//DrawFrame(ClientWidth/2,ClientHeight/3);

}

glMatrixMode (GL_MODELVIEW);

glClear (GL_DEPTH_BUFFER_BIT);

//description of the axis (numerical values)

if((loop > 5) && (loop < 11))

AxisX(elementMax[0], elementMin[0]);

if((loop > 10) && (loop<16))

AxisY(elementMax[(loop-10)], elementMin[(loop-10)]);

//drawing the frame and ticks on the axis

if(loop <= 5)

{

DrawFrame(ClientWidth/2, ClientHeight/3);

DrawTicksX();

glRasterPos2f(ClientWidth/2-50.0, 10.0);

glPrint("a [AU]");	// Print GL text to the screen

}

//if a file was open, animate in first 6 windows

for(FileNr = 0; FileNr < NrOfFiles; FileNr++)

if( loop <= 5)

if(Open == true)

{

Line = 0;

scaleX = ClientWidth/2.0/(elementMax[0]-elementMin[0]);

scaleY = ClientHeight/3.0/(elementMax[loop+1]-elementMin[loop+1]);

while(Line < NrLines)

{

if(Line <= Step)

if(Line > 5)

{

GLfloat x,y;

x = scaleX*(elements[Line-5][0][FileNr]-elementMin[0]);

y = scaleY*(elements[Line-5][loop+1][FileNr]-elementMin[loop+1]);

if(Line == Step)

{

glPointSize(6);

glColor3f(r,g+0.9*FileNr,b);

DrawPoint(x, y);

}

else

{

glPointSize(1.0);

glColor3f(r,g+0.9*FileNr,b);

DrawPoint(x, y);

}

}

Line++;

}

}

}

}

//---------------------------------------------------------------------------


[Edited by - dagmare on October 11, 2007 9:57:03 AM]

##### Share on other sites

You have a great number of duplicated blocks of code. You should consider putting that code into a function or method. This will localize any problems with your code and make the overall algorithm easier to read or change.

An obvious example is the block of code you repeat inside your loop:
// ...glViewport (10, 2*ClientHeight/3+28, 30, ClientHeight/3-44);glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);glColor3f(0,0,0);// ...

Instead of repeating this block so many times, lets put it into a function and parameterize the variables:
void SetupOrthoViewport(int viewLeft, int viewWidth, int viewTop, int viewHeight){	glViewport (viewLeft, viewWidth, viewTop, viewHeight);	glMatrixMode (GL_PROJECTION);	glLoadIdentity ();	gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3);	glColor3f(0,0,0);}

Now, using this function, lets look at your code again:
/---------------------------------------------------------------------------void __fastcall TFormMain::AnimKepEl(String FName){	GLfloat x,y;	if(Open == false)		ReadCaseOne(FName);	for (int loop=0; loop<=17; loop++)	{		if (loop==0)		{		// Set The Viewport To The Top Left. e(a)			SetupOrthoViewport(45, 2*ClientHeight/3+28, ClientWidth/2-45, ClientHeight/3-44);			glRasterPos2f(5.0, ClientHeight/3-10.0);			glPrint("e %f %f", elementMin[0], elementMax[0]);		}		if (loop==1)		{		// Set The Viewport To The Top Right. I(a)			SetupOrthoViewport(ClientWidth/2+35, 2*ClientHeight/3+28, ClientWidth/2-45, ClientHeight/3-44);			glRasterPos2f(5.0, ClientHeight/3-10.0);			glPrint("I [deg]");		}		if (loop==2)		{			// Set The Viewport To The Midlle Left. OM(a)			SetupOrthoViewport(45, ClientHeight/3+32, ClientWidth/2-45, ClientHeight/3-44);			glRasterPos2f(5.0, ClientHeight/3-10.0);			glPrint("node [deg]");		}				//		// ...		//		if (loop==16)		{			glPushMatrix();			SetupOrthoViewport(ClientWidth/2, 36, 30, ClientHeight/3-44);			DrawFrame(1,1);		}		if (loop==17)		{			SetupOrthoViewport(ClientWidth/2, 0, ClientWidth/2+100, 65);		}			glMatrixMode (GL_MODELVIEW);			glLoadIdentity ();			glClear (GL_DEPTH_BUFFER_BIT);			//description of the axis (numerical values)			if((loop > 5) && (loop < 11))					AxisX(elementMax[0], elementMin[0]);			if((loop > 10) && (loop<16))					AxisY(elementMax[(loop-10)], elementMin[(loop-10)]);			//drawing the frame and ticks on the axis			if(loop <= 5)			{					DrawFrame(ClientWidth/2, ClientHeight/3);					DrawTicksX();					glRasterPos2f(ClientWidth/2-50.0, 10.0);					glPrint("a [AU]");	// Print GL text to the screen					glLoadIdentity ();			}			//if a file was open, animate in first 6 windows			for(FileNr = 0; FileNr < NrOfFiles; FileNr++)			if( loop <= 5)			if(Open == true)			{				Line = 0;				scaleX = ClientWidth/2.0/(elementMax[0]-elementMin[0]);				scaleY = ClientHeight/3.0/(elementMax[loop+1]-elementMin[loop+1]);				while(Line < NrLines)				{					if(Line <= Step)					if(Line > 5)					{						GLfloat x,y;						x = scaleX*(elements[Line-5][0][FileNr]-elementMin[0]);						y = scaleY*(elements[Line-5][loop+1][FileNr]-elementMin[loop+1]);						if(Line == Step)						{								glPointSize(6);								glColor3f(r,g+0.9*FileNr,b);								DrawPoint(x, y);						}						else						{								glPointSize(1.0);								glColor3f(r,g+0.9*FileNr,b);								DrawPoint(x, y);						}					}					Line++;			}		}	}}//---------------------------------------------------------------------------

Here, with almost all of the common code hidden from us, it is much easier to see what might be different in your last two viewports. The most obvious suspect is the stray glPushMatrix in your loop==16 block. This is probably messing things up, especially since I don't see a corresponding glPopMatrix().

Also, using a for loop in this case doesn't seem to be doing you much good. You are saying, "do 18 different things. After each one, do one more thing." You could easily achieve this without the for loop.

However, if you were to algorithmically determine the coordinates for your viewports and other variables, the for loop might work quite nicely. Are you tiling the viewports in the window, or otherwise creating some calculate-able pattern? If so, I'm sure you could shorten up your for loop by calculating these values on the fly instead of hard coding them. This make it much less likely that you gave one of your viewports an invalid value, and also collapse many of the conditionals.

Also, you could probably group that last hunk of code (the one after the first set of conditionals) into one or more functions, to make the code more clear and concise.

Having such a huge, messy loop makes it difficult to read through your code, and, as you can see, find any mistakes.

There are definitely more ways to clean up the code, and I recommend trying to figure them out.

I know you came here looking for answers and not coding standards, but I think that if you worked on writing cleaner code, you'd spend a lot less time searching for bugs (and creating them in the first place! [smile]).

Hope that helps.

##### Share on other sites
dagmare    122
I will try to make it more clear and than get back here if i will still have problems with finding the bug. It is unfortunatelly not the glPlushMarix as you suggested - I have checked that.
And yes it supose to make a patern of 6 main viewports in which I am animating something, and than 12 viewports for making a discription of x and y axis(I mean printing numerical values for axis ticks).
Is there an easier way of producing those axis descriptions? should I just draw
the description in the same viewports as animation and animate it a bit higher and more on the right? or would that just make more mess?

maybe you also know, how could I convert this animation to avi file?
cheers

##### Share on other sites
dagmare    122
ok, I have made some modifications, so hopefuly the code is clearer now.

Anyway after those modifications, all the ports (not olny two last one) for axis descriprion are in a wrong place, and too short! I dont have a clue what have I wrote wrong..
could anybody have a look at this code?
the mathematicial logic of ports creation seems ok, but it still produces the ports in wrong places.......

//---------------------------------------------------------------------------void __fastcall TFormMain::AnimKepEl(String FName){    int cnt_k=0, cnt_l=2;    if(Open == false)    ReadCaseOne(FName);    for (int loop=0; loop<=17; loop++)    {        //set ports for animation and animate keplerian elements        if(loop <=5)        {                SetElementPort(cnt_k, cnt_l, 50, 40, loop);                cnt_k++;                if (cnt_k > 1)                        cnt_l--;                if(cnt_k > 1)                        cnt_k = 0;        }        if(loop == 5)//set counters back        {                cnt_k=0;                cnt_l=2;        }        //set and draw vertical ports        if((loop > 5) && (loop <= 11))        {                SetYDescriptionPort(cnt_k, cnt_l, 50, 40);                cnt_k++;                if (cnt_k > 1)                        cnt_l--;                if(cnt_k > 1)                        cnt_k = 0;                if(cnt_l < 0)                        cnt_l = 2;        }        if(loop == 11)//set counters back        {                cnt_k=0;                cnt_l=2;        }        //set and draw horizontal ports        if((loop > 11) && (loop <= 17))        {                SetXDescriptionPort(cnt_k, cnt_l, 50, 40);                cnt_k++;                if (cnt_k > 1)                        cnt_l--;                if(cnt_k > 1)                        cnt_k = 0;                if(cnt_l < 0)                        cnt_l = 2;        }        if(loop == 17)//set counters back        {                cnt_k=0;                cnt_l=2;        }        glMatrixMode (GL_MODELVIEW);        glLoadIdentity();        glClear (GL_DEPTH_BUFFER_BIT);    }}//---------------------------------------------------------------------------void __fastcall TFormMain::SetElementPort(int k, int l, GLfloat separateX, GLfloat separateY, int loop_){ String Title[6]; Title[0]="e"; Title[1]="I [deg]"; Title[2]="omega [deg]"; Title[3]="node [deg]"; Title[4]="M [deg]"; Title[5]="pdf"; GLfloat Yheight = (ClientHeight-4.0*separateY)/3.0; glViewport (separateX+k*ClientWidth/2.0, (l+1)*(separateY)+l*Yheight, ClientWidth/2-2*separateX, Yheight); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glColor3f(0,0,0); glRasterPos2f(5.0, ClientHeight/3-10.0); glPrint("%s", Title[loop_]); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_DEPTH_BUFFER_BIT); DrawFrame(ClientWidth/2, ClientHeight/3); DrawTicksX(); glRasterPos2f(ClientWidth/2-65.0, 10.0); glPrint("a [AU]"); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glClear (GL_DEPTH_BUFFER_BIT); AnimateElements(loop_);}//---------------------------------------------------------------------------void __fastcall TFormMain::SetYDescriptionPort(int k, int l, GLfloat separateX, GLfloat separateY){ GLfloat Yheight = (ClientHeight-4.0*separateY)/3.0; GLfloat Xwidth = ClientWidth/2-2*separateX; glViewport(k*ClientWidth/2.0, (l+1)*separateY+l*Yheight, separateX, Yheight); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glColor3f(0,0,0); DrawFrame(1,1); glMatrixMode (GL_MODELVIEW); glLoadIdentity ();}//---------------------------------------------------------------------------void __fastcall TFormMain::SetXDescriptionPort(int k, int l, GLfloat separateX, GLfloat separateY){ GLfloat Yheight = (ClientHeight-4.0*separateY)/3.0; GLfloat Xwidth = ClientWidth/2-2*separateX; glViewport(separateX+k*ClientWidth/2.0, l*(separateY+Yheight), Xwidth, separateY); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, ClientWidth/2, 0, ClientHeight/3); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glColor3f(0,0,0); DrawFrame(1,1); glMatrixMode (GL_MODELVIEW); glLoadIdentity ();}//---------------------------------------------------------------------------void __fastcall TFormMain::AnimateElements(int loop){  GLfloat x,y;//if a file was open, draw animation in the first 6 windows  for(FileNr = 0; FileNr < NrOfFiles; FileNr++)  if( loop <= 5)  if(Open == true)  {        Line = 0;        scaleX = ClientWidth/2.0/(elementMax[0]-elementMin[0]);        scaleY = ClientHeight/3.0/(elementMax[loop+1]-elementMin[loop+1]);        while(Line < NrLines)        {                if(Line <= Step)                if(Line > 5)                {                        GLfloat x,y;                        x = scaleX*(elements[Line-5][0][FileNr]-elementMin[0]);                        y = scaleY*(elements[Line-5][loop+1][FileNr]-elementMin[loop+1]);                        if(Line == Step)                        {                                glPointSize(6);                                glColor3f(r,g+0.5*FileNr,b);                                DrawPoint(x, y);                        }                        else                        {                                glPointSize(1.0);                                glColor3f(r,g+0.5*FileNr,b);                                DrawPoint(x, y);                        }                }                Line++;        }  }  glFlush();}

This is how it look like now:

http://www.astro.helsinki.fi/~doszkiew/Public/now.jpg

(you need to enlarge the picture to actually see it)

and i would like the smaller frames to be allign with the main big frames, so they are suitable for the axis discriprion.

This is how it shouldlook like:

http://www.astro.helsinki.fi/~doszkiew/Public/later.jpg

[Edited by - dagmare on October 11, 2007 10:14:32 AM]

##### Share on other sites
The picture definitely helps. It is now more clear to me what you are trying to do.

You are trying to draw 6 different areas, each with 3 different viewports. One viewport is your main area and the other two are along the left and bottom sides of the middle viewport (tell me if I am wrong).

Knowing this, instead of looping 18 times (one for each viewport), lets loop 6 times, one for each area (group of 3 viewports). In each loop, we'll set up the three viewports. This approach will lead to a more intuitive, easy to understand algorithm.

First, let's define the different things we need to do in each area:
void DrawElementPort(int x, int y, int width, int height, const char * title){	glViewport (x, width, y, height);	glMatrixMode (GL_PROJECTION);	glLoadIdentity ();	gluOrtho2D(0, width, 0, height);	glMatrixMode (GL_MODELVIEW);	glLoadIdentity ();	glColor3f(0,0,0);	glRasterPos2f(5.0, height-10.0);	glPrint("%s", title);	glMatrixMode (GL_MODELVIEW);	glLoadIdentity ();	glClear (GL_DEPTH_BUFFER_BIT);	DrawFrame(width, height);	DrawTicksX();	glRasterPos2f(width-65.0, 10.0);	glPrint("a [AU]");	glMatrixMode (GL_MODELVIEW);	glLoadIdentity();	glClear (GL_DEPTH_BUFFER_BIT);	AnimateElement(x, y, width, height);}void DrawDescPort(int x, int y, int width, int height){	glViewport(x, width, y, height);	glMatrixMode (GL_PROJECTION);	glLoadIdentity ();	gluOrtho2D(0, width, 0, height);	glMatrixMode (GL_PROJECTION);	glLoadIdentity ();	glColor3f(0,0,0);	DrawFrame(1,1);	glMatrixMode (GL_MODELVIEW);	glLoadIdentity ();}void AnimateElement(int x, int y, int width, int height){	//if a file was open, draw animation in the first 6 windows	for(FileNr = 0; FileNr < NrOfFiles; FileNr++)	if(Open == true)	{		Line = 0;		scaleX = width/(elementMax[0]-elementMin[0]);		scaleY = height/(elementMax[loop+1]-elementMin[loop+1]);		while(Line < NrLines)		{			if(Line <= Step)			{				if(Line > 5)				{					GLfloat x,y;					x = scaleX*(elements[Line-5][0][FileNr]-elementMin[0]);					y = scaleY*(elements[Line-5][loop+1][FileNr]-elementMin[loop+1]);					if(Line == Step)					{						glPointSize(6);						glColor3f(r,g+0.5*FileNr,b);						DrawPoint(x, y);					}					else					{						glPointSize(1.0);						glColor3f(r,g+0.5*FileNr,b);						DrawPoint(x, y);					}				}			}			Line++;		}  }  glFlush();}

Doing those three things should give us a complete area. Notice how I removed all of the loop index checks from the functions and passed in the width and height of each viewport instead of recalculating them everywhere. The main loop should be responsible for passing that information anyway:
void __fastcall TFormMain::AnimKepEl(String FName){	// number of 'areas' (collections of viewports) along the x and y axis	int areaCountX = 2;	int areaCountY = 3;	int spacingX = 10; // spacing between areas along x axis	int spacingY = 10; // spacing between areas along y axis.  from your pic, this might need to be 0	int areaX = 0;	// x-coord of current area	int areaY = 0;	// y-coord of current area	int areaWidth = (ClientWidth / areasX) - (spacingX * areaCountX);	// width of an entire area	int areaHeight = (ClientHeight / areasY) - (spacingY * areaCountY);	// height of an entire area	int descWidth = 65; // width or height of each description viewport.  might be calculate-able	int elementWidth = areaWidth - descWidth;		// width of each middle area	int elementHeight = areaHeight - descHeight;	// height of each middle area	int x = 0, y = 0; // current x and y coord		char * titles [6] = {	"e",				"I [deg]",				"omega [deg]",				...			};	if(Open == false)		ReadCaseOne(FName);	for (areaY = 0; areaY < areaCountY; ++areaY)	{		x = 0;		for (areaX = 0; areaX < areaCountX; ++areaX)		{			// draw the y desc			DrawDescPort(x, y, descWidth, elementHeight);			// draw element			DrawElementPort(x + descWidth, y, elementWidth, elementHeight, titles[areaX * areaY]);			// draw x desc			DrawDescPort(x + descWidth, y + elementWidth, elementWidth, descWidth);			glMatrixMode (GL_MODELVIEW);			glLoadIdentity();			glClear (GL_DEPTH_BUFFER_BIT);			x += areaWidth + spacingX;		}		y += areaHeight + spacingY;	}}

Notice how simple the main loop is now. You'll also notice I used a nested for loop to make things simpler - I tile the areas row by row. We also draw one entire area at a time instead of one viewport at a time.

I also made a few assumptions -

• The left-top corner of the window is at 0,0. I don't know if this is the case, but the code will have to change a little if it isn't
• You were using glOrtho in each viewport and giving it the size of each area and not the size of each viewport. I'm not sure if that was intended or not, but I assumed not.

Also note that there may be some typos in my code, and some of the variables in the main function could probably be constants (for instance, I make the number of areas dynamic, but assign a constant number of titles in my title array).

This more organized code should limit the number of areas in which there might be errors to 4 - one of our four functions, each of which is a fairly small chunk of code. Also, since we don't specialize what we do based on the current loop index, if we have something wrong, we'll probably see it propagate to all of the viewports, instead of just a few.

##### Share on other sites
dagmare    122
I have found the mistacke now :) <jupi>
I didnt put glMatrixMode (GL_MODELVIEW); after each gluOrtho2D.
I have corrected this now, and the ports are in correct places and the coordinates are ok too! :)
I like the idea of making the code to be flexible on the number of areas, but at the moment I dont need it :) thank you.
btw. you have division by 0 somewhere there ;)

And correct me please if I am wrong, but:

1) gluOrtho2D just sets the coordinates inside the port, so they dont have to be identical with what I put to viewport (basically they might be whatever I want?).

2) glViewport calls for x and y coordinates of the left bottom corner of the port and than for it width and height: glViewport (x, y, width, height);

anyway I will try to make the code more clearer, and your advices were verry helpful - thank you! :)

##### Share on other sites
Quote:
 Original post by dagmareI didnt put glMatrixMode (GL_MODELVIEW); after each gluOrtho2D.

Ah, yes, I remember seeing that but I didn't take the time to understand whether or not you did that on purpose.

Quote:
 1) gluOrtho2D just sets the coordinates inside the port, so they dont have to be identical with what I put to viewport (basically they might be whatever I want?).

Yes, you are right; this is true. I just wanted to make sure you weren't assigning the wrong orthographic projection, which would alter your coordinates and potentially distort whatever you were drawing.

Quote:
 2) glViewport calls for x and y coordinates of the left bottom corner of the port and than for it width and height: glViewport (x, y, width, height);

Yes, you are right. Just goes to show how long it's been since I worked with openGL [smile].

Anyway, congrats on fixing your bug!

dagmare    122
Thanks :)