GLUT 单个像素操作产生意想不到的结果

GLUT individual pixel manipulation produces unexpected result

为了学习,我正在使用 GLUT 访问单个像素数据,并通过遍历 window 中的所有像素手动设置像素颜色,如下所示(省略了一些不相关的代码):

void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, WIDTH, 0.0, HEIGHT);

}

void display() {
    glClear(GL_COLOR_BUFFER_BIT);

    for (int i = 0; i < WIDTH; i++) {
        for (int j = 0; j < HEIGHT; j++) {

            glPointSize(1.0f);
            glColor3f(255, 0, 0);
            glBegin(GL_POINTS);
            glVertex2i(i, j);
            glEnd();
        }
    }    
    glutSwapBuffers();
}

void timer(int obsolete) {
    glutPostRedisplay();
    glutTimerFunc(16, timer, 0);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(WIDTH, HEIGHT);

    glutCreateWindow("GLUT Test");

    init();

    glutDisplayFunc(display);
    timer(0);
    glutMainLoop();

    return 0;
}

我希望得到一个完全红色的像素 window,但我得到了一些不同的东西 - window 带有黑色垂直条纹,好像水平 for 循环突然跳过了一些行。

知道我在这里做错了什么吗?我怀疑它可能与“内部”某处的 float 到 int 转换有关,但我不确定要搜索什么。

编辑:我发现如果我在运行时将 window 的大小调整为宽度减少一个像素,那么这些黑色条纹撕裂就会消失。

您将投影设置为左边缘为 0,右边缘为 WIDTH。请注意,您的像素是具有面积的小方块,这意味着 0.0 映射到最左侧像素的 左边缘 ,而 WIDTH 映射到右边缘最右边的像素。整数坐标将恰好位于两个像素之间的中间。并且在转换过程中由于一些数值精度损失,您可能最终将两个相邻点四舍五入到同一像素。

您可以在绘制点时将 0.5 添加到 x 和 y,或者将您的正投影移动半个像素,以便将整数映射到像素中心:

 Ortho(-0.5f, WIDTH-0.5f, -0.5f, HEIGHT-0.5f, ...);