LWJGL 3 glReadPixles always reports 255 255 255 255

Started by Moocow9m, April 25, 2016, 17:34:18

Previous topic - Next topic

Moocow9m

Ok. Now returning 255,255,255 again though... glReadPixels(X, 600-Y-1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, rgb);

Kai

I see. The general problem here is that rasterizing a point at (1, 1) does not lead to the pixel (1, height-2) being rendered to, due to OpenGL's point rasterization rules. Rendering (1, 1) will fill pixel (1, height-1).
And likewise (0, 0) does not fill pixel (0, height-1), but no pixel at all.
This is because (0, 0) does not denote the top-left pixel but rather the top-left corner of the viewport, which is the top-left corner of the top-left pixel. It is NOT the CENTER of the pixel.
If you want to make absolutely sure that the pixel is hit when rasterizing a point with GL_POINTS, then you must use glVertex2f(0.5f, 0.5f) or in your case glVertex2f(1.5f, 1.5f), that is, add a 0.5f offset to the position, which is just the half-size of a pixel. The former would hit pixel (0, height-1) and the latter would hit pixel (1, height-2)

(I just tested it with a demo program myself):
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.nio.ByteBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;
public class ForumDemo {
    public static void main(String[] args) {
        int width = 600;
        int height = 600;
        glfwInit();
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
        long window = glfwCreateWindow(width, height, "", NULL, NULL);
        GLFWKeyCallback keyCallback;
        glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                    glfwSetWindowShouldClose(window, true);
            }
        });
        glfwMakeContextCurrent(window);
        GL.createCapabilities();
        glClearColor(1, 1, 1, 1);
        while (!glfwWindowShouldClose(window)) {
            glClear(GL_COLOR_BUFFER_BIT);
            glViewport(0, 0, width, height);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0, width, height, 0, -1, +1);
            glColor3f(0.0f, 0.0f, 1.0f);
            glBegin(GL_POINTS);
            glVertex2f(1.5f, 1.5f); // <- make sure pixel (1, height-1-1) is rendered to
            glEnd();
            glfwSwapBuffers(window);
            glReadBuffer(GL_FRONT);
            ByteBuffer rgb = BufferUtils.createByteBuffer(3);
            glReadPixels(1, height-1-1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, rgb);
            System.out.println((rgb.get(0) & 0xFF) + ", " + (rgb.get(1) & 0xFF) + ", " + (rgb.get(2) & 0xFF));
            glfwPollEvents();
        }
    }
}

Moocow9m

Just to make sure, add .5 to all points if I want to read them?

Kai

Quote from: Moocow9m on April 25, 2016, 20:26:07
Just to make sure, add .5 to all points if I want to read them?
Yes, but I would rather do the translation as part of the projection matrix. You can do the following right after glOrtho():
glTranslatef(0.5f, 0.5f, 0);

Since you are setting up a pixel-perfect projection anyway, this will not hurt.
Afterwards, when you glVertex2f(x, y) with integer coordinates then this will correctly hit the corresponding pixel.
So: no need to add a 0.5f offset to each vertex.

Moocow9m

Quote from: Kai on April 25, 2016, 20:37:49
Quote from: Moocow9m on April 25, 2016, 20:26:07
Just to make sure, add .5 to all points if I want to read them?
Yes, but I would rather do the translation as part of the projection matrix. You can do the following right after glOrtho():
glTranslatef(0.5f, 0.5f, 0);

Since you are setting up a pixel-perfect projection anyway, this will not hurt.
Afterwards, when you glVertex2f(x, y) with integer coordinates then this will correctly hit the corresponding pixel.
So: no need to add a 0.5f offset to each vertex.
So not in the while loop?

Kai

Correct. :) Not in the while loop. Just once directly after glOrtho().

Moocow9m

Thanks I will try when I get home in ~2 hours.