如何在OpenGL中绘制单个像素?

20

有人能告诉我如何在坐标(100,200)处绘制一个白色像素吗?

我正在使用GLUT,目前已经找出如何打开一个空白窗口。一旦我弄清如何画像素,我将使用它来实现Bresenham线条绘制算法。(是的,我知道OpenGL可以画线条。但我需要自己实现)。

#include <stdio.h>
#include <GL/glut.h>

static int win(0);

int main(int argc, char* argv[]){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);

    //step 2. Open a window named "GLUT DEMO"
    win = glutCreateWindow("GLUT DEMO");
    glClearColor(0.0,0.0,0.0,0.0); //set background

    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    glutMainLoop();
}

1
这是一个与OpenGL相关的奇怪操作,也不是它的设计初衷。你为什么要使用OpenGL呢?我想你可以创建一个包含线条像素的纹理,并用该纹理绘制三角形/四边形,或者为每个像素渲染一个点。 - user253751
1
你是否需要使用已弃用的Legacy OpenGL 1.0,还是可以使用现代OpenGL v3.3或更高版本? - Francis Cugler
3个回答

31

glVertex2i(x,y);

需要在以下上下文中使用:

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowPosition(80, 80);
glutInitWindowSize(500,500);

glutCreateWindow("A Simple OpenGL Program");

glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, 500.0, 500.0,0.0 );

glBegin(GL_POINTS);
   glColor3f(1,1,1);
   glVertex2i(100,100);
glEnd();

1
另外一个有效的答案,但请注意,如果glPointSize不是1(默认值),您可以绘制超过一个像素。 - MuertoExcobito
2
请注意,据我所了解,此答案使用的是OpenGL的旧代码。设备的驱动程序必须支持OpenGL的兼容性配置文件才能使其正常工作。 - HopefullyHelpful

5

通过设置剪切矩形并进行清除操作,可以轻松实现这一点,这将仅清除剪切矩形中指定的区域。例如:

glEnable(GL_SCISSOR_TEST);
glScissor(100, 200, 1, 1);
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
// Remember to disable scissor test, or, perhaps reset the scissor rectangle:
glDisable(GL_SCISSOR_TEST); 

这太棒了,现在我有一个十字准心,而不需要引入复杂的UI层。 - Avi

2
使用现代OpenGL,你可以将glScissor()与填充整个屏幕的四边形结合起来。
着色器可以非常简单:
// Vertex Shader
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

// Fragment Shader
#version 330 core
out vec4 FragColor;
uniform vec4 inColor;
void main()
{
    FragColor = inColor;
}

在使用您偏爱的方法(GLFW,GLAD,GLEN等)进行OpenGL和Windows初始化后,创建一个四边形(实际上是两个三角形),以覆盖整个屏幕,如下所示:
float vertices[] = {
    -1.0f, -1.0f, 0.0f,
     1.0f, -1.0f, 0.0f,
     1.0f,  1.0f, 0.0f,
    -1.0f, -1.0f, 0.0f,
     1.0f,  1.0f, 0.0f,
    -1.0f,  1.0f, 0.0f
};

首先创建缓冲区,编译着色器,绑定着色器程序和VAO。
然后使用:

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

您的绘图代码应该像这样,在x = 100,y = 100处绘制一个绿色像素:
GLint transformLoc = glGetUniformLocation(shaderProgramId, "inColor");
glUniform4f(transformLoc, 0.0f, 1.0f, 0.0f, 1.0f);

glEnable(GL_SCISSOR_TEST);
glScissor(100, 100, 1, 1); // position of pixel
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisable(GL_SCISSOR_TEST);

我写了一个基于OpenGL的小型图形渲染类,其中有代码可以做到这一点。它的核心函数是putPixel(),它接收x/y坐标和颜色,在屏幕上绘制单个像素。请随意查看代码:https://github.com/amengol/MinGL


不确定为什么要使用着色器来绘制全屏四边形,而不是像我的答案中那样使用清除。清除会更有效率,更容易实现,并且可以在传统和现代 OGL 中工作。 - MuertoExcobito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接