I'm writing a little OpenGl program with Glsl.
Now I have two objects which I need to draw. Both have different shaders.
Normally I think I should do something like that in my draw() method:
void draw() {
shaderObjektOne.bind();
glBegin(xxx);
//draw Object one
...
glEnd()
shaderObjektTwo.bind();
glBegin(xxx);
//draw Object two
...
glEnd()
}
If I do that this way my screen freezes.
Binding the shader for only one object is working without problems.
I've been looking around but I couldn't find a real explanation why this error occurs.
Is it because a render target can only be rendered with one shader?
How can I avoid a giant shader file or having multiple render targets?
Thanks.
EDIT:
I want to have separate compiled shader programs for each object. These will be bound right before I draw the vertexes for the object. I want to avoid one big shader in which I need to set specific parameters to choose the functionality for the object. I use glut and currently all drawing is done before glutSwapBuffers().
'Freezing' means that there is actual something visible on the screen (the last object I've drawn with the last bound shader) but my input isn't working anymore. That means, I cannot move the camera in the world but the program is still running normal (tested with a debugger).
Got it.
It was a problem with my program design. I accidentally added a copy of the shader which I wanted to bind.
Everytime I tried to bind the shader it bound the copy of it.
Thanks for your help guys :)
Related
Okay, so here is my problem. I have a framework used by my school for visualizations, and I've been trying to set it up to do 3d graphics. Problem is, the framework currently only uses the fixed function pipeline to draw. Without messing that up, i've been trying to work around the old code which still needs to use the fixed function pipeline, and i have been setting up facilities to allow for the creation of shaders and shader programs. I've got a simple color shader to compile and i've also made a test vertex array (a green triangle).
Now when i tried to render it, the screen went black. Before hand, there was a lot of 2d sprites and what not moving about the screen, but stepping through the code i added to the render function, I found that the screen goes black the moment I call glUseProgram. If i comment out the glUseProgram, and the parts where i set the uniforms and draw, everything works normally. Does glUseProgram disable the fixed function pipeline? if so, is there anyway to reactivate it, per se?
The moment you use glUseProgram fixed function pipeline is replaced by programmable pipeline. You can't have like fixed function + programmable pipeline at the same time. For example suppose your scene contains fog. But if you haven't taken care of that in your fragment shader you wont see it in final output.
Though in your render/draw function you can do something like this
draw
{
glUseProgram(program);
// render stuff with shader
glUseProgram(0)
// render stuff with fixed pipeline
}
I'm working on a small engine in OpenTK right now, and I've got shaders working so far. I wonder though , how it is possible to apply a shader to an entire scene!?. I've seen this done in minecraft for example, where someone created a shader that warped the entire scene. But since every object is rendered with its own shader active, how would I achieve this?
You seem to be referring to a technique called post processing. The way it works is that you first render the entire scene to a texture using the shaders you already have. You can then render this texture to the screen using a fragment shader to apply various effects like motion blur, warping or depth of field.
"But since every object is rendered with its own shader active"
That's not how OpenGL works. In fact there's no such thing as "models" (what you probably mean by "object") in OpenGL. OpenGL draws primitives (points, lines and triangles) one at a time. Furthermore there's no hard association between a set of primitives and the shaders being used.
It's trivial to just bind a single shader program at the beginning of a batch and every primitive of that batch is subjected to this shader. If the batch consists of the whole scene, then the whole scene uses that shader.
AFAIK, you can only bind one vertex shader at a time.
What you may want to try is to render to a texture first then rerender the texture onto the screen but applying some changes to it (warping it for example). You can also extract the depth buffer and use it if you have a more complex change that you want to apply.
If you bind the shader you want before the render loop, it would effect all items until you un-bind it (i.e. binding id #0) or disable GL_TEXTURE_2D via glEnable()/glDisable().
Okay, so here is my problem. I have a framework used by my school for visualizations, and I've been trying to set it up to do 3d graphics. Problem is, the framework currently only uses the fixed function pipeline to draw. Without messing that up, i've been trying to work around the old code which still needs to use the fixed function pipeline, and i have been setting up facilities to allow for the creation of shaders and shader programs. I've got a simple color shader to compile and i've also made a test vertex array (a green triangle).
Now when i tried to render it, the screen went black. Before hand, there was a lot of 2d sprites and what not moving about the screen, but stepping through the code i added to the render function, I found that the screen goes black the moment I call glUseProgram. If i comment out the glUseProgram, and the parts where i set the uniforms and draw, everything works normally. Does glUseProgram disable the fixed function pipeline? if so, is there anyway to reactivate it, per se?
The moment you use glUseProgram fixed function pipeline is replaced by programmable pipeline. You can't have like fixed function + programmable pipeline at the same time. For example suppose your scene contains fog. But if you haven't taken care of that in your fragment shader you wont see it in final output.
Though in your render/draw function you can do something like this
draw
{
glUseProgram(program);
// render stuff with shader
glUseProgram(0)
// render stuff with fixed pipeline
}
I've recently succeeded at making a small test app with a GL_TEXTURE_RECTANGLE. Now I'm trying to integrate it into my larger project, but when I call glBindTexture(GL_TEXTURE_RECTANGLE, _tex_id[0]) inside the render function, it's causing the GL_INVALID_OPERATION​ error. The texture image sometimes shows for a fraction of a second, then turns black and stays black.
I am trying to do this by using two sets of vertex and fragment shaders, one set for the 3D scene, and one set for the 2D overlay, but I've never tried this before so I don't know if that's what's causing the error, or if I should be going about this a different way. The shaders are all compiling and linking fine.
Any insight would be much appreciated, and if it would help to see some code, let me know and I'll post some of it (although I think it may be too much for anyone to reasonably look through).
Edit: gDEBugger breaks at the call to glBindTexture(), and when clicking on the breakpoint, the properties window shows a picture of one of my other textures (one that's being loaded by the 3D scene's shaders), it shows that it's trying to load texture number 1, but I know this number is already being used to draw the same 3D scene's texture shown in the properties window... why would glGenTextures() be giving me overlapping texture id numbers? Is this normal or maybe part of the problem?
The black texture was due to me not forwarding some vertex shader inputs (normals) through to the fragment shader, even though I'm not using normals for anything in the 2D overlay shaders. As soon as I added outputs for all the inputs, and forwarded them along to the fragment shader, the texture was no longer black, but it was still disappearing after a fraction of a second. This was because I was calling glBindTexture(GL_TEXTURE_RECTANGLE, 0) at the end of the render function with the hopes that it would clean up some state... this was clearly the wrong thing to do, because removing that call caused the 2D texture to stay on-screen. Furthermore, calling glBindTexture() with the GL_TEXTURE_RECTANGLE target seems to work during the texture setup stage, but during rendering the GL_TEXTURE_RECTANGLE target was causing the GL_INVALID_OPERATION​ error. Changing the target to GL_TEXTURE_2D only in the render function made the error go away, and everything seems to work nicely now.
I have several objects on my scene. I want to apply my shader to one of them only. Environment: OpenGL 2.0, C++, GLUT, GLEW.
The shader program is only in effect for as long as it is installed. Only the draw calls you make while the program is installed will use the shader. You must install your shader, draw your object, and then uninstall the shader.
Edit: By "install" the shader I mean use glUseProgram with your shader's handle. By "uninstall" I mean either installing another shader or calling glUseProgram with an argument of 0. See glUseProgram. My "install/uninstall" terminology comes from there.
In your drawcall draw that object with that shader and draw the other ones without it.. can't really be any more simple than that ;P You could use enums in your object class where you can specify shaders that are enabled for that object and only pass them through that shader when they are supposed to.. of course if it's a fullscreen pixelshader then you're in trouble as it processes every pixel and renders a new image to display. Unless you have a way of passing the object as a parameter and a algoritm to only apply the alterations at the location of that object.