1
$\begingroup$

So this should be easy and simple, but I still can't get it to work. All I need is a small example program that:

  • Takes in a BufferedImage (TYPE_INT_ARGB)
  • Renders that BufferedImage on a textured quad
  • Using a VBO
  • Without additional shader declaration
  • Using LWJGL3

Here's what I have got so far:

package togos.minecraft.maprend.guistandalone;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.system.MemoryUtil.NULL;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLUtil;
import org.lwjgl.system.Callback;

public class GuiMain2 {

    // We need to strongly reference callback instances.
    private GLFWErrorCallback       errorCallback;
    private GLFWKeyCallback         keyCallback;
    private GLFWWindowSizeCallback  wsCallback;
    private Callback                debugProc;

    // The window handle
    private long                    window;
    private int                     width, height;

    public void run() {
        try {
            init();
            loop();

            // Release window and window callbacks
            glfwDestroyWindow(window);
            keyCallback.free();
            wsCallback.free();
            if (debugProc != null)
                debugProc.free();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            glfwTerminate();
            errorCallback.free();
        }
    }

    private void init() {
        glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
        if (!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");

        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        // Create the window
        window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
        if (window == NULL)
            throw new RuntimeException("Failed to create the GLFW window");

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {

            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                    glfwSetWindowShouldClose(window, true); // We will detect this in our rendering loop
            }
        });
        glfwSetWindowSizeCallback(window, wsCallback = new GLFWWindowSizeCallback() {

            @Override
            public void invoke(long window, int w, int h) {
                if (w > 0 && h > 0) {
                    width = w;
                    height = h;
                }
            }
        });

        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        glfwSetWindowPos(window, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
        glfwMakeContextCurrent(window);
        glfwShowWindow(window);
    }

    private void loop() throws IOException {
        GL.createCapabilities();
        debugProc = GLUtil.setupDebugMessageCallback();

        glEnable(GL_TEXTURE_2D);
        glEnable(GL_COLOR_MATERIAL);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        float[] vertices = {
                -0.5f, -0.5f, 0, 0,
                0.5f, -0.5f, 1, 0,
                0.5f, 0.5f, 1, 1,
                -0.5f, 0.5f, 0, 1 };
        int vbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, (FloatBuffer) BufferUtils.createFloatBuffer(vertices.length).put(vertices).flip(), GL_STATIC_DRAW);

        int id = genTexture();
        while (!glfwWindowShouldClose(window)) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glViewport(0, 0, width, height);
            glMatrixMode(GL_PROJECTION);
            float aspect = (float) width / height;
            glLoadIdentity();
            glOrtho(-aspect, aspect, -1, 1, -1, 1);

            {// Rendering
                glBindTexture(GL_TEXTURE_2D, id);
                glVertexPointer(2, GL_FLOAT, 4 * 4, 0L);
                glTexCoordPointer(2, GL_FLOAT, 4 * 4, 4 * 2);
                glDrawArrays(GL_QUADS, 0, 4);
            }

            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    }

    public int genTexture() {
        int id = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, id);
        ByteBuffer pixels = BufferUtils.createByteBuffer(512 * 512 * 4);

        for (int y = 0; y < 512; y++) {
            for (int x = 0; x < 512; x++) {
                pixels.put((byte) 255);
                pixels.put((byte) 0);
                pixels.put((byte) 0);
                pixels.put((byte) 255);
            }
        }
        pixels.flip();

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
        return id;
    }

    public static void main(String[] args) {
        new GuiMain2().run();
    }
}

When starting, it displays a white quad in the center of the screen. If textures were working, that quad would be red. And I can't get textures to work.

$\endgroup$
1
$\begingroup$

I figured it out myself, again: just add

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

behind the glTexImage2D command and it works as intended.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.