Matrix stacks in OpenGL deprecated? - opengl

I just read this:
"OpenGL provided support
for managing coordinate transformations and projections using the standard matrix stacks
(GL_MODELVIEW and GL_PROJECTION). In core OpenGL 4.0, however, all of the functionality
supporting the matrix stacks has been removed. Therefore, it is up to us to provide our own
support for the usual transformation and projection matrices, and then to pass them into our
shaders."
This is strange, so how do I set the modelview and projection matrices now? I should create
them in the opengl app and then multiply the vertices in the vertex shader with the matrices?

This is strange
Nope. Fixed function was replaced by programmable pipeline that lets you design your transformations however you want.
I should create them in the opengl app and then multiply the vertices in the vertex shader with the matrices?
If you want to have something that would work just like the old OpenGL pair of matrix stacks, then you'd want to make your vertex shader look, for instance, like:
in vec4 vertexPosition;
// ...
uniform mat4 ModelView, Projection;
void main() {
gl_Position = Projection * ModelView * vertexPosition;
// ...
}
(You can optimise that a bit, of course)
And the corresponding client-size code (shown as C++ here) would be like:
std::stack<Matrix4x4> modelViewStack;
std::stack<Matrix4x4> projectionStack;
// Initialize them by
modelViewStack.push(Matrix4x4.Identity());
projectionStack.push(Matrix4x4.Identity());
// glPushMatrix:
stack.push(stack.top());
// `stack` is either one stack or the other;
// in old OpenGL you switched the affected stack by glMatrixMode
// glPopMatrix:
stack.pop();
// glTranslate and family:
stack.top().translate(1,0,0);
// And in order to pass the topmost ModelView matrix to a shader program:
GLint modelViewLocation = glGetUniformLocation(aLinkedProgramObject,
"ModelView");
glUniformMatrix4fv(modelViewLocation, 1, false, &modelViewStack.top());
I've assumed here that you have a Matrix4x4 class that supports operations like .translate(). A library like GLM can provide you with client-side implementations of matrices and vectors that behave like corresponding GLSL types, as well as implementations of functions like gluPerspective.
You can also keep using the OpenGL 1 functionality through the OpenGL compatibility profile, but that's not recommended (you won't be using OpenGL's full potential then).
OpenGL 3 (and 4)'s interface is more low level than OpenGL 1; If you consider the above to be too much code, then chances are you're better off with a rendering engine, like Irrlicht.

The matrix stack is part of the fixed function pipeline which is deprecated. You still can access the old functionality over the compatibility extension but you should avoid to do this.
There are some good tutorials on matrices and cameras but I prefer this one. Send your matrix to the shader and multiply, as you said, the vertices with the matrix.

Related

Permanently move vertices using vertex shader GLSL

I am leaning GLSL and in general some OpenGL and I am having some trouble with vertex movement and management.
I am good with camera rotations and translation but now I need to move a few vertices and have them stay in their new positions.
What I would like to do is move them using the vertex shader but also not keep track of their new positions trough matrices (as I need to move them around independently and it would be very pricey in terms of memory and computing power to store that many matrices).
If there were a way to change their position values in the VBO directly from the vertex shader, that would be optimal.
Is there a way to do that? What other ways do you suggest?
Thanks in advance.
PS I am using GLSL version 1.30
While it's possible to write values from a shader into a buffer and later read it from the CPU-client side (i.e., by using glReadPixels()) I don't think it is your case.
You can move a group of vertices, all with the same movement, with a single matrix. Why don't you do it with the CPU and store the results, updating their gl-buffer when needed? (VAO remains unchanged if you just update the glBuffer) Once they are moved, you don't need that matrix anymore, right? Or if you want to undo the movement, then, yes, yo need to store also the matrix.
It seems that transform feedback is exactly what you need.
What I would like to do is move them using the vertex shader but also not keep track of their new positions trough matrices
If I understand you correctly then what you want is to send some vertices to the GPU. Then having the vertex shader moving them. You can't because a vertex shader is only able to read from the vertex buffer, it isn't able to write back to it.
it would be very pricey in terms of memory and computing power to store that many matrices.
Considering:
I am good with camera rotations and translation
Then in wouldn't be expensive at all. Considering that you already have a view and projection matrix for the camera and viewport. Then having a model matrix contain the translation, rotation and scaling of each object isn't anywhere near a bottleneck.
In the vertex shader you'd simply have:
uniform mat4 mvp; // model view projection matrix
...
gl_Position = mvp * vec4(position, 1.0);
On the CPU side of things you'd do:
mvp = projection * view * model;
GLint mvpLocation​ = glGetUniformLocation(shaderGeometryPass, "mvp")
glUniformMatrix4fv(mvpLocation, 1, GL_FALSE, (const GLfloat*)&mvp);
If this gives you performance issues then the problem lies elsewhere.
If you really want to "save" which ever changes you make on the GPU side of things, then you'd have to look into Shader Storage Buffer Object and/or Transform Feedback

Adjusting the distortion caused by a projector in OpenGL ES

I'm getting started with a OpenGL ES app (C++/SDL) running on a Raspberry PI, that I'll want to output through a pocket projector.
I want to give the user the ability to correct the distortion caused by aiming the projector from a direction that is non-normal to the surface. The surface will also be smaller than the projected area. To do this, the user will be able to "move" the 4 corners of the projection window independently to match the surface.
I was planning to do this by solving a simple linear system of equations that transforms the original corners (in the current projection matrix coordinates) to the corners set by the user, and just push this resulting matrix on top of the GL_PROJECTION matrix stack.
However... I found out that I can't "read" the projection matrix in OpenGL ES:
float matrix[16];
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
In particular, the GL_PROJECTION_MATRIX symbol doesn't exist... and I've even read that there's no such thing as a projection matrix in OpenGL ES (something I find hard to believe, but I'm totally new to it, so...).
Any idea of a workaround for reading this matrix, or maybe an alternative approach to do what I'm trying to do?
Thanks!
OpenGL ES 1.x has a projection matrix, and you should be able to get the current value with exactly the code you have in your question. See http://www.khronos.org/opengles/sdk/1.1/docs/man/glGet.xml for the documentation confirming this, or the header file at http://www.khronos.org/registry/gles/api/GLES/gl.h.
ES 2.0 and higher are a different story. ES 2.0 eliminates most of the fixed pipeline that was present in ES 1.x, and replaces it with shader based rendering.
Therefore, concepts like a built-in projection matrix don't exist anymore in ES 2.0 and are replaced with the much more flexible concept of shader programs written in GLSL. If you want to use a projection matrix in ES 2.0, you have a matrix variable in your vertex shader code, pass a value for the matrix into the shader program (using the glUniformMatrix4fv API call), and the GLSL code you provide for the vertex shader performs the multiplication of vectors with the projection matrix.
So in the case of ES 2.0, there is no need for a glGet*() call for the projection matrix. If you have one, you calculated it, and passed it into the shader program. Which means that you already have the matrix in your code. Well, you could get any matrix value back with the glGetUniformfv() API call, but it's much easier and cleaner to just keep it around in your code.

How to move from model space to orthographic view in OpenGL 3.0+?

I've recently completed some examples in OpenGL which resulted in me drawing some triangles in the space -1 >= x <= 1, -1 >= y <= 1. What do I need to do to move to an orthographic view? What transforms do I need to perform? I'm assuming the resulting transform will be set into the vertex shader as a uniform variable, then applied to any incoming vertices.
Is it wise to use pixels as the scale of the view (i.e. 1024x768) or to use logical units (pixels x1000 for example)?
What do I need to do to move to an orthographic view? What transforms do I need to perform?
You must apply a orthographic projection. Note that the identity transform you used so far is already orthographic.
It's a good idea to decompose the transformation process into projection and modelview transformations. Each is described by a 4×4 matrix, which, you a right, are passed as uniforms to the vertex shader.
The typical vertex shader layout looks like
#version 120 /* or something later */
attribute vec4 position;
uniform mat4 proj;
uniform mat4 mv;
varying vec4 vert_pos; // for later versions of GLSL replace 'varying' with 'out'
void main()
{
// order matters, matrix multiplication is not
vert_pos = proj * mv * position; commutative */
}
The projection matrix itself must be supplied by you. You can either look at older fixed function OpenGL specifications to see how they're implemented. Or you use some ready to use graphics math library, like →GLM or (self advertisement) →linmath.h
Update due to comment
The modelview transform is used to set the point of view and the placement of geometry drawn into the scene. In general the modelview usually differs for each model drawn. Modelview itself can be decomposed into model and view. The view is what some people set using some sort of "lookAt" function. And model is the geometry placement part.
The projection is kind of the "lens" of OpenGL and what's responsible for the "ortho" or "perspective" or whatever look.
Like stated above the specific projection to be used is user defined, but usually follows the typical transformation matrices like found in older OpenGL specifications or in graphics math libraries. Just look at some older specification of OpenGL (say OpenGL-1.5 or so) for the definition of ortho and frustum matrices (they can be found for the fixed functions glOrtho and glFrustum).

How do I retrieve the ModelView matrix in GLSL 1.5?

I have been reading through the specification of openGL 1.5, and saw that any reference to what used to be a variable holding the reference to the ModelView matrix (like gl_ModelViewMatrix) has been deprecated, and is only availble in some kind of compatability mode (which happens not to be supported on my GPU).
I have seen a few examples first retrieving the ModelView matrix or creating one, then sending it back to the GPU as a uniform variable.
Now this all seems just backward to me; even for a simple Vertex Shader you will in many cases want to use some kind of transformation on the geometry.
So I am really wondering now; is there any way to get the current ModelView matrix from within a vertex shader, using GLSL 1.5?
OpenGL-3 core completely dropped the matrix stack, i.e. the built-in modelview, projection, texture and color matrices. It's now expected from you to implement the matrix math and supply the matrices through self chosen uniforms.
There is no built in matrix system/lib in core openGL - since 3.+ version.
A lot of people had similar (bad) opinions about that "huge change" in openGL.
You have to use your own set of functions to perform matrix calculation. See libraries like: GLM or in lighthouse3D.
All in all it was very useful to have matrix functions in OpenGL when learning. Now you have to look for other solutions...
On the other side it is not a problem for game engines or game frameworks that usually have their own math libraries. So for them "new" OpenGL is even easier to use.

Orthographic Projection in Modern OpenGL

I'd like to set up an orthographic projection using only modern OpenGL techniques (i.e. no immediate-mode stuff). I'm seeing conflicting info on the web about how to approach this.
Some people are saying that it's still OK to call glMatrixMode(GL_PROJECTION) and then glOrtho. This has always worked for me in the past, but I'm wondering if this has been deprecated in modern OpenGL.
If so, are vertex shaders the standard way to do an orthographic projection nowadays? Does GLSL provide a handy built-in function to set up an orthographic projection, or do I need to write that math myself in the vertex shader?
If so, are vertex shaders the standard way to do an orthographic projection nowadays?
Not quite. Vertex shaders perform the calculations, but the transformation matrices are usually fed into the shader through a uniform. A shader should only evaluate things, that vary with each vertex. Implementing a "ortho" function, the returns a projection matrix in GLSL is counterproductive.
I'd like to set up an orthographic projection using only modern OpenGL techniques (i.e. no immediate-mode stuff). I'm seeing conflicting info on the web about how to approach this.
The matrix stack of OpenGL before version 3 has nothing to do with the immediate mode. Immediate mode was glBegin(…); for(…){ ...; glVertex(…);} glEnd(). And up to OpenGL version 3 is was rather common to use the matrices specified through the matrix stack in a vertex shader.
With OpenGL-3 it was aimed to do, what was originally planned for OpenGL-2: A unification of the API and removing old cruft. One of those things removed was the matrix stack. Many shaders already used more than the standard matrices already, anyway (like for example for skeletal animation), so matrices already had been passed as uniforms and the programs did already contain the whole matrix math code. Taking the step of remocing the matrix math stuff from OpenGL-3 was just the next logical step.
In general, you do not compute matrices in shaders. You compute them on the CPU and upload them as uniforms to the shaders. So your vertex shader would neither know nor care if it is for an orthographic projection or a perspective one. It just transforms by whatever projection matrix it is given.
When you target an OpenGL version > 3.0, glOrtho has been removed from the official specs (but still is present in the compatability profile), so you shouldn't use it anymore. Therefore, you will have to calculate the projection you want to use directly within the vertex shader
(for OpenGL up to 3.0 glOrtho is perfectly ok ;).
And no there is no "handy" function to get the projection matrix in GLSL, so you have to specify it yourself. This is, however, no problem, as there is a) plenty of example code in the web and b) the equations are right in the OpenGL spec, so you can take it simply from there if you want to.