Hello,
To resume my problem :
I'm using basic Sprite-sheets with alpha transparency. I also wish to use light/color effects with shaders. My problem is with (or seems to be with) glBlendFunc :
In the main gl setup, glBlendFunc(GL_ONE, GL_ONE) works fine for lights with glCreateShader(GL_FRAGMENT_SHADER) but all Sprites have transparency when overlapping. With glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), Sprites are fine but "shader lights" don't display correctly.
I'm trying to find the correct way to setup gl for both these aspects. I've tried many different params in glBlendFunc without success. My code examples bellow :
My main gl setup with call to shader lights setup at end :
Display.create();
// enable textures since : used sprites.
glEnable(GL_TEXTURE_2D);
// disable the OpenGL depth test : rendering 2D graphics
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glEnable(GL_BLEND);
// this call to Blend makes lights work:
glBlendFunc(GL_ONE, GL_ONE);
// this call to blend is good for sprites but not for lights:
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLoadIdentity();
glOrtho(0, FrameConst.FRM_WIDTH_800, FrameConst.FRM_HEIGHT_600, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, FrameConst.FRM_WIDTH_800, FrameConst.FRM_HEIGHT_600);
glLightHelper.initGLLightRendering(GLLightHelper.SHADER1);
//------- TEST : --------------//
glLightHelper.lightEntities.put("test",
new GLLight(new Vector2f(300.0f, 300.0f), 1.0f, 5.0f, 10.0f));
// END TEST
Init for light rendenring with shader :
public void initGLLightRendering(final String shaderPath) throws GLLightHelperException {
shaderProgram = glCreateProgram();
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
final StringBuilder fragmentShaderSource = new StringBuilder();
try {
String line;
BufferedReader reader = new BufferedReader(new FileReader(shaderPath));
while ((line = reader.readLine()) != null) {
fragmentShaderSource.append(line).append("\n");
}
} catch (final FileNotFoundException fnfe) {
Logger.getLogger(GLLightHelper.class.getName()).log(Level.SEVERE, null, fnfe);
} catch (final IOException ioe) {
Logger.getLogger(GLLightHelper.class.getName()).log(Level.SEVERE, null, ioe);
}
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
throw new GLLightHelperException("Fragment shader compilation failed.");
}
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
glEnable(GL_STENCIL_TEST);
glClearColor(0, 0, 0, 0);
}
Light rendering method :
public void renderLights() {
for (GLLight light : this.lightEntities.values()) {
glColorMask(false, false, false, false);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, 1);
glColorMask(true, true, true, true);
glUseProgram(shaderProgram);
glUniform2f(glGetUniformLocation(shaderProgram, "lightLocation"),
light.location.getX(), FRAME_HEIGHT - light.location.getY());
glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"),
light.red, light.green, light.blue);
//glEnable(GL_BLEND); // Already activated (see Game.init()).
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // OK for textures but no lights.
//glBlendFunc(GL_ONE, GL_ONE); // OK for lights but to much alpha on textures.
glBegin(GL_QUADS);
{
glVertex2f(0, 0);
glVertex2f(0, FRAME_HEIGHT);
glVertex2f(FRAME_WIDTH, FRAME_HEIGHT);
glVertex2f(FRAME_WIDTH, 0);
}
glEnd();
glUseProgram(0);
glClear(GL_STENCIL_BUFFER_BIT);
}
glColor3f(0, 0, 0);
}
POJO class for lights :
public class GLLight {
public Vector2f location;
public float red;
public float green;
public float blue;
public GLLight(Vector2f location, float red, float green, float blue) {
this.location = location;
this.red = red;
this.green = green;
this.blue = blue;
}
}
Finaly, shader fragment :
uniform vec2 lightLocation;
uniform vec3 lightColor;
uniform float screenHeight;
void main() {
float distance = length(lightLocation - gl_FragCoord.xy);
float attenuation = 1.0 / (distance * 2); // Also try 1.0 / distance;
vec4 color = vec4(attenuation, attenuation, attenuation, pow(attenuation, 3)) * vec4(lightColor, 1);
gl_FragColor = color;
}
I am obviously new to OPENGL and LWJGL. I'm very gratefull for any help/advice or links to documentation of any kind on the subject.