Search code examples
javaopengllwjglopengl-compat

LWJGL OpenGL won't draw 2D texture


I'm trying to create some code for loading and drawing 2D textures in LWJGL. Here is my code for drawing:

glfwShowWindow(window);
GL.createCapabilities();
loadTextures();
glClearColor(1f, 1f, 1f, 1f);

while (!glfwWindowShouldClose(window))
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //draw

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

    glPushMatrix();
    glTranslatef(100, 100, 0);
    glBindTexture(GL_TEXTURE_2D, testTexture);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0, 0);
        glVertex2f(0, 0);

        glTexCoord2f(1, 0);
        glVertex2f(TEXTURE_WIDTH, 0);

        glTexCoord2f(1, 1);
        glVertex2f(TEXTURE_WIDTH, TEXTURE_HEIGHT);

        glTexCoord2f(0, 1);
        glVertex2f(0, TEXTURE_HEIGHT);
     }

     glEnd();
     glPopMatrix();

    //end draw

    glfwSwapBuffers(window);
    glfwPollEvents();
}

glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();

And this is my texture loading code:

try
{
    BufferedImage image = ImageIO.read(file);
    /*
    if (image.getType() != BufferedImage.TYPE_INT_ARGB)
    {
        throw new TextureException("Invalid image!");
    }
    */
    int[] pixels = new int[image.getWidth() * image.getHeight()];
    image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
    ByteBuffer byteBuffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);

    for (int x = 0; x < image.getWidth(); x++)
    {
        for (int y = 0; y < image.getHeight(); y++)
        {
            int pixel = pixels[y * image.getWidth() + x];
            byteBuffer.put((byte)((pixel >> 16) & 0xFF));
            byteBuffer.put((byte)((pixel >> 8) & 0xFF));
            byteBuffer.put((byte)(pixel & 0xFF));
            byteBuffer.put((byte)((pixel >> 24) & 0xFF));
        }
    }

    byteBuffer.flip();
    int textureID = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, byteBuffer);
    return textureID;
}
catch (Exception e)
{
    e.printStackTrace();
    throw new TextureException("Failed to load image!");
}

However, when I run this code all I get is a white screen. I checked the value of testTexture and it was set to 1, so I assume that's the texture's ID which makes me believe that worked, but I think there's something going wrong when drawing.


Solution

  • Two-dimensional texturing has to be enabled by glEnable and can be disabled by glDisable:

    glEnable(GL_TEXTURE_2D);
    

    If texturing is enables then the texture wich is currently bound is applied, when the geometry is drawn by the glBegin/glEnd sequences.


    If you want to draw the geometry in window (pixel) coordinates, then you've to set an orthographic projection with. The orthographic projection can be set by glOrtho.
    If you dont set the orthographic projection, the vertex coordinates would have to be in normalized device space in range [-1.0, 1.0].

    In the following windowWidth an windowHeight is assumed to be the width and height of the window:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);
    
    glMatrixMode(GL_MODELVIEW);
    
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
        // [...]
    }