Followers 0

# OpenGL Orthographic matrix not working

## 13 posts in this topic

Hi all,

I am having trouble creating an orthographic projection in opengl (without using glOrtho).  And before anyone tells me to use glOrtho, lets just pretend I'm using opengl 3.0 as an exercise.  Here is the way I have set up my matrix:

projectionMatrix.m00 = 2/WIDTH;
projectionMatrix.m11 = 2/HEIGHT;
projectionMatrix.m22 = -2/(far_plane - near_plane);
projectionMatrix.m32 = -((far_plane + near_plane)/(far_plane - near_plane));
projectionMatrix.m33 = 1;


This is your typical ortho projection matrix, taken straight from the opengl spec def. for glOrtho.

When I set up a frustrum and use a perspective matrix, this works fine, but I can't use my regular screen coordinates properly.  But when I use the glOrtho matrix above, I see nothing but my background color. Anyone know what's going on? Is my matrix wrong?

#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;

out vec4 pass_Color;
out vec2 pass_TextureCoord;

void main(void){
gl_Position = in_Position;

//override gl position with new calculated position
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;

pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;

}

Any help appreciated.

Thanks!

0

##### Share on other sites

Try this:

void glOrtho(float* out, float left, float right,float bottom, float top,float near, float far)
{

float a = 2.0f / (right - left);
float b = 2.0f / (top - bottom);
float c = -2.0f / (far - near);

float tx = - (right + left)/(right - left);
float ty = - (top + bottom)/(top - bottom);
float tz = - (far + near)/(far - near);

float ortho[16] = {
a, 0, 0, 0,
0, b, 0, 0,
0, 0, c, 0,
tx, ty, tz, 1
};

memcpy(out, ortho, sizeof(float)*16);
}


Your vertex program should be fine if it works with your perspective matrix.  Let me know if this fixes your problem, this has been confirmed to work for OpenGL ES 2.0.

Shogun.

0

##### Share on other sites

Thanks Shogun - but isn't that matrix the same as the one I have, if I have 0 as left and 680 as right for example (and same for top/bottom/height)?

0

##### Share on other sites

What geometry are you feeding it?

A mistake I see sometimes is that people will be drawing, say, a quad: [b](-1,-1,0) -> (1,1,0)[/b] or some other geometry on a very small scale. Which will work fine with a perspective matrix, since you can always move your camera to near enough the object that it appears as large in the viewport as you need it to be. But in a screen-size orthographic projection, that 2x2 size quad will only ever be 2x2 pixels on screen, regardless of where you put your camera. This makes switching from perspective to ortho tricky, in that you have to think about the scale of your objects. If you make your base unit to be a meter for example (ie, 1 unit=1 meter) then you might have a character model that is 2 units tall. In an orthographic projection, this object will only be 2 pixels tall.

So if your geometry is small, you either need to scale the geometry or include a scaling factor when constructing your matrix.

0

##### Share on other sites

Well right now all I am trying to do is get a 40 pixel by 40 sprite displayed on the screen.  I have tried messing around with the size of the sprite to no avail.  Once I get home I will take a look at the code and give you some more details about it, but I have a feeling you ar right about the scaling/size/etc.

0

##### Share on other sites

Ok, so I have a sprite with x,y,z (10,10,0)  with w/h 10fx10f

I have left as 0 and right as 680

top as as 480, bottom as 0

Still I see nothing.

Also, I am using lwjgl, in which if you have a matrix4f, I think m23 means 2nd column, 3rd row.

              Sprite sprite = new Sprite("assets/texture/redman.png", 50f, 50f, 10f, 10f );

projectionMatrix.m00 = 2/WIDTH;
projectionMatrix.m11 = 2/HEIGHT;
projectionMatrix.m22 = -2/(far_plane - near_plane);
projectionMatrix.m30 = -1;
projectionMatrix.m31 = -1;
projectionMatrix.m32 = -((far_plane + near_plane)/(far_plane - near_plane));
projectionMatrix.m33 = 1;

cameraPos = new Vector3f(0,0,-1); ...

//Translate camera
Matrix4f.translate(cameraPos, viewMatrix, viewMatrix);

//Scale, translate and rotate model
Matrix4f.scale(modelScale, modelMatrix, modelMatrix);
Matrix4f.translate(modelPos, modelMatrix, modelMatrix);


..

Edited by sufimaster
0

##### Share on other sites

Have you tried disabling back face culling?

If your sprite doesn't have the correct winding, and back face culling is enabled , then it will not be drawn.

Also, in OpenGL the Y coordinate goes from bottom to top, so make sure that you are positioning the sprite inside the view (unlike the projection matrix where point 0.0, 0.0, 0.0, is the center of the screen, on an orthographic projection, it is the left bottom corner).

Although you can change this when you build the matrix.

You can also try a bigger sprite, like with a size of (100, 100).

One last note. You should try the function Shogun posted to calculate your matrix. Somehow, and i might be wrong, but it doesn't seem like your matrix is being calculated like it should (again, it may be just me).

Don't know if this is your problem, but try it and see.

Edited by __SKYe
0

##### Share on other sites

Ok- so i used Shogun's method, I messed around with the camera position and near and far plane.

Now:

near plane is 1f, far plane is 100f (though I dont see why this matters in an ortho projection)

Camera is located at 0,0,-1

Sprite is at 0,0,0 dim: 10x10 pixels.

I can actually see it on the screen now, but it seems like everything is vanishing at the origin point, as attached:

This is supposed to be a quad, but the perspective is all wonky. Any idea what's going on now?

0

##### Share on other sites

Bump - anyone? This is super frustrating.  Is my ortho matrix still messed up?

0

##### Share on other sites

How are you sending this to your shader?  Are you multiplying it by your previous projection matrix before doing so?  These are two other areas where things can go wrong, and you haven't provided sufficient info to diagnose.

0

##### Share on other sites

This is how I send it to the shader: I know this part works since the perspective projection matrix works, but the ortho produces wierd results.

As for my previous projection matrix - this is my first projection matrix - so I am not multiplying it by anything before sending it tothe shader. Should I be?

///upload matrices to uniform varis in shader

projectionMatrix.store(matrix44Buffer);matrix44Buffer.flip();
GL20.glUniformMatrix4(projectionMatrixLocation, false, matrix44Buffer);

viewMatrix.store(matrix44Buffer);matrix44Buffer.flip();
GL20.glUniformMatrix4(viewMatrixLocation, false, matrix44Buffer);

modelMatrix.store(matrix44Buffer);matrix44Buffer.flip();
GL20.glUniformMatrix4(modelMatrixLocation, false, matrix44Buffer);

GL20.glUseProgram(0);

0

##### Share on other sites

I managed to figure this out - apparently I was not accessing the matrix elements correctly - transposing their accessors = m03 instead of m30 for example for the translation matrix.  All is well now! Thanks everyone.

0

##### Share on other sites

I noticed you're transforming your matrices as so:

projectionMatrix * viewMatrix * modelMatrix

This is also how I do it, but a lot of people do it opposite (and I think glOrtho does too). If this is the case, than the glOrtho() code provided above may be correct, but it just has to be transposed. Here's my camera's ortho code:

void Camera::Ortho(float width, float height, float zNear, float zFar)
{
Ortho(0.0f, width, 0.0f, height, zNear, zFar);
}

void Camera::Ortho(float left, float right, float top, float bottom, float zNear, float zFar)
{
// find the translation vector
const float tx = - (right + left)/(right - left);
const float ty = - (top + bottom)/(top - bottom);
const float tz = - (zFar + zNear)/(zFar - zNear);

// column 1
projMat.m[ 0] = 2.0f / (right - left);
projMat.m[ 1] = 0;
projMat.m[ 2] = 0;
projMat.m[ 3] = 0;

// column 2
projMat.m[ 4] = 0;
projMat.m[ 5] = 2.0f / (top - bottom);
projMat.m[ 6] = 0;
projMat.m[ 7] = 0;

// column 3
projMat.m[ 8] = 0;
projMat.m[ 9] = 0;
projMat.m[10] = -2.0f / (zFar - zNear);
projMat.m[11] = 0;

// column 4
projMat.m[12] = tx;
projMat.m[13] = ty;
projMat.m[14] = tz;
projMat.m[15] = 1;

mode = PROJECTION_MODE_ORTHOGONAL;
Update(0.0f); // update the camera
}


The first method is just a shortcut I created where the origin is in the upper-left corner of the screen is treated as the origin. The second method is what would emulate glOrtho() from the old OpenGL days, only it should be multiplied first like you have it.

Also, keep in mind that all matrix elements are an array of 16 floats stored on a column-by-column basis:

m[ 0] m[ 4] m[ 8] m[12]
m[ 1] m[ 5] m[ 9] m[13]
m[ 2] m[ 6] m[10] m[14]
m[ 3] m[ 7] m[11] m[15]


When you feed the matrix as a 4x4 to OpenGL, make sure that the transpose argument is GL_FALSE. That's very important.

0

##### Share on other sites

When you feed the matrix as a 4x4 to OpenGL, make sure that the transpose argument is GL_FALSE. That's very important.

Column-major versus row-major is purely a notational convention. Note that post-multiplying with column-major matrices produces the same result as pre-multiplying with row-major matrices. The OpenGL Specification and the OpenGL Reference Manual both use column-major notation. You can use any notation, as long as it's clearly stated.

Also

Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community. Column-major notation suggests that matrices are not laid out in memory as a programmer would expect.

OpenGL is perfectly capable of using either row-major or column-major matrices (and all the more so with the programmable pipeline); the only important thing is that you be consistent in your code.  That just means getting the multiplication orders correct in both your C/C++ code and your shader code.  You don't have to use the same major-ness in your shaders as you use in your C/C++: either transpose before sending (either manually or by using GL_TRUE in your glUniformMatrix call) or flip the multiplication order in your shader code.

So what's actually important is that you know which major-ness each element of your code uses and that you set things up appropriately for that; otherwise the importance of row-major versus column-major is hugely overstated.

0

## Create an account

Register a new account

Followers 0

• ### Similar Content

• By mapra99
Hello

I am working on a recent project and I have been learning how to code in C# using OpenGL libraries for some graphics. I have achieved some quite interesting things using TAO Framework writing in Console Applications, creating a GLUT Window. But my problem now is that I need to incorporate the Graphics in a Windows Form so I can relate the objects that I render with some .NET Controls.

To deal with this problem, I have seen in some forums that it's better to use OpenTK instead of TAO Framework, so I can use the glControl that OpenTK libraries offer. However, I haven't found complete articles, tutorials or source codes that help using the glControl or that may insert me into de OpenTK functions. Would somebody please share in this forum some links or files where I can find good documentation about this topic? Or may I use another library different of OpenTK?

Thanks!

• Hello, I have been working on SH Irradiance map rendering, and I have been using a GLSL pixel shader to render SH irradiance to 2D irradiance maps for my static objects. I already have it working with 9 3D textures so far for the first 9 SH functions.
In my GLSL shader, I have to send in 9 SH Coefficient 3D Texures that use RGBA8 as a pixel format. RGB being used for the coefficients for red, green, and blue, and the A for checking if the voxel is in use (for the 3D texture solidification shader to prevent bleeding).
My problem is, I want to knock this number of textures down to something like 4 or 5. Getting even lower would be a godsend. This is because I eventually plan on adding more SH Coefficient 3D Textures for other parts of the game map (such as inside rooms, as opposed to the outside), to circumvent irradiance probe bleeding between rooms separated by walls. I don't want to reach the 32 texture limit too soon. Also, I figure that it would be a LOT faster.
Is there a way I could, say, store 2 sets of SH Coefficients for 2 SH functions inside a texture with RGBA16 pixels? If so, how would I extract them from inside GLSL? Let me know if you have any suggestions ^^.
• By KarimIO
EDIT: I thought this was restricted to Attribute-Created GL contexts, but it isn't, so I rewrote the post.
Hey guys, whenever I call SwapBuffers(hDC), I get a crash, and I get a "Too many posts were made to a semaphore." from Windows as I call SwapBuffers. What could be the cause of this?
Update: No crash occurs if I don't draw, just clear and swap.
static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 32, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 24, // 24Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; if (!(hDC = GetDC(windowHandle))) return false; unsigned int PixelFormat; if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) return false; if (!SetPixelFormat(hDC, PixelFormat, &pfd)) return false; hRC = wglCreateContext(hDC); if (!hRC) { std::cout << "wglCreateContext Failed!\n"; return false; } if (wglMakeCurrent(hDC, hRC) == NULL) { std::cout << "Make Context Current Second Failed!\n"; return false; } ... // OGL Buffer Initialization glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glBindVertexArray(vao); glUseProgram(myprogram); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, (void *)indexStart); SwapBuffers(GetDC(window_handle));
• By Tchom
Hey devs!

I've been working on a OpenGL ES 2.0 android engine and I have begun implementing some simple (point) lighting. I had something fairly simple working, so I tried to get fancy and added color-tinting light. And it works great... with only one or two lights. Any more than that, the application drops about 15 frames per light added (my ideal is at least 4 or 5). I know implementing lighting is expensive, I just didn't think it was that expensive. I'm fairly new to the world of OpenGL and GLSL, so there is a good chance I've written some crappy shader code. If anyone had any feedback or tips on how I can optimize this code, please let me know.

uniform mat4 u_MVPMatrix; uniform mat4 u_MVMatrix; attribute vec4 a_Position; attribute vec3 a_Normal; attribute vec2 a_TexCoordinate; varying vec3 v_Position; varying vec3 v_Normal; varying vec2 v_TexCoordinate; void main() { v_Position = vec3(u_MVMatrix * a_Position); v_TexCoordinate = a_TexCoordinate; v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0)); gl_Position = u_MVPMatrix * a_Position; } Fragment Shader
precision mediump float; uniform vec4 u_LightPos["+numLights+"]; uniform vec4 u_LightColours["+numLights+"]; uniform float u_LightPower["+numLights+"]; uniform sampler2D u_Texture; varying vec3 v_Position; varying vec3 v_Normal; varying vec2 v_TexCoordinate; void main() { gl_FragColor = (texture2D(u_Texture, v_TexCoordinate)); float diffuse = 0.0; vec4 colourSum = vec4(1.0); for (int i = 0; i < "+numLights+"; i++) { vec3 toPointLight = vec3(u_LightPos[i]); float distance = length(toPointLight - v_Position); vec3 lightVector = normalize(toPointLight - v_Position); float diffuseDiff = 0.0; // The diffuse difference contributed from current light diffuseDiff = max(dot(v_Normal, lightVector), 0.0); diffuseDiff = diffuseDiff * (1.0 / (1.0 + ((1.0-u_LightPower[i])* distance * distance))); //Determine attenuatio diffuse += diffuseDiff; gl_FragColor.rgb *= vec3(1.0) / ((vec3(1.0) + ((vec3(1.0) - vec3(u_LightColours[i]))*diffuseDiff))); //The expensive part } diffuse += 0.1; //Add ambient light gl_FragColor.rgb *= diffuse; } Am I making any rookie mistakes? Or am I just being unrealistic about what I can do? Thanks in advance
• By yahiko00
Hi,
Not sure to post at the right place, if not, please forgive me...
For a game project I am working on, I would like to implement a 2D starfield as a background.
I do not want to deal with static tiles, since I plan to slowly animate the starfield. So, I am trying to figure out how to generate a random starfield for the entire map.
I feel that using a uniform distribution for the stars will not do the trick. Instead I would like something similar to the screenshot below, taken from the game Star Wars: Empire At War (all credits to Lucasfilm, Disney, and so on...).

Is there someone who could have an idea of a distribution which could result in such a starfield?
Any insight would be appreciated

• 9
• 10
• 20
• 11
• 28