views:

94

answers:

3

This might sound lazy at first, but I've been researching it for 2 days.

I have an SDL+GLEW app that draws a primitive. I wanted to make a few viewports in different perspectives. I see the four viewports but I can't change the the perspectives.

Assume you have

draw();
swapbuffers();

What is the simplest way - in OpenGL3+ spec - to create a perspective viewport (or ideally several ones)?

+3  A: 

The simplest is the only way. Calculate yourself (with some lib, plain math, etc) a projection matrix, and upload it to a uniform in your vertex shader, and do the transformation there.

Matias Valdenegro
Reluctantly accepted since I assumed a more detailed answer; but technically correct.
Lela Dax
@Lela You could have requested a more detailed answer, i will provide one later.
Matias Valdenegro
I don't need it urgently anymore but it might help the site I guess.
Lela Dax
+2  A: 

For perspective matrix: gluPerspective, then glGetFLoatv(GL_PROJECTION_MATRIX, ...), then glUniform or glUniformMatrix4fv

For viewports: glViewport and glScissor. Or use framebuffer object, render to texture, then render texture.

P.S. If you don't want to use deprecated features, grab matrix formula from gluPerspective documentation, calculate matrix yourself, then use glUniformMatrix4fv. Or work in compatibility profile.

SigTerm
Just a headsup. Using gluPerspective assumes the use of the matrix stack, which is deprecated. The context of the question was to avoid the use of deprecated features. Better calculate the matrix values manually, and then use glUniformMatrix4fv
Mads Elvheim
@Mads Elvheim: "which is deprecated" so, they deprecated matrix stack, but hadn't provided replacement math functions? Great.
SigTerm
@SigTerm: No, why should they have? This was the reason for removing the functionality in the first place. It's a few lines of code. OpenGL is a bare bone low-level library for rendering. Any non-trivial program that uses OpenGL most probably has its own functions or classes for linear algebra anyway. OpenGL was never meant to be a utility library. It was meant to be fast (for graphics). OpenGL 3.1 and later remedied this.
Mads Elvheim
@Mads Elvheim: "No, why should they have?" I just don't think it is a good idea. The beauty of those deprecated functions is that everybody could use opengl with almost zero math background. I.e. you could quickly make program that draw hierarchical structures graphs, primitive engine, operating on simple terms like "move/rotate". Without deprecated matrix functions API just looks weird. For example, DirectX has D3DX (math/vector functions) that is used by many people, and it looks like OGL has nothing similar. Which means there will be many competing "OGL math libraries". Oh well, whatever.
SigTerm
DirectX is a whole game framework. OpenGL is a platform-agnostic library only used for rendering. You're not alone with your opinion regarding the deprecation (and later removal) of the fixed-function pipeline however. I guess there are two camps of thought. One side wants OpenGL to be feature rich with a lot of helper functions. The other camp wants a clean, small and efficient library which can be demanding on people with little background in computer graphics.
Mads Elvheim
@Mads Elveim: Can't say that I want OpenGL to be extremely feature rich, but deprecated functions like glPushMatrix/glVertex were certainly useful for quick graphic tests and visual debugging, because to draw things this way in DirectX(9) you had to implement a layer that would provide that functionality by using dynamic primitive buffers, which was pain. Also, it makes sense to have "official" math library bundled with 3D api (although I can write my library). Anyway, thanks for headsup - hadn't noticed (in the 3.0 spec) that the stack was deprecaeted.
SigTerm
OpenGL 3.0 is old already. Everything deprecated in OpenGL 3.0 (except line thickness) was removed in 3.1, and added to a separate extension, GL_ARB_compatibility. So it's not a part of the core spec anymore. The latest version is 4.1. OpenGL 3.3 was released as an intermediate version for hardware that don't have DirectX11 features, so 3.3 is the last version for DirectX10(.1) hardware.
Mads Elvheim
+1  A: 

Here's GLSL 1.50 code for doing the same thing as gluPerspective. You can easily convert it to your language of choice, and upload it via glUniformMatrix4fv instead.

mat4 CreatePerspectiveMatrix(in float fov, in float aspect,
    in float near, in float far)
{
    mat4 m = mat4(0.0);

    float angle = (fov / 180.0f) * PI;
    float f = 1.0f / tan( angle * 0.5f );

    /* Note, matrices are accessed like 2D arrays in C.
       They are column major, i.e m[y][x] */

    m[0][0] = f / aspect;
    m[1][1] = f;
    m[2][2] = (far + near) / (near - far);
    m[2][3] = -1.0f;
    m[3][2] = (2.0f * far*near) / (near - far);

    return m;
}

Then you do:

mat4 worldMatrix = CreateSomeWorldMatrix();
mat4 clipMatrix = CreatePerspectiveMatrix(90.0, 4.0/3.0, 1.0, 128.0);

gl_Position = worldMatrix * clipMatrix * myvertex;
some_varying1 = worldMatrix * myvertex; 
some_varying2 = worldMatrix * vec4(mynormal.xyz, 0.0);
Mads Elvheim