Lightmap with multitexturing, disabling lighting for one of the textures? - opengl

How i can disable lighting for only one of the textures in this multitexturing scheme? I tried to use glDisable(GL_LIGHTING) and glEnable(GL_LIGHTING) but it doesnt remember the settings when i render the quad.
Here is the code snippet:
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_RECTANGLE_ARB);
glDisable(GL_TEXTURE_2D);
//------------------------
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, LIGHT_MAP); // texture with black/white
//------------------------
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, MY_TEXTURE); // normal texture
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
glNormal3f(0,0,1);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1, 0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1, 0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glActiveTextureARB(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
Edit: the texture loading:
glGenTextures(1, &LIGHT_MAP);
glBindTexture(GL_TEXTURE_2D, LIGHT_MAP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
Weird thing is that when i enable lighting at the first line of code, i cant see the light_map texture rendered at all in the multitexture quad. Also the lighting doesnt seem to affect that quad at all, it works on other quads (which arent multitextured) in my app.
Any help appreciated.

Your first sentence does not make sense. GL Lighting happens at the vertex level. texturing, be it single texture or multitexture. happens way after. In more details:
The lighting that got computed per vertex is interpolated to each fragment, and that value is input to the texturing pipeline stage 0.
So... The lit color L comes in and gets combined with the texture on the texture stage 0 (your light map here), according to the texture environment of stage 0. You don't show how you set up the Texture environment for texture stage 0, so I can't tell you how it will pass down.
Then your output from stage 0 (computed from lighting and texture 0) get sent to the texture stage 1 input (where your "normal" texture is bound. That's called a diffuse texture). You use an environment of COMBINE with ADD on both RGB and ALPHA here, which is not typical of lightmapping: You're adding your lighting+lightmap to the diffuse color. Usually you want to multiply them (GL_TEXTURE_ENV_MODE=GL_MODULATE rather than GL_COMBINE).
Also, you did not set the SOURCE0_ALPHA and SOURCE1_ALPHA, so I'm not sure what exactly you add to generate the stage 1 ALPHA output.
All in all, I'd advise to write down exactly what you want as a result first (as math), and try to map that to the GL multitexturing pipeline.
Edit: Following your comments, if you don't specify stage 0 TexEnv, then you get the default:
GL_TEXTURE_ENV_MODE defaults to GL_MODULATE and GL_TEXTURE_ENV_COLOR
defaults to (0, 0, 0, 0).
So your color coming from the lighting is modulated with your lightmap (which may make sense depending on what you're trying to achieve). That gets added to your diffuse (where, as I said, it should probably get modulated instead).
None of these change what I said earlier: write down exactly what math you would like for your result. From that we can help find which texture environment you may need. But you did not say what result you want to achieve.

Related

OpenGL: Can't get textures to display

I'm trying to add a texture to a simple square for more than 5h now but I still don't manage to do so.
Here's the code I'm using in paintGL():
glEnable(GL_TEXTURE_2D);
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
float pixels[] = {
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0,0,0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1,0,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1,1,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0,1,0);
glEnd();
if (glGetError() != 0)
{
qDebug() << glGetError();
}
There is no errors nor OpenGL's ones. I initialized the clear color to grey.
When I try to change color with glColor3f(...), it works.
I read about all tutorials that I could find with Google but no one helped.
SOLUTION:
I never put
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
at the right place: just after the glTexImage2D! Code above is edited and now work like a charm.
You HAVE to specify filtering for your texture:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
Because default filter uses mipmaps, but you don't generate them.
It looks to me like you're only using one quarter of your texture. It's only 4 pixels, and you've set the texture coordinates to be just the first pixel. If that pixel is white and your texture environment is set to multiply the quad's color by the texture, and you're set to use nearest neighbor sampling, then you'll get just the color. Try changing the texture coordinates to be (0,0) to (1,1) instead of (0,0) to (0.5,0.5) and see if that gives you the expected result. You can also try setting the various texture parameters and environments differently to see how that affects your drawing.

opengl, textures have always the same size

I'm trying to apply a texture to a vertex array whit the following code:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glColor3f(1.0f, 1.0f, 1.0f);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_QUADS, 12, GL_UNSIGNED_BYTE, faceIndices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_TEXTURE_2D);
with this texture:
so i have this result:
Now I'm wondering how can I scale the floor texture, i've already tried to scale the texture with photoshop, but the result is the same but heavier.
I assume you mean you want the texture to tile less, or tile more. In which case, change your texture coordinates, not the texture (i.e. whatever data is in texcoords).
Also, your example texture is blue, but it's brown in the rendered image. You might be swapping the R+B channels when loading.
It depends on your texture coordinates how you want to map the texture.
Let take example,it cover the whole polygon
glTexCoord2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
Now if you want to repeat the texture five times then provide coordinates like `
glTexCoord2f(0.0f, 0.0f);
glTexCoord2f(5.0f, 0.0f);
glTexCoord2f(5.0f, 5.0f);
glTexCoord2f(0.0f, 5.0f);`
Like above example change the value how you want to map the texture.

OpenGL display textures correctly

I'm rendering textures on the two surfaces which actually have the same location and position.
In these kind of cases I want to display only one of the textures, while I get following
I.e. I want only the texture of first material to be displayed.
So I would like to know where I've to search for solution, should I play with the blending of the materials ?
This is a pretty old issue (z-fighting) as the card isn't sure which object to draw in front. The linked Wikipedia article has more examples of this.
To fix this, increase the depth buffer's accuracy (bit depth), reduce the depth of your view (distance far/near clip plane) or add a tiny offset so the coordinates are no longer exactly (or almost) the same. You could as well simply disable the depth buffer (or clear it) for rendering this (in which case whatever is rendered last will overlap everything else).
You mean you want to display few textures at one time? Use multi texturing then. Attach both textures to one Quad using:
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
And play with glTexEnvi to combine them as you want. If you want to show only one of your textures then draw two quads with separate textures on each of them. And quad witch will be drawn later will be visible. Then if you want to turn from one to another, make separate -(void)'s for each of quad, with glClearColor before each quad drawing and then make button to call for example -(void)quad1 and button to call -(void)quad2.
Or just use depth buffer.
At your situation i would use multi texturing, because all buffers looked too hard for me all time.
I will show how would my code look like.
Code using multi texture:
glClear(GL_COLOR_BUFFER_BIT);
//Turn on blending and set glBlendFunc for your needs
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Describing multitexturing
glClientActiveTexture(GL_TEXTURE0_ARB); //Activating texture on unit 0
glActiveTexture(GL_TEXTURE0_ARB); //Activating texture on unit 0
glBindTexture(GL_TEXTURE_2D, Texture1); //Bind texture on unit 0
glEnable(GL_TEXTURE_2D); //Enable GL_TEXTURE_2D to set it's glTexEnvi for your needs
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); //Edit glTexEnvi for your needs (link bellow code)
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE );
glClientActiveTexture(GL_TEXTURE1_ARB); //Activating texture on unit 1
glActiveTexture(GL_TEXTURE1_ARB); //Activating texture on unit 1
glBindTexture(GL_TEXTURE_2D, Texture2); //Bind texture on unit 0
glEnable(GL_TEXTURE_2D); //Enable GL_TEXTURE_2D to set it's glTexEnvi for your needs
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); //Edit glTexEnvi for your needs (link bellow code)
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE );
//Drawing quad with multi texture
glBegin(GL_QUADS);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f); //Texture on unit 1 coords
glVertex2f(0.0, 500);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f); //Texture on unit 1 coords
glVertex2f(0.0, 0.0);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f); //Texture on unit 1 coords
glVertex2f(800, 0.0);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f); //Texture on unit 1 coords
glVertex2f(800, 500);
glEnd();
//Disable GL_TEXTURE_2D. We don't need it anymore
glDisable(GL_TEXTURE_2D);
//Disable blending
glDisable(GL_BLEND);
//Flush everything
glFlush();
Code for using one quad for each texture
-(void) drawQuad1
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 500);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(800, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(800, 500);
glEnd();
glDisable(GL_TEXTURE_2D)
glFlush();
}
-(void) drawQuad2
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture2);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 500);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(800, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(800, 500);
glEnd();
glDisable(GL_TEXTURE_2D)
glFlush();
}
//and now when you want to draw `drawQuad1` you need to do `[self drawQuad1];`
//and where you want to draw `drawQuad2` you need to do `[self drawQuad2];`
Info about glTexEnvi here. Its just sample code. Fast written so could have mistakes. Sorry if i forgot something. Just i haven't been doing it for long time. Written it on Mac OS X, so if you are using other platform maby you will have to change few things (not opengl). And about depth buffer? I don't know how to use it. So I can't explain it for you. Sorry. Never used them.

opengl texture cube c++

hello i create a cube and want on one side an texture.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
glBegin(GL_POLYGON); //Vorderseite
glColor4f(1.0f,0.0f,0.0f,1.0f); //ROT
glVertex3f(-fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,1.0f,0.0f,1.0f); //GELB
glVertex3f(+fSeitenL/2.0f,-fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,1.0f,1.0f,1.0f); //WEISS
glVertex3f(+fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glColor4f(1.0f,0.0f,1.0f,1.0f); //MAGENTA
glVertex3f(-fSeitenL/2.0f,+fSeitenL/2.0f,+fSeitenL/2.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
but i can't see my texture, what did i wrong?
thanks.
You haven't supplied texture coordinates. You need to issue one call to glTexCoord (the 2f variant being the most commonly-used) that indicates a part of the texture that the vector maps to, before the corresponding glVertex call.
Otherwise, OpenGL has no idea how the texture should be pasted onto the polygons.
First of all this doesn't seem a cube but just a quad, a cube is made by 6 different quads.. (and you could use GL_QUADS instead that GL_POLYGON.
Second thing is that you are loading the texture but not mapping it to the vertices. You need to supply coordinates to map how the texture should fit onto the quad. You can do it by using
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
the example is taken from NEHE OpenGL guide and I really suggest you to take a look since it's quite well explained: http://nehe.gamedev.net
Check tutorial 6 about texture mapping: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06

Cannot read from a texture when binding to GL_TEXTURE0

I'm learning to use OpenGL in my free time, and I'm working on deferred rendering right now. I've been stuck on this problem for a few weeks. When I bind my diffuse texture to GL_TEXTURE0, each pixel in the texture is (0.0f, 0.0f, 0.0f, 0.0f). When I switch it to GL_TEXTURE3 it works. Where should I be looking to debug this problem?
I will post the draw call for the rendering below.
The entire source code is in this repository:
https://github.com/DanielSmithMichigan/OpenGLExperimentation
The act of writing and reading from different textures happens in here:
https://github.com/DanielSmithMichigan/OpenGLExperimentation/blob/master/OpenGlTest6/Defer.h
The draw call:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// if I switch GL_TEXTURE0 to GL_TEXTURE3
// and diffuseUniform << 0 to diffuseUniform << 3
// then it will work
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
*diffuseUniform << 0;
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, positionTexture);
*positionUniform << 1;
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normalsTexture);
*normalsUniform << 2;
*ambientColorUniform << objects->ambientLight->color;
*lightColorUniform << objects->sun->color;
*lightDirectionUniform << objects->sun->direction;
*cameraPositionUniform << objects->camera->position;
*specularColorUniform << objects->sun->color;
*specularPowerUniform << 5.0f;
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(1, 0);
glVertex3f((float)width, 0.0f, 0.0f);
glTexCoord2f(1, 1);
glVertex3f((float)width, (float)height, 0.0f);
glTexCoord2f(0, 1);
glVertex3f(0.0f, (float)height, 0.0f);
glEnd();
I was trying to say GL_TEXTURE1 with uniform = 1
Because I doubted a texture you made before the diffuse texture using glGenTextures(1, &depthBuffer) but I don't know why you made its name depthBuffer depthbuffer must be one of RBOs not a texture.
Anyway,
the default value of glactivetexture() is GL_TEXTURE0
You didn't call glactivetexture(GL_TEXTURE0) before you called glbindtexture(depthBuffer) although because the default value is GL_TEXTURE0, you are using GL_TEXTURE0 already for the depthBuffer .
The issue was that in the files Mesh.h and Grid.h, I was binding a sampler to index 0 (GL_TEXTURE0). This sampler was still bound by the time I was trying to bind/read my diffuse texture on index 0.
The solution was to use glActiveTexture(GL_TEXTURE0) and glEnable(GL_TEXTURE_2D) before I started my geometry pass, and the opposite glActiveTexture(GL_TEXTURE0) and glDisable(GL_TEXTURE_2D) after it ended.
Then in the draw call for my deferred rendering object, I use glBindSampler(0, 0).
As far as I can tell, all 5 functions mentioned above were necessary.
The fix for this problem is in commit hash d60fec483e896971304f5f9f24c4bd0f10fe48fe for anyone who needs more information.