OpenGL muliply/add texture with glColor - java

I'm making a game in Java using the LWJGL and Slick.
From what I understand glColor multiplies the RGB values, but what if I wanted to add color to a texture that's had RBG removed? (desaturated)
The purpose of this is to create a grey texture and then use OpenGL to add color to it in code.

Adding is most likely not what you wan't. Adding is more of a brightening effect.
It sounds like the feature that you wan't is multiplying (glColor). If you have a grayscale texture, mulyiplying it with a color like red will create an image where the white parts of the texture are pure red, and the dark sections are darker shades of red.
Read:
http://en.wikipedia.org/wiki/Blend_modes

Related

Slick2d / LWJGL Adjusting alpha channel in OpenGL layer ( Java )

I apologize for some of my ignorance as I am fairly new to Slick2D and LWJGL. Essentially what I'm trying to do is make a scene look like night time by covering it with a GL_QUADS rectangle that is tinted blue and is translucent.
That part is easy enough. What I want to do from there is draw triangles into this layer that vary the alpha channel so. The reason I want to do this is so I can simulate a light source by decreasing the opacity of the blue tinted rectangle as it gets closer to the light source.
I drew an example of what the expected result should be with the green being the background, the blue being the nighttime effect created by a blue tinted rectangle, and the increasingly dim light source in the center.
I need to find a way to do this with triangles because I created a raycasting algorithm that generates the result as a series of gradient triangles.
I apologize if this is explained poorly. I will answer any questions you might have.
Here is the chunk of code used to create the blue tinted rectangle:
glColor4f (0.0f,0.0f,1.0f,0.4f);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(screenWidth,0);
glVertex2f(screenWidth,screenHeight);
glVertex2f(0,screenHeight);
glEnd();
I would like to write a modified version of the following code to adjusted the alpha channel of that rectangle.
glBegin(GL_TRIANGLES);
setAlphaOfPriorLayer(0.0f);
glVertex2f(x1,y1);
setAlphaOfPriorLayer(0.4f);
glVertex2f(x2,y2);
setAlphaOfPriorLayer(0.4f);
glVertex2f(x3,y3);
glEnd();
Again, I'm using triangles to approximate a circle and allow for proper raycasting.
To achieve this, the use of a Frame Buffer Object is super useful. A FBO allows you to essentially render to a texture which can then be displayed on the screen. In my particular case, I rendered the elements to a FBO then used a shader while drawing it to the screen to get the desired opacities.

How to change color in lwjgl texture

I have the following texture:
The black pixels are characters, the background is transparent.
How do I change the black pixels of the characters to another color?
I use this texture as a bitmap for tekst rendering in lwjgl. Is there a way to change the black pixels to red?
I would appreciate an example.
As far as I am aware glColor* also applies for textures. If you change the black color of your font to white the given color would simply apply to this.

Rendering lighting

I have a small block engine similar to a very early version of Minecraft using LWJGL. I now want to actually implement lighting. I understand how it works I'm just confused as to how I'm supposed to render lighting. Am I supposed to change the "brightness" of the texture to simulate bright terrain? I'm asking how to actually change the light value of a quad, maybe there are some tutorials out there? I want it to be block by block, no smooth lighting. I have figured out that blocks need to have a light value, and for every block next to it, you decrease that light value by a little bit until its "black".
(At least) two options, assuming a fixed-function renderer:
Use a single texture (your basic texture atlas, with the default GL_MODULATE texenv.) and set a per-vertex gray-scale color to darken the texture in proportion to the light level. With GL_MODULATE the texture RGB channels are multiplied by the vertex color RGB channels. So a vertex color of RGB(255,255,255) would be fully lit, RGB(0,0,0) would be pure black, and RGB(128,128,128) would be somewhere in the middle.
Use two textures (appearance atlas and lightmap atlas) and multitexture. The light level is set for a given face by supplying texture coordinates that select the appropriate lightmap square. If you animate the lightmap you can get a day/night cycle "for free" without having to iterate over the entire volume fixing up vertex colors like in #1.

Why do I need to disable GL_TEXTURE_2D after drawing string in order for shapes to render?

I'm using the Slick2D library in order to render text to the screen but in order to render gl shapes like Rect, I need to first disable GL_TEXTURE_2D. I'm just curious as to why that is needed. Why does GL_TEXTURE_2D disable the rendering of shapes?
The way OpenGL works is basically one large, global state machine. When you bind a texture, every triangle you draw afterwards will use that texture.
The issue here is that the text drawing doesn't unbind it's texture afterwards, so the shapes you draw afterwards will be using that texture instead of no texture. The reason why you think it's "disabling" rendering is because the texture is made up of characters with everything else being transparent. What you're seeing is OpenGL drawing your shape with opacity at 0.
What happens when you disable GL_TEXTURE_2D is that the texture gets unbound and you draw regularly without a texture.
Because the string's texture is applied. As you probably don't set any texture coords it probably uses a section of the texture that is transparent and hence you see nothing.

Using blending to create multiple areas of transparency surrounded by black

I've been playing around in openGL a little bit and I was wondering how I can take an image (say for example a black background) and then render a smaller white gradient over the top but have it make the white gradient transparent (instead of white) and remove from the black background. Leaving a black background with a transparent gradient in the center. I'm using LWJGL if that helps.
Is there any way of doing this with blending?
Edit: Okay, is there any way of instead of subtracting two images, I draw black around an image? So I have my white gradient, change it to be transparent and then draw black all around that?
Fixed function is usually implemented using shaders in modern GL drivers (there are old ATI's presentations with SM2.0+ shaders for all of the fixed functionality).
The close-to-trivial blending fragment shader like this
in vec2 TexCoord;
uniform sampler2D Texture0;
uniform sampler2D Texture1;
out vec4 out_FragColor;
void main()
{
vec4 Color = texture(Texture0, TexCoord);
/// The mask contains (R,G,B,A) - image + transparency
/// for both the mask and the source
vec4 Mask = texture(Texture1, TexCoord);
/// Mask is also significant as a color source, not only the alpha
out_FragColor = Color * ( 1.0 - Mask.a ) + Mask * Mask.a;
/// Thanks to Tim's comment, the last line can be done simpler:
/* out_FragColor = mix(Color, Mask, Mask.a); */
}
should mix the image the way you want to.
This is not overkill for modern hardware and it is 100% compatible even with the GL ES 2.0 hardware.
EDIT:
The image from one of my projects (simple mask used to create the fade-away reflection).
We use this mask
and get the final result in this image: Gallery
It may be possible to achieve what you want in the specific case, but in general once you 'draw a black background', there's no way to make it transparent afterward. You can't remove or erase pixels that have already been drawn.
If you can draw the gradient before the black background, then you can deposit the alpha into the framebuffer, and then sample the destination alpha when you draw the black background afterward. You'll need to have a real alpha texture though, as you can't really convert a white gradient to an alpha gradient at draw time.
Here's my suggested pseudocode:
draw whatever you want in the background
create texture with alpha gradient
lock color channels with glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE);
draw alpha gradient over background
unmask color channels with glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
draw 'black texture' with following blend options: glBlend(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA)
That should leave you with a black texture with a blended gradient to whatever was underneath it.

Categories

Resources