PDA

View Full Version : Visualization Problem (glOrtho)



marcusscarface
11-08-2016, 02:37 PM
Hi everyone.

I'm a real newbie in OpenGL and I came across a problem I can't figure out :sick:

I don't know if I did something wrong in my functions (maybe wrong parameters to glOrtho) and so the result is just wrong or if it's all normal as it would be.

In particular I have this situation:

LINK -> h_ttp://imgur.com/a/SWGFn (remove the _ from the link please)

I would like to have the green rect and all its inner content to take all the space of the window and not just a part of it (if you notice there are some empty spaces all around the main content: "the green rect").

Here there are my main functions:



#define HEXAGONAL_SHRINK 0.8655f

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

void reshape(int w, int h)
{
GLfloat aspect, dim;

glViewport (0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (s3hex->rows > s3hex->columns)
dim = s3hex->rows * 0.5f;
else
dim = s3hex->columns * 0.5f;
aspect = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho (-dim, dim, -dim/aspect, dim/aspect, 1.0, -1.0);
else
glOrtho (-dim*aspect, dim*aspect, -dim, dim, 1.0, -1.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void display(void)
{
CALint i, j;
CALreal z, h, color;

glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();

glTranslatef(-(s3hex->columns*HEXAGONAL_SHRINK)/2.0f, s3hex->rows/2.0f, 0);
glScalef(HEXAGONAL_SHRINK, -1, 1);

for (i=0; i<s3hex->rows; i++)
for (j=0; j<s3hex->columns; j++)
{
z = calGet2Dr(s3hex,Q.z,i,j);
h = calGet2Dr(s3hex,Q.h,i,j);

if (h > 0)
{
color = (h - h_min) / (h_Max - h_min);
glColor3d(1,color,0);
glRecti(j, i, j+1, i+1);
}
else
if (z > 0)
{
color = (z - z_min) / (z_Max - z_min);
glColor3d(color,color,color);
glRecti(j, i, j+1, i+1);
}
}

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3d(0,1,0);
glRectd(0,0,s3hex->columns, s3hex->rows);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glPopMatrix();

glutSwapBuffers();
}


P.S: If you need to know what's s3hex is, then you can see it as a normal matrix in which every cell contains a set of substates. Then in according to the value of these substates I set the colors for the rendering in the display func.

Thanks in advance for help :)

marcusscarface
11-10-2016, 01:28 AM
Anyone ?

P.S: besides that problem, is there any way to get or calculate the pixel (screen) coordinates of the green rectangle every time the reshape funct is called ?

Silence
11-10-2016, 02:16 AM
Well, just draw a quad that has exactly the same size than your orthographic projection:



gluOrtho2D(0, width, 0, height);
...
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(width, 0);
glVertex2f(width, height);
glVertex2f(0, height);
glEnd();


No need for translations or scales.

marcusscarface
11-10-2016, 03:03 AM
Well, just draw a quad that has exactly the same size than your orthographic projection:



gluOrtho2D(0, width, 0, height);
...
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(width, 0);
glVertex2f(width, height);
glVertex2f(0, height);
glEnd();


No need for translations or scales.

Regarding to my first question I think I just can't do what you've suggested because I need to keep the correct aspect ratio in every situation and the inner content of the rect would be distorted without scales or translates and that's because s3hex->columns and s3hex->rows are not always equal to the viewport :sorrow:
Any tips for the other question ? I'll solve my problem anyway if I could do that.

Thanks for the help.

GClements
11-10-2016, 03:14 AM
As a general guide, the way to calculate the scale factor while maintaining the correct aspect ratio is to:

1. Calculate the scale factor which just fills the screen vertically.
2. Calculate the scale factor which just fills the screen horizontally.
3. Choose the smaller scale factor, and use it for both axes.

Calculating a scale factor boils down to calculating what the size would be with a scale factor of 1, then dividing the desired size by that value.

Silence
11-10-2016, 06:00 AM
Regarding to my first question I think I just can't do what you've suggested because I need to keep the correct aspect ratio in every situation and the inner content of the rect would be distorted without scales or translates and that's because s3hex->columns and s3hex->rows are not always equal to the viewport :sorrow:
Any tips for the other question ? I'll solve my problem anyway if I could do that.

Thanks for the help.

Right. I missed that point.

GClements answered it. Just use the minimum value of the width and height (which will normally be height) as the size of the quad and the common factor for the scaling.

marcusscarface
11-10-2016, 08:20 AM
Ok got the issue and now it everything seems to work properly, thanks.

Regarding to the last answer I posted (to know the pixel coordinates) of the green rect, I came across the gluProject() funct which should do exactly what I need, convert 3D coordinates to 2D screen coordinates. However when I call it, it just gives me some coordinates that are not corresponding with the ones I get from the mouse clicked event on the same vertex.
I'm pretty sure that I'm passing wrong matrix to gluProject() or I'm calling it at wrong times.
So regarding to the same code I originally posted, at what time should I call the gluProject func to get the screen coordinates of the top left corner of the green rect (0,0) ? Myabe after the translation and scaling in display funct and so before the popMatrix() call ?

P.S: I just solved the problem by calling gluProject() just before popMatrix() in the display function.

Thanks all for the help.

GClements
11-10-2016, 07:43 PM
P.S: I just solved the problem by calling gluProject() just before popMatrix() in the display function.

The matrices need to be those used for rendering, so the calls to retrieve the matrices probably need to be made at that point. But it doesn't matter where the gluProject() call goes.

Also, bear in mind that OpenGL window coordinates have (0,0) at the lower-left, while mouse coordinates are normally reported with (0,0) at the upper-left.

marcusscarface
11-11-2016, 09:25 AM
The matrices need to be those used for rendering, so the calls to retrieve the matrices probably need to be made at that point. But it doesn't matter where the gluProject() call goes.

Also, bear in mind that OpenGL window coordinates have (0,0) at the lower-left, while mouse coordinates are normally reported with (0,0) at the upper-left.

Thanks for the tip. Now it works perfectly !