You need to enable JavaScript to run this app. 如何在现代OpenGL中基于2D数组绘制图像,glVertex2f参数怎么用?
优惠活动
大模型
产品
解决方案
定价
更多

如何在现代OpenGL中基于2D数组绘制图像,glVertex2f参数怎么用?

问题解答

1. glVertex2f参数逻辑

默认情况下,OpenGL使用标准化设备坐标(NDC),传入glVertex2f(x,y)的x、y取值范围都在[-1, 1]之间:

  • x=-1对应窗口左边缘,x=1对应窗口右边缘
  • y=-1对应窗口下边缘,y=1对应窗口上边缘
    超出这个范围的坐标会被直接裁剪,不会渲染到窗口上,这也是你原来代码看不到任何红色点的核心原因:你传入的0~32的坐标远大于1,几乎所有点都在视口外。

2. 你的代码存在的前置错误

首先要修正两个逻辑顺序问题,否则后续调整也不会生效:

  • glutInitWindowSize必须放在glutCreateWindow之前调用,否则窗口大小设置不会生效
  • 所有绘制相关的代码(glClear、绘制点、glFlush等)必须放在你注册的displaySpectrogram回调函数里,glutMainLoop是事件死循环,写在它之后的代码永远不会被执行

3. 两种实现全屏红色的方案

方案1:调整坐标适配默认NDC(无需修改投影矩阵)

把循环里的i、j坐标转换到[-1, 1]区间即可,修改循环部分代码:

glBegin(GL_POINTS);              
glColor3f(1.0f, 0.0f, 0.0f); // Red
for (int i = 0; i < 32; i++)
{
    for (int j = 0; j < 32; j++)
    {
        // 把0~31的像素坐标转换为[-1,1]的NDC坐标
        float x = (i / 31.0f) * 2.0f - 1.0f;
        float y = (j / 31.0f) * 2.0f - 1.0f;
        glVertex2f(x, y);
    }
}
glEnd();

如果想要更方便的直接用像素坐标绘制,可以修改正交投影矩阵,在初始化阶段添加以下代码:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 设置正交投影:左下角(0,0),右上角(32,32),和窗口像素一一对应
glOrtho(0, 32, 0, 32, -1, 1);
glMatrixMode(GL_MODELVIEW);

添加后你原来的glVertex2f(i,j)写法可以直接使用,无需坐标转换。

方案2:纹理实现(效率更高,适合后续动态修改像素内容)

相比逐点绘制,纹理方案更适合像素级渲染场景,步骤如下:

  1. 初始化阶段创建32x32的纹理对象,填充全红的像素数据
  2. 绘制阶段渲染一个覆盖整个NDC范围的四边形,绑定纹理后映射到四边形上
    示例代码片段:
// 初始化阶段创建纹理
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
// 构造32x32全红的像素数据(RGBA格式)
unsigned char pixels[32*32*4];
for(int i=0; i<32*32; i++){
    pixels[i*4 + 0] = 255; // R
    pixels[i*4 + 1] = 0;   // G
    pixels[i*4 + 2] = 0;   // B
    pixels[i*4 + 3] = 255; // A
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// 绘制阶段
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
// 绘制覆盖整个窗口的四边形,对应纹理四个角
glTexCoord2f(0,0); glVertex2f(-1,-1);
glTexCoord2f(1,0); glVertex2f(1,-1);
glTexCoord2f(1,1); glVertex2f(1,1);
glTexCoord2f(0,1); glVertex2f(-1,1);
glEnd();
glDisable(GL_TEXTURE_2D);

后续如果要修改窗口像素内容,只需要更新pixels数组后调用glTexSubImage2D更新纹理即可,比逐点绘制性能高很多。

内容的提问来源于stack exchange,提问作者yarin Cohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 22:54:04