gpt4 book ai didi

Opengl 像素完美 2D 绘图

转载 作者:太空宇宙 更新时间:2023-11-04 12:01:41 26 4
gpt4 key购买 nike

我正在开发 2d 引擎。它已经工作得很好,但我不断收到像素错误。

例如,我的窗口是 960x540 像素,我从 (0, 0) 到 (959, 0) 画一条线。我希望扫描线 0 上的每个像素都会被设置为一种颜色,但事实并非如此:最右边的像素没有被绘制。当我垂直绘制到像素 539 时,同样的问题。我确实需要绘制到 (960, 0) 或 (0, 540) 才能绘制它。

由于我出生在像素时代,我确信这不是正确的结果。当我的屏幕大小为 320x200 像素时,我可以从 0 到 319 以及从 0 到 199 进行绘制,并且我的屏幕将充满。现在我最终得到一个屏幕,其中右侧/底部像素未绘制。

这可能是由于不同的原因造成的:我期望 opengl 线基元从一个像素绘制到另一个像素(包含),最后一个像素实际上是排他的?是这样吗?我的投影矩阵不正确?我有一个错误的假设,即当我有 960x540 的后缓冲区时,实际上多了一个像素?还有别的吗?

有人可以帮我吗?我已经研究这个问题很长时间了,每次当我认为没问题的时候,过了一段时间我发现事实并非如此。

这是我的一些代码,我试图尽可能地精简它。当我调用线路函数时,每个坐标都会添加 0.375、0.375,以使其在 ATI 和 nvidia 适配器上都正确。

int width = resX();
int height = resY();

for (int i = 0; i < height; i += 2)
rm->line(0, i, width - 1, i, vec4f(1, 0, 0, 1));
for (int i = 1; i < height; i += 2)
rm->line(0, i, width - 1, i, vec4f(0, 1, 0, 1));

// when I do this, one pixel to the right remains undrawn

void rendermachine::line(int x1, int y1, int x2, int y2, const vec4f &color)
{
... some code to decide what std::vector the coordinates should be pushed into
// m_z is a z-coordinate, I use z-buffering to preserve correct drawing orders
// vec2f(0, 0) is a texture-coordinate, the line is drawn without texturing
target->push_back(vertex(vec3f((float)x1 + 0.375f, (float)y1 + 0.375f, m_z), color, vec2f(0, 0)));
target->push_back(vertex(vec3f((float)x2 + 0.375f, (float)y2 + 0.375f, m_z), color, vec2f(0, 0)));
}

void rendermachine::update(...)
{
... render target object is queried for width and height, in my test it is just the back buffer so the window client resolution is returned
mat4f mP;
mP.setOrthographic(0, (float)width, (float)height, 0, 0, 8000000);

... all vertices are copied to video memory

... drawing
if (there are lines to draw)
glDrawArrays(GL_LINES, (int)offset, (int)lines.size());

...
}

// And the (very simple) shader to draw these lines

// Vertex shader
#version 120
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 mP;
varying vec4 vColor;
void main(void) {
gl_Position = mP * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}

// Fragment shader
#version 120
#ifdef GL_ES
precision highp float;
#endif
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor.rgb;
}

最佳答案

在 OpenGL 中,线条使用“菱形退出”规则进行光栅化。这几乎与结束坐标是排他的相同,但不完全...

这是 OpenGL 规范的规定: http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html

另请参阅 OpenGL 常见问题解答,http://www.opengl.org/archives/resources/faq/technical/rasterization.htm ,项目“14.090 如何获得线条的精确像素化?”。它说“OpenGL 规范允许广泛的线条渲染硬件,因此精确的像素化可能根本不可能。”

许多人会认为您根本不应该在 OpenGL 中使用线条。他们的行为基于古老的 SGI 硬件的工作方式,而不是基于什么有意义。 (宽度 >1 的线条几乎不可能以看起来不错的方式使用!)

关于Opengl 像素完美 2D 绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40842896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com