Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

880105 Posts in 33021 Topics- by 24387 Members - Latest Member: OPNitro

May 25, 2013, 07:02:39 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Sending vertex coordinates to vertex shaders
Pages: [1]
Print
Author Topic: Sending vertex coordinates to vertex shaders  (Read 1748 times)
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« on: January 06, 2011, 07:17:56 AM »

I'm just starting to dig into GLSL, and I have an issue which I can't seem to figure out, and I'm having a lot of trouble finding information.

In the early versions of GLSL, vertex shaders had a predefined variable named gl_Vertex which contained the coordinates of the current vertex, prior to transformation.  This variable has been deprecated from GLSL 1.3 forward.

The examples in the orange book create an in variable to the vertex shader for passing the vertex coordinates.  This seems extremely awkward to me.  Is this really what's going on?

What confuses me more is that OpenGL 3.0 deprecated most of the old pipeline.  Immediate mode glVertex* and display lists as a whole have been deprecated (There goes my font engine...).  The only way to specify vertices that I can find that hasn't been deprecated is glDrawArrays, but since I apparently have to pass the vertex coordinates as an in variable anyway, should I be using that?  What happens to those coordinates?

It seems like I'm missing some key bit of understanding here.  Is there some kind of "OK, start the shaders" functions that I'm overlooking?  The red and orange books seem awfully keen to show shader examples, but client-side code for actually using the damn things is strangely lacking.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
Glaiel-Gamer
Moderator
Level 10
******


Stoleurface!


View Profile WWW Email
« Reply #1 on: January 06, 2011, 08:34:24 AM »

You could just use openGL 2.0 / GLSL 1.2 instead. All the cards still support it and I highly doubt they'll stop anytime soon.

====

just checked wikipedia. As someone who recently had to rewrite 22 shaders from GLSL to nvidia CG, I wish I had originally done them the "new" way, cause it would have made it a lot easier. GLSL seems a little bit odd in the way you specify certain inputs (and looking back I have no idea how half my shaders worked), whereas nvidia CG (and HLSL since they're the same) let you specify certain registers to be associated with your variables (float4 pos : POSITION, float4 texcoordin : TEXCOORD0, etc).

For passing the vertices in, vertex buffer objects are your best bet in any version of opengl. I haven't found a situation where a vertex buffer is slower than a display list, immediate mode, or glDrawArrays.

Code:
Is there some kind of "OK, start the shaders" functions that I'm overlooking?  The red and orange books seem awfully keen to show shader examples, but client-side code for actually using the damn things is strangely lacking.

this was a bit tough to find, but the process goes like so:

1. compile the fragment shader and vertex shader (you can compile as many files as you want actually like if you had a library you used with all your shaders, as long as you only have 1 entry point for fragments and 1 entry point for vertices)
see: glCreateShader, glCreateProgram, glShaderSource, glCompileShader

2. link the shaders into a program object
see: glAttachShader, glLinkProgram

3. when you want to use your shader, call glUseProgram. glUseProgram(0) goes back to default

4. get uniform locations with glGetUniformLocation
5. set uniforms with glUniform{1|2|3|4}{f|i}(v)

6. delete shit when you're done with it


the opengl documentation should be enough for those functions.
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #2 on: January 06, 2011, 08:47:27 AM »

this was a bit tough to find, but the process goes like so:

1. compile the fragment shader and vertex shader (you can compile as many files as you want actually like if you had a library you used with all your shaders, as long as you only have 1 entry point for fragments and 1 entry point for vertices)
see: glCreateShader, glCreateProgram, glShaderSource, glCompileShader

2. link the shaders into a program object
see: glAttachShader, glLinkProgram

3. when you want to use your shader, call glUseProgram. glUseProgram(0) goes back to default

4. get uniform locations with glGetUniformLocation
5. set uniforms with glUniform{1|2|3|4}{f|i}(v)

6. delete shit when you're done with it


the opengl documentation should be enough for those functions.

I've got all that, what I'm missing is step 5.5.

To restate my issue, modern GLSL seems to want me to specify the vertex coordinates using a generic vertex attribute.  Something like so:

Code:
in vec4 vertex_in;  // Passed in vertex coordinates.

void main()
{
    gl_Position = // Do stuff with vertex_in.
}

Now, presumably I have to set vertex_in using glVertexAttrib*, or one of the array forms.  This seems to imply that I shouldn't be using the standard vertex functions, or else I'd get this:

Code:
glVertexAttrib4fv(vertex_in_index, the_vertex_coords);
glVertex4fv(the_vertex_coords);

Now, the call to glVertex4fv is what actually starts the vertex shader (right?), meaning I have to pass the vertex coords twice, once to set the in variable (since gl_Vertex is deprecated) and once with another call to actually start the shader.  This doesn't seem right.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
Linus
Level 0
***


View Profile Email
« Reply #3 on: January 06, 2011, 08:51:40 AM »

Let's see.
I may be way off, since it was a while since I last looked at this, but as far as I know, you have a function family for specifying vertex attributes for a shader program: glVertexAttrib
They're used together with glGetAttribLocation to link vertex arrays, matrix arrays, and other data. Similarly, the glUniform family is used for uniform data.
Finally, I believe glDrawArrays is used to pass this data to geometry/vertex/fragment-shaders.
glDrawArrays allows you to set the starting point in the vertex arrays and how much of them you want to render.

Since OpenGL 3.x got rid of the fixed-function pipeline, you'll also have to implement your own matrix/vertex math libraries, which is logical since OpenGL isn't a math library. Tongue
Furthermore, you will always need to set up shaders to render your geometry.

The pipeline in OpenGL 3.x is overall very similar to what's used in OpenGL ES, so most samples from there should be applicable in OpenGL 3.x as well.
Edit: For example, this demo, or at least the Draw() function, should be, to a large extent, the same as in OpenGL 3.x.
« Last Edit: January 06, 2011, 08:57:21 AM by Linus » Logged
Glaiel-Gamer
Moderator
Level 10
******


Stoleurface!


View Profile WWW Email
« Reply #4 on: January 06, 2011, 09:10:34 AM »

Now, the call to glVertex4fv is what actually starts the vertex shader (right?), meaning I have to pass the vertex coords twice, once to set the in variable (since gl_Vertex is deprecated) and once with another call to actually start the shader.  This doesn't seem right.

glVertex4fv is deprecated though isn't it? glDrawArrays/glDrawElements is what causes the vertex shader to run. Also glVertex4fv never caused the shader to run, that was glEnd()

//

looks like openGL3.0 and glsl 1.3 want everything to be vertex attributes. Yup, just use glDrawArrays / glDrawElements and only pass vertex attributes in

edit:

glVertixAttributePointer(all your position stuff and whatnot dont care about syntax)
glDrawArrays(trianglestrip, 0, num_vertices)

^ this is super easy to convert into VBOs later too
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #5 on: January 07, 2011, 08:07:10 AM »

OK, I think I've got a handle on this now.

Since my core code is so heavily display list based, I'm just going to target OpenGL 2.1 and work shaders in where ever I can in the new code.  For my next project, I'll overhaul my back end for OpenGL 3.x.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
Solved
Level 0
***


View Profile
« Reply #6 on: January 07, 2011, 09:50:45 AM »

I'd recommend reading these tutorials. A while ago I got the Red Book in order to learn OpenGL, only to discover that almost all the functions in the book had been deprecated, and there didn't appear to be much help on using just non deprecated stuff. Then I found these tutorials which are pretty good and explain how to do things the OpenGL 3 way.
« Last Edit: January 07, 2011, 11:44:51 AM by Solved » Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic