Hot questions for Using Lightweight Java Game Library in alpha

Question:

I have grass models textured by PNG pictures. And i get white background color instead of black, which I want to. Why it is so and what should i do to fix that? I am using LWJGL 3 and PNGDecoder.jar

Texture loader code:

public int loadTexture(String fileName) {
    ByteBuffer buf = null;
    int tWidth = 0;
    int tHeight = 0;

    try {
        // Open the PNG file as an InputStream
        InputStream in = new FileInputStream("res/" + fileName + ".png");
        // Link the PNG decoder to this stream
        PNGDecoder decoder = new PNGDecoder(in);

        // Get the width and height of the texture
        tWidth = decoder.getWidth();
        tHeight = decoder.getHeight();

        // Decode the PNG file in a ByteBuffer
        buf = ByteBuffer.allocateDirect(
                4 * decoder.getWidth() * decoder.getHeight());
        decoder.decode(buf, decoder.getWidth() * 4, Format.RGBA);
        buf.flip();

        in.close();
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(-1);
    }

    // Create a new texture object in memory and bind it
    int textureId = GL11.glGenTextures();
    GL13.glActiveTexture(textureId);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);

    // All RGB bytes are aligned to each other and each component is 1 byte
    GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);

    // Upload the texture data and generate mip maps (for scaling)
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0,
            GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
    GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);

    // Setup the ST coordinate system
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);

    // Setup what to do when the texture has to be scaled
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
            GL11.GL_NEAREST);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
            GL11.GL_LINEAR_MIPMAP_LINEAR);

    return textureId;
}

Answer:

If you want transparent textures to look transparent, you have to enable blending first. Put the following somewhere in your OpenGL initialization code.

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

You are also internally storing your texture in RGB instead of RGBA format.

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0,
    GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);

should become

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, tWidth, tHeight, 0,
    GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);

Question:

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.


Answer:

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.

Question:

I am creating a 2D game with lwjgl and slick-util. For a special feature in my game I wanted to be able to give textures a certain opacity. I have managed to figure this out but the next step is giving a Texture as a paramter which will give me the ability to give certain textures certain opacities in certain spots.

Note: I have gotten it sort of working before, but the mask also seemed to remove my background image, which I do not want.

I cannot post images because I dont have enough reputation or something but anyway what I want to basically do is:

  • first render a background image.
  • then render another images on top with a mask on it, I do not want this mask to apply onto the background.

How would I go about doing this?


Answer:

I think you use wrong blending mode. If you did not change default blending mode, then you need:

glEnable (GL_BLEND); // Enable blending.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Setup blending function.

I think in you case, texture does not blend with background, it simple replaces background.

Question:

I want to use Alpha/Blend mode for future stuff (transactions mainly and possible image blending).

Well, I can't get it to work using LWJGL (GL1.1), I already tried other blend modes but didn't worked, nor changing the background or anything like that...

Screenshots:
  1. http://i.imgur.com/cHU4YGS.png - GL_BLEND always enabled, everything is transparent
  2. http://i.imgur.com/sPmPqne.png - GL_BLEND enabled on QUAD and text, I can see the line that is on disabled GL_BLEND
  3. i imgur com/nkda41v png - GL_BLEND disabled on everything but the text -> I need some reputation to post more than 2 links, sorry about that but I belive this image is important so i'll post it anyway. Just fill with dots

The results are the same with or without alpha argument on all these tests

Code:

`    private void init() {
        try {
            Display.setDisplayMode(new DisplayMode(DEFAULT_WIDTH, DEFAULT_HEIGHT));
            Display.setResizable(true);
            Display.setVSyncEnabled(true);
            Display.setTitle(DEFAULT_TITLE + " v" + VERSION);
            Display.create();
            updateMatrix();
        } catch(LWJGLException e) {
            e.printStackTrace();
        }
        Keyboard.enableRepeatEvents(true);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Font consolas = new Font("consolas", Font.PLAIN, 13); font = new TrueTypeFont(consolas, antiAliasedFont); } private void updateMatrix() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0, 1, -1); //glScaled((double) DEFAULT_WIDTH / (double) Display.getWidth(), (double) DEFAULT_HEIGHT / (double) Display.getHeight(), 0); glViewport(0, 0, Display.getWidth(), Display.getHeight()); glMatrixMode(GL_MODELVIEW); } @Override public void run() { init(); Main main = Main.getMain(); while(!Display.isCloseRequested()) { currentGraphicsTick++; { glClear(GL_COLOR_BUFFER_BIT); glClearColor(0f, 0f, 0f, 1f); if(Display.wasResized()) updateMatrix(); if(vsyncMode == 1) Display.setVSyncEnabled(true); else if(vsyncMode == 2) Display.setVSyncEnabled(false); if(Display.isActive()) { glPushMatrix(); try { // Draw float alpha = (float) Math.cos(Math.toRadians(currentGraphicsTick % 90)); System.out.println("Alpha: " + alpha); glBegin(GL_LINE_STRIP); { float sin = (float) Math.abs(Math.sin(Math.toRadians(currentGraphicsTick % 360))); new Color(0.7f, 0.7f, 0.7f, alpha).bind(); glVertex2f(DEFAULT_WIDTH * 0.03f, DEFAULT_HEIGHT * 0.05f); glVertex2f(DEFAULT_WIDTH * 0.93f * sin, DEFAULT_HEIGHT * 0.95f * sin); } glEnd(); glBegin(GL_QUAD_STRIP); { new Color(0.5f, 0.5f, 0.5f, alpha).bind(); glVertex2i(0, 0); glVertex2i(0, DEFAULT_HEIGHT); glVertex2i(DEFAULT_WIDTH, 0); glVertex2i(DEFAULT_WIDTH, DEFAULT_HEIGHT); } glEnd(); String[] split = main.getGameLoopThread().getDebugString().split("\n"); for(int i = 0; i < split.length; i++) { font.drawString(1, 1 + (i * font.getLineHeight()), split[i], Color.white); } } catch(Throwable throwable) { throwable.printStackTrace(); } glPopMatrix(); } Display.update(); Display.sync(TARGET_FPS); } } Display.destroy(); closeRequested = true; }
I already tried:
  1. Removing the 'alpha' argument from the Slick's Color constructor
  2. Using OpenGL's glColor with and without alpha argument
  3. Disabling/Enabling GL_BLEND in part of the code (I know some things wouldn't work, but you never know, right?)
  4. Used constants to the alpha variable (such as 0.3f, 0.5f, 0.7f, 1f) instead of making it variable through Math.sin/cos using the tick as the degree
  5. Using glRect(...)
  6. Changing the background
  7. Removing the glClearColor
  8. Removing glClear (nice effect, never did this lol)
What I expect to see was a fading moving LINE_STRIP:
  • On one side it moves from the (0, 0) to (width - 7%, height - 5%)

  • On the other it stand still on (width + 3%, height + 5%)

  • the rectangle would make it fade (the original idea would use the same color as the background, but it didn't on my tests because I want to see the rectangle)


Answer:

I've had a similar(in terms of what I had to tackle) when doing a 2D game using my own engine. LWJGL's blend functions always have a few issues and there aren't really that many concrete answers for them as it really boils down to your code and how you placed things.

I presume you're using SlickUtil, and to that I would say write your own (or of course search around) your own methods for this. Util's methods were always somewhat wonky with blending.

  1. Removing alpha shouldn't have changed much in terms of getting what you want
  2. The only time I explicitly enable GL_BLEND is when rendering lights(always presuming you're doing 3D) and when I would render textures
  3. I suggest not removing glClearColor, that doesn't directly affect your situation as long as you put it in the correct place

Like I said this bug/problem could be due to quite a few things that I can't quite pin-point from what you've posted.

My suggestions are:

  1. Organise the whole project well to be able to point bugs out quickly
  2. Make alot of stuff generic ASAP(Doesn't matter if you just want to quickly write something)
  3. Avoid SlickUtil, it's great and I LOVE it but it does get it's issues

Sorry I can't help too much but tracking down your issue from the jumbled up code you posted is a bit difficult. I'll keep my eye on this question in case I may be of help in the future.