View Full Version : I should see a Square, instead of a Rectangle...

gedamial

03-21-2016, 07:45 AM

Hello.

I want to draw a Square on my OpenGL application.

So, If I have the X,Y coordinates of the top-left vertex and the lenght of the sides (which are all the same for a square), with a very simple math I can find the other vertices in the 2D space.

// Vertex is a simple struct with a constructor taking 2 arguments: X and Y of the vertex

// In this case I set the topLeft vertex to have X = 0, Y = 0.5f

Vertex topLeft{ 0.0f, 0.5f };

//side is the lenght of the square's sides

GLfloat side = 0.5f;

// DrawTriangle is a function that takes 3 vertices (each of those has a x,y coordinate) and draws them on the application

// 1st argument: the topLeft vertex that we've already created

// 2nd and 3rd agument: the other two vertices

DrawTriangle(window, topLeft, Vertex{ topLeft.x + side, topLeft.y }, Vertex{ topLeft.x + side, topLeft.y - side });

This code will draw half square. But not exactly as I expected.

This is the result: (attachment)

2243

Now let's draw the other half square:

DrawTriangle(window, topLeft, Vertex{ topLeft.x, topLeft.y - side }, Vertex{ topLeft.x + side, topLeft.y - side });

Aaaand, the result is rectangle, not a square

2244

Is my math wrong?

Cornix

03-21-2016, 08:21 AM

The code you have shown us really isnt enough to give you any kind of feedback. Especially because you didnt show us any OpenGL code but code using some kind of framework.

If I had to guess I would say you are using the old deprecated rendering pipeline and you have forgotten to set up your matrices.

gedamial

03-21-2016, 08:29 AM

The code you have shown us really isnt enough to give you any kind of feedback. Especially because you didnt show us any OpenGL code but code using some kind of framework.

If I had to guess I would say you are using the old deprecated rendering pipeline and you have forgotten to set up your matrices.

Ok sorry.

This is the DrawTriangle() function that I use above:

void DrawTriangle(SDL_Window* Win, Vertex v1, Vertex v2, Vertex v3)

{

Vertex vertices[3] { v1, v2, v3 };

glGenBuffers(1, &vbo);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableVertexAttribArray(0);

glDisableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, 0);

}

Spoops

03-21-2016, 12:10 PM

You should take into account that clip space coordinates don't change ([-1;1] on all 3 axis) while the window's aspect ratio changes.

gedamial

03-21-2016, 01:06 PM

You should take into account that clip space coordinates don't change ([-1;1] on all 3 axis) while the window's aspect ratio changes.

Sorry, I don't get what you wanna say.

How can I solve that problem?

Spoops

03-21-2016, 01:57 PM

I meant that OpenGL doesn't care what size your window is, the coordinates still range from -1 to 1 on the whole window.

gedamial

03-21-2016, 02:03 PM

I meant that OpenGL doesn't care what size your window is, the coordinates still range from -1 to 1 on the whole window.

I know. But even though I just draw a triangle with these coordinates:

First vertex:

{0, 0.5f}

Second vertex:

{ 0.5f, 0.5f }

Third vertex:

{ 0.5f, 0 }

OpenGL draws this:

2245

As you can see, the two catheti aren't equal but they should be

Cornix

03-21-2016, 03:14 PM

They are equal. But the X-Axis has a different scaling factor.

If your Window is 500 pixels in width and your rectangle is 0.5 length units in width with the bounds going from -1.0 to 1.0 then that is 125 pixels (=500/4).

If your Window is 300 pixels in height and your rectangle is 0.5 length units in height with the bounds going from -1.0 to 1.0 then that is 75 pixels (=300/4).

Its 0.5 length units on both axis, but the results in pixels are different.

OpenGL doesnt care about pixels. You are supposed to set up your own coordinate system in the way that you want to use it.

gedamial

03-21-2016, 03:18 PM

They are equal. But the X-Axis has a different scaling factor.

If your Window is 500 pixels in width and your rectangle is 0.5 length units in width with the bounds going from -1.0 to 1.0 then that is 125 pixels (=500/4).

If your Window is 300 pixels in height and your rectangle is 0.5 length units in height with the bounds going from -1.0 to 1.0 then that is 75 pixels (=300/4).

Its 0.5 length units on both axis, but the results in pixels are different.

OpenGL doesnt care about pixels. You are supposed to set up your own coordinate system in the way that you want to use it.

How do I well render my geometry independently from the size of the Window?

Spoops

03-21-2016, 03:40 PM

Choose correct positions or send a matrix in your vertex shader to rescale/translate primitives.

reaktor24

03-21-2016, 03:41 PM

You need to make sure your aspect ratio is 1:1 like this: When you setup your rendering context setup the aspect ratio last:

// Grab hold of this windows Device Context

if ((hDC = GetDC(handle)) == NULL) return 0;

// Use the Device Context to get the graphics cards' pixel format

if (!SelectPixelFormat(hDC)) return 0;

// Create the OpenGL Rendering Context

if ((hRC = wglCreateContext(hDC)) == NULL) return 0;

// Next we select the Rendering Context and make it the current Rendering Context

if (!wglMakeCurrent(hDC, hRC)) return 0;

// Finally we setup the projection and viewport BEFORE we initialise OpenGL

ResizeViewport(800, 600);

My ResizeViewport function looks like this:

// This function resizes the screen display to the requested size

void ResizeViewport(int width, int height)

{

// Prevent the aspect ratio from dividing by zero

if (height == 0) { height = 1; }

// ****** STAGE 1: CALCULATE THE VIEWPORT TRANSFORMATION ******/

glViewport(0, 0, width, height);

// ****** STAGE 2: CALCULATE THE PROJECTION TRANSFORMATION ******/

UpdateProjection(45.0f, (float)width, (float)height, 1.0f, 100.0f);

}

Then in update projection I update the aspect ratio and setup my projection matrix like this:

// Update the projection matrix

void UpdateProjection(float fov, float width, float height, float z_near, float z_far)

{

float aspect_ratio = width / height;

mProjectionMatrix.LoadIdentity();

mProjectionMatrix.BuildPerspectiveMatrix(fov, aspect_ratio, z_near, z_far); // 3D perspective

// mProjectionMatrix.BuildOrthographicMatrix(width, height);

}

gedamial

03-22-2016, 06:06 AM

@Spoofs @Cornix @reaktor24

I've tried this code before initializing SDL:

float aspect = (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT;

glEnable(GL_DEPTH_TEST);

glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

glMatrixMode(GL_PROJECTION);

glOrtho(-aspect, aspect, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

But that didn't work

Powered by vBulletin® Version 4.2.3 Copyright © 2017 vBulletin Solutions, Inc. All rights reserved.