Drawing a texture with glDrawArrays()

Started by whizvox, February 17, 2016, 21:24:42

Previous topic - Next topic

whizvox

Hello. Sorry if I come across as stupid, but I'm still fairly new to OpenGL and GLFW, and I cannot figure out why this code doesn't work:

package whizvox.lwjgltest;

import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.stb.STBImage;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class Main {

    public static void main(String[] args) {
        GLFW.glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
        if (GLFW.glfwInit() == 0) {
            throw new RuntimeException("Could not init GLFW");
        }
        GLFW.glfwDefaultWindowHints();
        long window = GLFW.glfwCreateWindow(800, 600, "Hello world!", 0, 0);
        GLFW.glfwMakeContextCurrent(window);
        GLFW.glfwSetKeyCallback(window, new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if (key == GLFW.GLFW_KEY_ESCAPE) {
                    GLFW.glfwSetWindowShouldClose(window, 1);
                }
            }
        });
        GL.createCapabilities();

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(-1, 1, -1, 1, -1, 1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glLoadIdentity();

        IntBuffer widthBuf = BufferUtils.createIntBuffer(1),
                heightBuf = BufferUtils.createIntBuffer(1),
                compBuf = BufferUtils.createIntBuffer(1);
        ByteBuffer texData = STBImage.stbi_load("PATH_OF_PNG_WHICH_ACTUALLY_EXISTS", widthBuf, heightBuf, compBuf, 4);
        if (texData == null) {
            throw new NullPointerException();
        }
        int texId = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, widthBuf.get(), heightBuf.get(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, texData);

        FloatBuffer vertBuf = BufferUtils.createFloatBuffer(18);
        FloatBuffer texBuf = BufferUtils.createFloatBuffer(12);
        vertBuf.put(new float[] { -1f, 1f, 0f, });
        vertBuf.put(new float[] { 1f, 1f, 0f, });
        vertBuf.put(new float[] { -1f, -1f, 0f, });

        vertBuf.put(new float[] { 1f, -1f, 0f, });
        vertBuf.put(new float[] { -1f, -1f, 0f, });
        vertBuf.put(new float[] { 1f, 1f, 0f, });

        texBuf.put(new float[] { 0f, 1f, });
        texBuf.put(new float[] { 1f, 1f, });
        texBuf.put(new float[] { 0f, 0f, });

        texBuf.put(new float[] { 1f, 0f, });
        texBuf.put(new float[] { 0f, 0f, });
        texBuf.put(new float[] { 1f, 1f, });
        vertBuf.flip();
        texBuf.flip();

        int vertVbo = GL15.glGenBuffers();
        int texVbo = GL15.glGenBuffers();

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertVbo);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertBuf, GL15.GL_STATIC_DRAW);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, texVbo);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texBuf, GL15.GL_STATIC_DRAW);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        while (GLFW.glfwWindowShouldClose(window) == 0) {
            GL11.glClearColor(0f, 0f, 0f, 0f);
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

            GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertVbo);
            GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, texVbo);
            GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);

            GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
            GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

            GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);

            GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
            GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

            GLFW.glfwSwapBuffers(window);
            GLFW.glfwPollEvents();
        }
        GL11.glDeleteTextures(texId);
        GL15.glDeleteBuffers(vertVbo);
        GL15.glDeleteBuffers(texVbo);
        GL.destroy();
        GLFW.glfwDestroyWindow(window);
        GLFW.glfwTerminate();
    }

}


I followed this guide: http://stackoverflow.com/a/18819693
The only thing I see is a plain white background. I'm using LWJGL 3.0.0b.

Kai

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);

after your glBindTexture will do.
Reason: OpenGL does not know how to sample your texture without a mipmap chain, since the default minification filter for 2D textures is 'NEAREST_MIPMAP_LINEAR'.

whizvox

Quote from: Kai on February 18, 2016, 07:27:11
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);

after your glBindTexture will do.
Reason: OpenGL does not know how to sample your texture without a mipmap chain, since the default minification filter for 2D textures is 'NEAREST_MIPMAP_LINEAR'.

Thanks! I added

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);


after the textureId is generated, and I also added

STBImage.stbi_set_flip_vertically_on_load(GL11.GL_TRUE);


before the image is loaded so it's rendered properly.