• Advertisement
Sign in to follow this  

Miscellaneous OpenGL questions (mostly dealing with shaders)

This topic is 1940 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to learn the modern, full programmable OpenGL using LWJGL. At the moment I know how to parse files for models, use them in VBOs and draw them to the screen. I also have a first-person style camera that lets me freely move around and look at whatever I want.

 

Is glLight completely out of date? All lighting should be done with shaders, right?

I know how to apply shaders to models, is there a way to create a fragment shader that acts on everything? Is that the modern approach to light?

 

My render code for models looks like this:

		glPushMatrix();
		glRotatef(rotation, rx, ry, rz);
		glTranslatef(x, y, z);
		glScalef(sx, sy, sz);
		glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);
		glVertexPointer(3, GL_FLOAT, 0, 0);
		glBindBuffer(GL_ARRAY_BUFFER, vbos[1]);
		glNormalPointer(GL_FLOAT, 0, 0L);
		
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_NORMAL_ARRAY);
		glUseProgram(shaderProgram);
		glColor4f(r, g, b, 1f);
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10f);
		
		glDrawArrays(GL_TRIANGLES, 0, model.getFaces().size() * 3);
		glUseProgram(0);
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_NORMAL_ARRAY);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glPopMatrix();

Am I enabling and disabling the shader program at the correct times? Are glColor4f and glMaterialf worthless if shaders are used properly? Am I pushing and popping the matrix at the right time?

 

Thanks! I've read a lot but even with my Linear Algebra experience a lot of the math is hard to visualize.

Share this post


Link to post
Share on other sites
Advertisement

Given that you say that you want to learn the modern approach, the answer to almost all of your questions are not relevant. In the code you posted, all functions except glBindBuffer, glUseProgram and glDrawArrays are deprecated,s o questions about them are not relevant in the context of your final goal.

  • Materials and coloring has to be done by yourself in the shader, so glColor and glMaterial are all out of the question; you have to implement lighting and all that yourself in the shaders.
  • Transformation has to be done by yourself and be uploaded to the shader programs as uniforms, so glPushMatrix, glRotate and all those functions are out of the question; you have to replace those with some other math library.
  • Vertex arrays has been generalized and the specific functions such as glVertexPointer, glNormalPointer adn glEnableClientState has been replaced with generic attributes such as glVertexAttribArray (one generic function for any kind of vertex attribute, not a specific function for specific vertex attributes) and glEnableVertexAttribArray.

Otherwise, your buffer object and program object binding seems to be fine in relation to where you bind, where you set vertex array pointers, where you draw the arrays and so on.

Share this post


Link to post
Share on other sites

Thank you! So if the functions aren't listed at http://www.opengl.org/sdk/docs/man/ then I shouldn't use them if I want to use the modern approach. Learning OpenGL ES 2.0 should be very similar because it doesn't include any of the deprecated stuff as far as I know.

 

One more thing, I'm guessing per-pixel lighting via fragment shading is the modern approach. How do you apply a shader to the entire screen and not just a model?

Share this post


Link to post
Share on other sites
Thank you! So if the functions aren't listed at http://www.opengl.org/sdk/docs/man/ then I shouldn't use them if I want to use the modern approach. Learning OpenGL ES 2.0 should be very similar because it doesn't include any of the deprecated stuff as far as I know.

That seems to be the case, yes.

 

One more thing, I'm guessing per-pixel lighting via fragment shading is the modern approach.

Yes, fragment shaders are the way to do per-pixel lighting.

 

How do you apply a shader to the entire screen and not just a model?

That would depend on what kind of full-screen effect you want to do. You could, for example, render the scene to an off-screen texture and then draw the texture onto a full-screen quad. Use the desired fragment shader when drawing the quad.

Share this post


Link to post
Share on other sites

Ignoring exotic lighting techniques, it's typically enough to do them in the fragment shader when you draw the model. You don't see any effect of the lighting anywhere except for where the model is actually drawn. You need some kind of post-processing technique only if you want, say, halos or glows around very bright spots because they spread outside the model.

Share this post


Link to post
Share on other sites

Sorry, I ask that question wrong. The post-processing bit is interesting though, thank you.

 

I know you can apply shaders to models, and basic lighting can be done that way. Is there a way to use a shader to add lighting to every model in a scene at once? I'm having a very hard time specifying this question dry.png

Share this post


Link to post
Share on other sites

Brother Bob wanted to stay away from exotic lighting techniques, but I'm feeling adventurous.

 

Basically, ignoring extremely exotic lighting techniques (and if anyone else feels more adventurous, go ahead), there are two main ways in which you do lighting:

 

1) forward shading: you render your scene model by model and do the lighting either in the vertex shader or fragment shader, depending on the effect you want to obtain and the trade between visual quality and speed.

 

2)  deferred shading: you first render your scene in special textures that will retain different attributes per pixel, like diffuse color (before lighting), screen position (depth), normal and any other kind of attribute that you would need in your lighting calculations. After the first pass is complete (all opaque objects were rendered in these special textures), you draw a fullscreen quad with a special shader that uses all these textures to perform lighting on each pixel on the screen.   This technique is a bit more tricky, but I'm assuming you're not afraid and you want to learn new and exciting stuff. Lots of new games use this, but it can be quite heavy on texture memory. Also, handing transparent objects can be quite tricky, but there are tons of books explaining all that (ShaderX 4- 7, GPU Gems, etc).

 

After all that, you can (and should, because it's nice) do some image post processing. In the deferred shading technique, since you have more information per pixel than just color and depth, you can get quite creative with your post processing. In forward shading, for more complex post processing you will most likely need to render the scene multiple times in multiple textures. Come to think about it. deferred shading can be considered a quite heavy post processing effect :p

Share this post


Link to post
Share on other sites
I know you can apply shaders to models, and basic lighting can be done that way. Is there a way to use a shader to add lighting to every model in a scene at once? I'm having a very hard time specifying this question dry.png

 

If you use deferred shading (as described by LordJulian above), you are no longer on the level of individual meshes, as (often) all you have is the relevent shading data for that pixel. A common technique is to draw bounding geometry for calculating dynamic lighting so that lighting is only calculated if the light is visible and touching (or close to touching) those pixels. Deferred shading can also be useful to reduce the number and complexity of shaders due to its separation of calculating diffuse color from pretty much all of the lighting options.

Share this post


Link to post
Share on other sites

2 more cents throws in:

 

If you use deferred shading (as described by LordJulian above)

DON'T! don't use deferred shading as described by me above, research it and use it as described by someone who actually used it; I only wanted to paint the available pictures.

 

Also, my advice is: use the forward shading technique, it's more forgiving. When that fails to provide the results you're looking for, add a post processing step and milk that into more and more complex filters. In no time you'll do the steps to prepare yourself for deferred shading and you won't even know it. Don't go full deferred until you are ready, deferred shading, while offering an elegant model that promises to solve lots of issues,  presents lots of problems in itself. You'd have to be more controlled in the way you render your scene, with the different render targets and the way you pack/unpack information, etc. In one word, you'd have to be an obsessed management whore with your rendering pipeline(are we allowed to say whore in here? we should, it's the internets).

 

And, before you reach the "relevant shading data for that pixel" stage, you still have to first RENDER that data into the render targets; this is done, of course, with a custom shader that outputs all the needed values, which, later, will be interpreted by the super-shader. So, shader complexity is not really lower, it's just separated into multiple shaders, which, in itself, is a complex thing to do.

 

So, go gradually, and know that whatever you learn/experiment with "the classical way of applying shaders to models and basic lighting " will stay with you and will be relevant. Deferred shading is, after all, forward shading a full screen quad with some real-time generated textures :).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement