OpenGL tinting textures

Okay, so I’m learning OpenGL through LWJGL, and I am starting to learn to program in a more procedural manner because of it. (I consider this to be a step back, but what can you do?) I have some experience with Slick2D, and know a few concepts from LibGDX, but now I’m trying to make my own library that functions like these two. I feel that by making my own library, I’ll be able to know exactly what is going on under the hood and won’t rely on these wrappers to talk to OpenGL for me.

BUT I DIGRESS! Right now, I am trying to program Quad class that will allow shading to occur. More specifically, I want to apply a tint to textures that I have binded. Currently, my rendering code looks like this…


	// Renders quad
	public void render()
	{
		texture.bind();
		
		// Mins and maxes for which parts of the image to select
		float minX = srcX / (float)texture.getImageWidth();
		float minY = srcY / (float)texture.getImageHeight();
		float maxX = srcX2 / (float)texture.getImageWidth();
		float maxY = srcY2 / (float)texture.getImageHeight();
				
		// Begins drawing a quad
		GL11.glBegin(GL11.GL_QUADS);
		   GL11.glColor3f(v2Shade, v2Shade, v2Shade);
		   GL11.glTexCoord2f(maxX, minY);
		   GL11.glVertex2f(srcX2 - srcX, 0);
		   GL11.glColor3f(1, 1, 1);
		   //
		   GL11.glColor3f(v3Shade, v3Shade, v3Shade);
		   GL11.glTexCoord2f(maxX, maxY);		//
		   GL11.glVertex2f(srcX2 - srcX, srcY2 - srcY);
		   //
		   GL11.glColor3f(v4Shade, v4Shade, v4Shade);
		   GL11.glTexCoord2f(minX, maxY);		//
		   GL11.glVertex2f(0, srcY2 - srcY);
		   //
		   GL11.glColor3f(v1Shade, v1Shade, v1Shade);
		   GL11.glTexCoord2f(minX, minY);
		   GL11.glVertex2f(0, 0);
		GL11.glEnd();
	}

This is all fine and dandy, but glColor3f only really darkens the colors. That’s good enough for me in most cases, but what if I want to apply a tint? The tint, of course, could be for lighting. Maybe the light is particularly yellow, and the texture would be more yellow than usual. It would be useful if there was a method like…


glTint4f(float red, float green, float blue, float intensity);

As far as I know, though, OpenGL has no such function. Is their a painless way to do this? Shading is already painless.

…when you give your color for your vertex you can use glColor4f(r,g,b,a) and use same rgba for each coord and it will tint for you over what ever texture you are using. A is alpha which is intensity. So actually opengl does have that.

Hmm, maybe I wasn’t explicit. Let’s say I wanted to apply a white light to a texture. How would I go about doing that? By writing glColor4f(1, 1, 1, 1), I just get the original texture. I can’t really make it brighter. That’s my problem. Maybe I should have written that in my first post. Sorry.

I would like something like…

glColor4f(1, 1, 1, 0.5f)

to make the texture half way closer to a white silhouette.

If you wanted it to get brighter you would have to do glcolor4f(2,2,2,1), but unfortunately input is clamped to the 0-1 range.

That’s depressing… Is that just an lwjgl thing?

After rending your image you could render a non textured quad/trianglestrip above it with additive blending on. That is what I do when I want to do lighting without actually doing lighting.

There are three solutions for this problem: shaders, shaders, shaders.

I have to agree with this. I recently started using shaders and stopped using old OpenGL coloring, and it’s much easier.

i’m trying to get into shaders too. Just FYI the fixed function pipeline is a LOT slower then vertex arrays or VBOS and shaders.

I agree; shaders are the way to go.

Now’s a good time to pimp my lwjgl-basics API, which is kind of like a more minimal and more modernized SlickUtil. It’s very lightweight, and reduces a lot of the boilerplate for you. It should also perform hundreds of times better than Slick or plain old glBegin/glEnd. Basically your entire tint rendering will look like this:

... create ...
    //create a tint shader, loading source from text files
    tintShader = new ShaderProgram(vertexShader, fragShader, SpriteBatch.ATTRIBUTES);
 
    //create a sprite batch with our shader
    batch = new SpriteBatch(tintShader);

... render ...
    //start rendering with our tint shader
    batch.begin();
   
    //set the tint RGB values to modulate our texture by
    tintShader.setUniformf("tintColor", 1.2f, 1.0f, 0.8f);

    //draw some sprites with the specified tint
    batch.draw(sprite, 10, 10);

    //finish rendering, flushing our batch to the GPU
    batch.end();

I have a number of tutorials on GLSL and other OpenGL concepts that utilize the library. Shader Lesson 3 explains tinting with sepia (first desaturate to grayscale, then multiply by color). I’d suggest starting with the Intro to Shaders before moving on. Also make sure you have a firm grasp of how OpenGL Textures work before diving into shaders.

Check out the rest of my tutorials here:

If you are really crazy and refuse to use a 3rd party library, here are a couple links that might help you re-invent the wheel:
Writing your own ShaderProgram Utility
Sprite Batch example code

You confuse immediate mode with fixed function pipeline.

Fixed function pipeline has nothing to do with how geometry is sent to the GPU. Therefore fixed function pipeline by definition cannot affect performance of ‘vertex arrays or VBOs’.

sorry. I hava trouble putting things into words. Immediate mode is slow. The fixed function pipeline is deprecated.

Technically speaking, OpenGL is all immediate mode, since the opposite of that is “Retained Mode”, a feature that was in the original Iris GL and really old DirectX. That’s where the driver itself maintained a scenegraph of objects, and to move things or set their color, you just sent it the changes and it recalculated all the states. Sounds pretty nifty, but it was slow and inflexible.

Stuff like the various buffer objects in OpenGL are, I suppose, “retained mode done right”. Just thought I’d throw out that little nugget o historical trivia :wink: