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 :)
I have a strange bug in opengl I cannot explain.
I have "programmed" using copy-paste of tutorials a shadow map.
I wanted to display the shadow map, so I wrote a little routine that displays it. It doesn't work (I only get a white square).
Finally, by trying a lot, I get the shadow to be almost correct on the main rendering of the scene. But the shadow doesn't render anymore when I un-comment the routine to display the shadowmap. (which goes before the main rendering)
I guess it has to do with glBindTexture(GL_TEXTURE_2D, depthTex) (which is stored in the shadowbuffer). If it is not asked to refer to this depthTex to display the shadow map, then somehow the shadow is built, but when asked to display this depthTex, then the shadow computed is nonsens.
I wonder if once asked glBindTexture(GL_TEXTURE_2D, depthTex) for the displaying of the shadowMap, the depthTex is not anymore able to be linked for the computation of the shadow shader.
I don't understand if glBindTexture is for reading or for writing...
This depthTex is indeed defined as the texture in which is stored the shadowmap.
to sum up : two pieces of code interfere, so that the rendering of a texture appears to become more complicated than simply giving the regular opengl commands to display a texture. Just as if glBindTexture(GL_TEXTURE_2D, depthTex) could be called only once.
If I ask in the displaying of the shadow map routine to display another texture of the program (such as "floor"), then the shadow is ok on the main rendered scene, but when i ask to display "depthTex", then the shadow doesn't works anymore.
I have a strange bug in opengl I cannot explain. I have "programmed" using copy-past of tutorials a shadow map.
In short: You're cargo culting. Read some good OpenGL tutorial(s), understand what they teach and then you'll make some progress.
I don't understand if glBindTexture is for reading or for writing... This depthTex is indeed defined as the texture in which is stored the shadowmap.
It's for both. It selects the texture bound to the active texture unit. When texturing is enabled or a shader bound that samples from the texture unit the bound texture is read. Calling one of the glTex…Image functions will write to it.
Well, I have been learning openGL with this tutorial: opengl-tutorial.org.
That tutorial do not explain how do the shaders works. I mean, is the vertex shader readed before the fragment shader?
Ok talking about the question, I want to create two objects for practice, one box (3D Square with a texture) and a pyramid (3D Triangle with a texture), I don't know how to do it, I know how to draw it with C++/OpenGl but talking about the GLSL.... Do I need to create another program? How can I do that?
(OpenGL 3.3)
OpenGL does not maintain "objects" in such a way as you seem to assume (the term object is used to refer to "something" internal that OpenGL uses and that you can refer to via an identifier. A vertex buffer, a texture, or a shader are all examples of "objects"). OpenGL is not a scenegraph.
You need to create the vertex data for each of your objects in your application (or load that data from a file) and to provide OpenGL with that by feeding a buffer object with that data.
Then you tell OpenGL to draw a number of vertices from that buffer. OpenGL does not care what that data is or how to draw it. It will only do exactly what you tell it to do. If you tell it "take this block of data that contains vertex coordinates, and now draw 5 triangles", then it will just do that.
Most of the tutorials, guides and books that I've found out there are related to OpenGL, explains how to draw a triangle and initialize OpenGL. That's fine. But when they try to explain it they just list a bunch of functions and parameters like:
glClear()
glClearColor()
glBegin()
glEnd()
...
Since I'm not very good at learning things by memory, I always need an answer to "why are we doing this?" so that I'll write that bunch of functions because I remember that I have to set a certain things before doing somethings else and so on not because the tutorial told me so.
Could please someone explain to me what do I have to define to OpenGL (only pure OpenGL, I'm using SFML as background library but that really doesn't matter) before starting to draw something with glBegin() and glEnd()?
Sample answer:
You have to first tell OpenGL what color does it need to clear the
screen with. Because each frame needs to be cleared by the previous
before we start to draw the current one...
First you should know, that OpenGL is a state machine. That means, that apart from creating the OpenGL context (which is done by SFML) there's no such thing as initialization!
Since I'm not very good at learning things by memory,
This is good…
I always need an answer to "why are we doing this?"
This is excellent!
Could please someone explain to me what do I have to define to OpenGL (only pure OpenGL, I'm using SFML as background library but that really doesn't matter) before starting to draw something with glBegin() and glEnd()?
As I already told: OpenGL is a state machine. That basically means, that there are two kinds of calls you can do: Setting state and executing operations.
For example glClearColor sets a state variable, that of the clear color, which value is used for clearing the active framebuffer color to, when a call to glClear with the GL_COLOR_BUFFER_BIT flag set. There exists a similar function glClearDepth for the depth value (GL_DEPTH_BUFFER_BIT flag to glClear).
glBegin and glEnd belong to the immediate mode of OpenGL, which have been deprecated. So there's little reason in learning them. You should use Vertex Arrays instead, preferrably through Vertex Buffer Objects.
But here it goes: glBegin sets OpenGL in a state that it should now draw geometry, of the kind of primitive selected as parameter to glBegin. GL_TRIANGLES for example means, that OpenGL will now interpret every 3 calls to glVertex as forming a triangle. glEnd tells OpenGL that you've finished that batch of triangles. Within a glBegin…glEnd block certain state changes are disallowed. Among those everything that has to do with transforming the geometry and generating the picture, which matrices, shaders, textures, and some others.
One common misconception is, that OpenGL is initialized. This is due to badly written tutorials which have a initGL function or similar. It's a good practice to set all state from scratch when beginning to render a scene. But since a single frame may contain several scenes (think of a HUD or split screen gaming) this happens several times a scene.
Update:
So how do you draw a triangle? Well, it's simple enough. First you need the geometry data. For example this:
GLfloat triangle[] = {
-1, 0, 0,
+1, 0, 0,
0, 1, 0
};
In the render function we tell OpenGL that the next calls to glDrawArrays or glDrawElements shall fetch the data from there (for the sake of simplicity I'll use OpenGL-2 functions here):
glVertexPointer(3, /* there are three scalars per vertex element */
GL_FLOAT, /* element scalars are float */
0, /* elements are tightly packed (could as well be sizeof(GLfloat)*3 */
trignale /* and there you find the data */ );
/* Note that glVertexPointer does not make a copy of the data!
If using a VBO the data is copied when calling glBufferData. */
/* this switches OpenGL into a state that it will
actually access data at the place we pointed it
to with glVertexPointer */
glEnableClientState(GL_VERTEX_ARRAY);
/* glDrawArrays takes data from the supplied arrays and draws them
as if they were submitted sequentially in a for loop to immediate
mode functions. Has some valid applications. Better use index
based drawing for models with a lot of shared vertices. */
glDrawArrays(Gl_TRIANGLE, /* draw triangles */
0, /* start at index 0 */
3, /* process 3 elements (of 3 scalars each) */ );
What I didn't include yet is setting up the transformation and viewport mapping.
The viewport defines how the readily projected and normalized geometry is placed in the window. This state is set using glViewport(pos_left, pos_bottom, width, height).
Transformation today happens in a vertex shader, Essentially a vertex shader is a small program written in a special language (GLSL), that takes the vertex attributes and calculates the clip space position of the resulting vertex. The usual approach for this is emulating the fixed function pipeline, which is a two stage process: First transform the geometry into view space (some calculations, like illumination are easier in this space), then project it into clip space, which is kind of the lens of the renderer. In the fixed function pipeline there are two transformation matrices for this: Modelview and Projection. You set them to whatever is required for the desired outcome. In the case of just a triangle, we leave the modelview identity and use a ortho projection from -1 to 1 in either dimension.
glMatrixMode(GL_PROJECTION);
/* the following function multiplies onto what's already on the stack,
so reset it to identity */
glLoadIdentity();
/* our clip volume is defined by 6 orthogonal planes with normals X,Y,Z
and ditance 1 from origin into each direction */
glOrtho(-1, 1, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
/* now a identity matrix is loaded onto the modelview */
glLoadIdentity();
Having set up the transformation we can now draw the triangle as outlined above:
draw_triangle();
Finally we need to tell OpenGL we're done with sending commands and it should finish it's renderings.
if(singlebuffered)
glFinish();
However most of the time your window is double buffered, so you need to swap it to make things visime. Since swapping makes no sense without finishing the swap implies a finish
else
SwapBuffers();
You're using the API to set and change the OpenGL state machine.
You're not actually programming directly to the GPU, you're using a medium between your application and your GPU to do whatever you're trying to do.
The reason it is like this and doesn't work the same way as a CPU and memory, is because openGL was intended to run on os/system-independent hardware, so that your code can run on any OS and run on any hardware and not just the one your programming to.
Hence, because of this, you need to learn to use their preset code that makes sure that whatever you're trying to do it will be able to be run on all systems/OS/hardware within a reasonable range.
For example if you were to create your application on windows 8.1 with a certain graphics card(say amd's) you still want your application to be able to run on Andoird/iOS/Linux/other Windows systems/other hardware(gpus) such as Nvidia.
Hence why Khronos, when they created the API, they made it as system/hardware independent as possible so that it can run on everything and be a standard for everyone.
This is the price we have to pay for it, we have to learn their API instead of learning how to directly write to gpu memory and directly utilize the GPU to process information/data.
Although with the introduction of Vulkan things might be different when it is released(also from khronos)and we will find out how it will be working.
I'm having a problem getting accurate primitive colours when I'm using multi-texturing elsewhere in the scene. Basically, I have some lines and polygons that I am trying render over a video texture (I'm using 3 stage multitexturing to create the video texture)... Anyhow, I know the problem is not alpha related... In fact, I know that in my texture update function if I just comment out the calls to glBindTexture() for texture levels 1 and 2, the primitive color is fine (so leaving texture level 0)... Is it trying to multitexture the primitives too (even though I'm obviously not setting texture coordinates for primitives)?
Make sure to disable multitexturing when not using it. OpenGL uses a state machine, so if you turn on a texture it will stay on until you explicitly turn it off.
Just because you're not setting coordinates, doesn't mean OpenGL will assume you're not using the texture.