OpenGL version to start with (as of late 2014) - c++

I know nothing about OpenGL, but it turns out it might be needed for something that I'm working on (figured this out simply because I want some visual effects that need fast drawing - hardware accelerated).
So I'm very much troubled about which version of OpenGL to start coding for as of the current date? (September 2014 for future readers).
As of now, I have read OpenGL 3.x is the most available (read as: supported) version, even on very old hardware (i.e. designed for Windows XP). But, what if I develop for OpenGL 4.x, will my application be backward-compatible with 3.x supported hardware? Or does it just break there and only run on 4.x (and future?) supported hardware?
My use of OpenGL is not for a videogame or anything similar so I might never need advanced functionality (as of now I can't name any to give you an example of what I may never use, I hope experienced OpenGL people will understand my point). However, I don't think this is going to lower in any way the driver support required, am I right?
Please note that I might have used the wrong terminology and I want to start learning OpenGL which puts me in a position not so good to understand whether I might need this or that feature and/or possible requirements - I am in the need of real advice to get started and figure my way out.

I'm sure this answer skips many many details and exceptions (so take with salt and if you disagree or have something to add, leave a comment :P), but... Each OpenGL version mostly just adds features, so if you start using a new features it might limit the hardware you can run your app on (and so the question attracted a downvote, when instead it should have attracted an explanation).
Basic drawing pretty much remains a constant, with one very big exception: all the stuff that was deprecated in version 3 and removed in 3.1.
Old, < GL 3:
We used to be able to do things like:
glEnable(GL_LIGHTING); //fixed-pipeline lighting. replaced with shaders
glEnable(GL_TEXTURE_2D); //fixed texturing
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(...); //builtin matrices
glBegin(GL_TRIANGLES); glVertex3f(...) ...; glEnd(); //immediate mode with per-vertex calls
glVertexPointer(..., myArray); glDrawArrays(...); //immediate mode with client side array
But even then we still had GLSL shaders and VBOs. There's a fair amount of overlap and the GL3 deprecation didn't instantly replace everything:
glBufferData(...); //buffer mesh data to bound VBO
...
glVertexAttribPointer(...); //attach data to myCustomVar (either VBO or immediate mode local array)
...
attribute vec3 myCustomVar;
varying vec3 myVarying;
...
gl_Position = gl_ProjectionMatrix * gl_ModelviewMatrix * gl_Vertex;
...
gl_FragColor = vec4(1, 0, 0, 1);
New, >= GL 3:
The new way of drawing removes immediate mode and a lot of these in-built features so you do a lot from scratch, adds a few features and syntax changes. You have to use VBOs and shaders:
glBufferData(...); //buffer mesh data
...
glVertexAttribPointer(...); //attach VBOs, but have to set your own position etc too
...
#version 150 //set GLSL version number
out vec3 myVarying; //replaces "varying"
gl_Position = myProjection * myModelview * myPosition;
...
in vec3 myVarying;
out vec4 fragColour; //have to define your own fragment shader output
...
fragColour = vec4(1, 0, 0, 1);
To answer your question, and this is completely my opinion, I'd start learning GLES2.0 (afaik pretty much a subset of GL3) because it's so well supported right now. GL2/immediate mode certainly doesn't hurt as a learning step, and there's still quite a lot that isn't deprecated. You can always just use GL 4 features if you find you need them, but as said the basics really only changed between the above versions. Even if you use deprecated features you have to go out of your way to get a pure GL3.2 (for example) context that disallows certain calls/features. I'm not advocating it but it's entirely possible to mix very old with very new and most drivers seem to allow it.
TLDR: 1. use VBOs, 2. use shaders. Just for learning, don't bother with an explicit version context.
See Also:
http://www.opengl.org/wiki/History_of_OpenGL
http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts
List of deprecated OpenGL functionalities

Related

OpenGL - Fixed pipeline shader defaults (Mimic fixed pipeline with shaders)

Can anyone provide me the shader that are similar to the Fixed function Pipeline?
I need the Fragment shader default the most, because I found a similar vertex shader online. But if you have a pair that should be fine!
I want to use fixed pipeline, but have the flexability of shaders, so I need similar shaders so I'll be able to mimic the functionality of the fixed pipeline.
Thank you very much!
I'm new here so if you need more information tell me:D
This is what I would like to replicate: (texture unit 0)
functionality of glTranslatef
functionality of glColor4f
functionality of glTexCoord2f
functionality of glVertex2f
functionality of glOrtho (I know it does some magic stuff behind the scenes with the shader)
Thats it. That is all the functionality I would like to replicate form the fixed function pipeline. Can anyone show me an example of how to replicate those things with shaders?
You have a couple of issues here that will make implementing this using shaders more difficult.
First and foremost, in addition to using fixed-function features you are also using immediate mode. Before you can make the transition to shaders, you should switch to vertex arrays. You could write a class that takes immediate mode-like commands that would come between glBegin (...) and glEnd (...) and pushes them into a vertex array if you absolutely need to structure your software this way.
As for glTranslatef (...) and glOrtho (...) these are nothing particularly special. They create translation matrices and orthographic projection matrices and multiply the "current" matrix by this. It is unclear what language you are using, but one possible replacement for these functions could come from using a library like glm (C++).
The biggest obstacle will be getting rid of the "current" state mentality that comes with thinking in terms of the fixed-function pipeline. With shaders you have full control over just about every state, and you don't have to use functions that multiply the "current" matrix or set the "current" color. You can simply pass the exact matrix or color value that you need to your shader. This is an altogether better way of approaching these problems, and is why I honestly think you should ditch the fixed-function approach altogether instead of trying to emulate it.
This is why your desire to "use the fixed-function pipeline but have the flexibility of shaders" fundamentally makes very little sense.
Having said all that, in OpenGL compatibility mode, there are reserved words in GLSL that refer to many of the fixed-function constructs. These include things like gl_MultiTexCoord<N>, gl_ModelViewProjectionMatrix, etc. They can be used as a transitional aid, but really should not be relied upon in the long run.
Se also this question: OpenGL Fixed function shader implementation where they point to a few web resources.
The OpenGL ES 2 book contains an implementation of the OpenGL ES 1.1 fixed function pipeline in Chapter 8 (vertex shader) and Chapter 10 (fragment shader).
Unfortunately, these shaders seem to not be included in the book's sample code. On the other hand, reading the book and typing the code is certainly worthwile.

Why does OpenGL drawing fail when vertex attrib array zero is disabled?

I was having extreme trouble getting a vertex shader of mine to run under OpenGL 3.3 core on an ATI driver:
#version 150
uniform mat4 graph_matrix, view_matrix, proj_matrix;
uniform bool align_origin;
attribute vec2 graph_position;
attribute vec2 screen_position;
attribute vec2 texcoord0;
attribute vec4 color;
varying vec2 texcoord0_px;
varying vec4 color_px;
void main() {
// Pick the position or the annotation position
vec2 pos = graph_position;
// Transform the coordinates
pos = vec2(graph_matrix * vec4(pos, 0.0, 1.0));
if( align_origin )
pos = floor(pos + vec2(0.5, 0.5)) + vec2(0.5, 0.5);
gl_Position = proj_matrix * view_matrix * vec4(pos + screen_position, 0.0, 1.0);
texcoord0_px = texcoord0;
color_px = color;
}
I used glVertexAttrib4f to specify the color attribute, and turned the attribute array off. According to page 33 of the 3.3 core spec, that should work:
If an array corresponding to a generic attribute required by a vertex shader is not enabled, then the corresponding element is taken from the current generic attribute state (see section 2.7).
But (most of the time, depending on the profile and driver) the shader either didn't run at all or used black if I accessed the disabled color attribute. Replacing it with a constant got it to run.
Much searching yielded this page of tips regarding WebGL, which had the following to say:
Always have vertex attrib 0 array enabled. If you draw with vertex attrib 0 array disabled, you will force the browser to do complicated emulation when running on desktop OpenGL (e.g. on Mac OSX). This is because in desktop OpenGL, nothing gets drawn if vertex attrib 0 is not array-enabled. You can use bindAttribLocation() to force a vertex attribute to use location 0, and use enableVertexAttribArray() to make it array-enabled.
Sure enough, not only was the color attribute assigned to index zero, but if I force-bound a different, array-enabled attribute to zero, the code ran and produced the right color.
I can't find any other mention of this rule anywhere, and certainly not on ATI hardware. Does anyone know where this rule comes from? Or is this a bug in the implementation that the Mozilla folks noticed and warned about?
tl;dr: this is a driver bug. Core OpenGL 3.3 should allow you to not use attribute 0, but the compatibility profile does not, and some drivers don't implement that switch correctly. Just make sure to use attribute 0 to avoid any problems.
Actual Content:
Let's have a little history lesson in how the OpenGL specification came to be.
In the most ancient days of OpenGL, there was exactly one way to render: immediate mode (ie: glBegin/glVertex/glColor/glEtc/glEnd). Display lists existed, but they were always defined as simply sending the captured commands again. So while implementations didn't actually make all of those function calls, implementations would still behave as if they did.
In OpenGL 1.1, client-side vertex arrays were added to the specification. Now remember: the specification is a document that specifies behavior, not implementation. Therefore, the ARB simply defined that client-side arrays worked exactly like making immediate mode calls, using the appropriate accesses to the current array pointers. Obviously implementations wouldn't actually do that, but they behaved as if they did.
Buffer-object-based vertex arrays were defined in the same way, though with language slightly complicated by pulling from server storage instead of client storage.
Then something happened: ARB_vertex_program (not ARB_vertex_shader. I'm talking about assembly programs).
See, once you have shaders, you want to start being able to define your own attributes instead of using the built-in ones. And that all made sense. However, there was one problem.
Immedate mode works like this:
glBegin(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glTexCoord(...);
glColor(...);
glVertex(...);
glEnd();
Every time you call glVertex, this causes all of the current attribute state to be used for a single vertex. All of the other immediate mode functions simply set values into the context; this function actually sends the vertex to OpenGL to be processed. That's very important in immediate mode. And since every vertex must have a position in fixed-function land, it made sense to use this function to decide when a vertex should be processed.
Once you're no longer using OpenGL's fixed-function vertex semantics, you have a problem in immediate mode. Namely, how do you decide when to actually send the vertex?
By convention, they stuck this onto attribute 0. Therefore, all immediate mode rendering must use either attribute 0 or glVertex to send a vertex.
However, because all other rendering is based on the language of immediate mode rendering, all other rendering has the same limitations of immediate mode rendering. Immediate mode requires attribute 0 or glVertex, and therefore so too do client-side arrays and so forth. Even though it doesn't make sense for them to, they need it because of how the specification defines their behavior.
Then OpenGL 3.0 came around. They deprecated immediate mode. Deprecated does not mean removed; the specification still had those functions in it, and all vertex array rendering was still defined in terms of them.
OpenGL 3.1 actually ripped out the old stuff. And that posed a bit of a language problem. After all, every array drawing command was always defined in terms of immediate mode. But once immediate mode no longer exists... how do you define it?
So they had to come up with new language for core OpenGL 3.1+. While doing so, they removed the pointless restriction on needing to use attribute 0.
But the compatibility profile did not.
Therefore, the rules for OpenGL 3.2+ is this. If you have a core OpenGL profile, then you do not have to use attribute 0. If you have a compatibility OpenGL profile, you must use attribute 0 (or glVertex). That's what the specification says.
But that's not what implementations implement.
In general, NVIDIA never cared much for the "must use attribute 0" rule and just does it how you would expect, even in compatibility profiles. Thus violating the letter of the specification. AMD is generally more likely to stick to the specification. However, they forgot to implement the core behavior correctly. So NVIDIA's too permissive on compatibility, and AMD is too restrictive on core.
To work around these driver bugs, simply always use attribute 0.
BTW, if you're wondering, NVIDIA won. In OpenGL 4.3, the compatibility profile uses the same wording for its array rendering commands as core. Thus, you're allowed to not use attribute 0 on both core and compatibility.

Fixed-Function Vs. Shaders - help understand the conceptual differences

My background: I first started experimenting with OpenGL some months ago, for no particular purpose, just fun. I started reading the OpenGL redbook, and got as far as making a planetary system with a lot of different lighting. That lasted for a month, and my interest for openGL went away. It awoke again a week or so ago, and as I gathered from some SO posts, the redbook is outdated and the OpenGL Superbible is a better source for learning. So I started reading it. I like the concept of shaders but there's a real mess going on in my brain because of transition from my old memories of the fixed pipeline and the new concept of shaders.
Question: I would like to write some statements which I think are true and I am asking OpenGL experts to verify them (i.e. whether I am understanding correctly, not quite correctly or absolutely incorrectly). So...
1) If we don't use any shader program, nothing changes. We have current color, current normal, current transformation matrix, current everything, and as soon as we call glVertex**(...) these current values are taken and the vertex is fed to ... I don't know what. The fact is that it's transformed with the current matrix, the current color and normal are applied to it etc.
2) As soon as we use a shader program, all the above stops working. That is, glColor, glRotate etc. make no sense (Do they?). I mean, glColor still does set the current color, glRotate still multiplies the current matrix by the rotation matrix, but these aren't used at all. Instead, we feed vertex attributes by glVertexAttrib. Which attribute means what is totally dependent on our vertex shader and the in variable binding. We also find ans set the values of the uniforms and then call glVertex and the shader is executed ( I don't know immediately or after glEnd() is called). The actual vertex and fragment processing is done entirely manually in the shader program.
3) Shaders don't add anything to depth testing. That is, I don't need to take care of it in a shader. I just call glEnable(GL_DEPTH_TEST). Neither is face culling affected.
4) Alpha blending and antialiasing need not be taken care of in shaders. glEnable calls will suffice.
5) Is it a good idea to use gluPerspective, glRotate, glPushMatrix and other matrix functions, and then retrieve the current matrix and feed it as a uniform to a shader? Thus there won't be any need in using a 3rd party matrix library.
It depends on what version of OpenGL you're talking about. Up through OpenGL 3.0, all the fixed functionality is still present, so yes, if you decide to just use fixed functionality it continues to work like it always did. Starting from 3.0, quite a bit of the fixed pipeline was deprecated, and as of 3.1 it disappears completely. Using these, you no longer really have the option to just use the fixed pipeline.
Again, it depends. For example, up through OpenGL 3.0, glColor is still supported, even when you use a shader. The difference is that instead of automatically being applied to what gets drawn, it's supplied to your shader, which can use it unchanged, modify it as it sees fit, or ignore it completely. So, your fragment shader receives gl_FrontColor and gl_BackColor, and writes the actual fragment color to gl_FragColor. If you're using OpenGL 3.1 or newer, however, glColor (for example) just no longer exists -- a color will be just another value you supply to your shader like you could/would anything else.
That's correct, at least up to OpenGL 3.1. As of 4.0, there's a new compute shader that (I believe) can get involved in things like depth testing (but I haven't used it, so I'm a bit uncertain about that).
Yes, you can still use built-in alpha blending. Depending on your hardware, you may also want to consider using the gl_ARB_draw_buffers_blend extension (which is mandatory as of OpenGL 4, if I recall correctly).
Yet again, it depends on the version of OpenGL you're talking about. Current OpenGL completely eliminates all support for matrices so you have no choice but to use some other matrix library. Older versions supplied things like gl_ModelViewMatrix and gl_NormalMatrix to your shader as a uniform so you could go that route if you chose.
2) In modern OpenGL, there is no glColor, glBegin, glVertex, glRotate etc. so they don't make sense.
5) In modern OpenGL there are no built-in matrices, so you have to use a 3rd party library or write your own. So to answer your question, no, it's not a good idea.

GLSL dynamically indexed arrays

I've been using DirectX (with XNA) for a while now, and have recently switched to OpenGL. I'm really loving it, but one thing has got me annoyed.
I've been trying to implement something that requires dynamic indexing in the vertex shader, but I've been told that this requires the equivilant of SM 4.0. However I know that this works in DX even with SM 2.0, possibly even 1.0. XNA's instancing sample uses this to do instancing on SM2.0 only cards http://create.msdn.com/en-US/education/catalog/sample/mesh_instancing.
The compiler can't have been "unrolling" it into a giant list of if statements, since this would surely exceed the instruction limit on SM2 for our 250 instances.
So is DX doing some trickery that I can't do with OpenGL, can I manipulate OpenGL to do the same, or is it a hardware feature that OpenGL doesn't expose?
You can upload an array for your light directions with something like glUniform3fv, then (assuming I understand what you're trying to do correctly) you just need your vertex format to include an index into this array (so there be lots of duplication of these indices if the index only changes once per mesh or something). If you don't already know, you can use glGetAttribLocation + glVertexAttribPointer to send arbitrary vertex attributes like this to the shader (as opposed to using the deprecated built-in attributes like gl_Vertex, gl_Normal, etc).
From your link:
Note that there is no single perfect
instancing technique. This must be
implemented in a different way on
Windows compared to Xbox 360, and on
Windows the ideal technique requires
shader 3.0, but there is also a
fallback approach that will work with
shader 2.0. This sample implements
several different instancing
techniques, so it can work on both
platforms and shader versions.
Not the emboldened part. So ont hat basis you should be able to do similar instancing on shader model 3. Shader model 2's instancing is usually performed using a matrix palette. It sumply means you can render multiple meshes in one call by uploading a load of transformation matrices in one go. This reduces draw calls and improves speed.
Anyway for OpenGL there was a lot of troubles finalising this extension and hence you need shader 4. You CAN, however, still stick a per vertex matrix palette index in yoru vertex structure and do matrix palette rendering using a shader...

OpenGL 3.1-4.1 new and deprecated features

I've been working with OpenGL for about a year now, and have learned a lot of stuff. Unfortunatly the way I learned it was the old pre 3.x way, meaning immediate mode, default shaders, matrix stacks, etc. I more or less have an idea of what has changed from then to now by looking at the OpenGL specs, however I don't totally understand some of the new ways to do things.
From my understanding they got rid of matrix stacks, meaning you have to keep track of your own transformation matrices, which doesn't seem too complicated. They also got rid of immediate mode, meaning you now need to use VBOs or VAOs (never know which one, maybe both..) to send the pixel/normal/texture,etc. information to the shader program. I don't really get the way these objects works, I think you need to put all the info into them, and provide an ofset of some sort to show the separators between pixel,normal and texture coordinates. Could someone briefly explain how this actually works (or send me a link which explains it)? I tried wikipedia and googling it, but found myself still not quite understanding them.
Another point I would like to know more about are shaders, as I've never used them. I'm not going to ask how to code them or anything, just what needs to go in there and what opengl still does for you. More specifically, what would you need to do in the shaders to get a basic rendering program? I know you need to do all the ligthing calculations and use your matrices to calculate the real vertex position. But does opengl still take care of backface culling, line clipping, polygon filling and other lower level issues, or do you have to code them yourslef into the shaders (or don't they even belong in the shaders)?
Since immediate mode is deprecated doing a "hello triangle" application is a bit more involved. There is a good tutorial on modern OpenGL here:
http://arcsynthesis.org/gltut/
You should read it thoroughly. Bear in mind that it doesn't use VAOs so you'll have to read about it somewhere else afterwards. VAOs don't change things much so you won't have to unlearn things from mentioned tutorial to use them.
And about your second question... Your vertex shader will be executed by OpenGL for every vertex. Your job is to calculate final position of the vertex and prepare data (like normals, light data...) to be sent to fragment shader, given the attributes of vertex and other data you send to shader (uniforms - you'll read about it in tutorial). Fragment shader will be executed per fragment and in fragment shader you are calculating the final color of each fragment.
You can see here:
http://www.opengl.org/sdk/docs/man4/
that things like, glPolygonMode and glCullFace are still there.