OpenGL ES 渲染位图字形作为纹理定位问题

发布于 2024-09-24 13:07:47 字数 2159 浏览 1 评论 0原文

我只是测试这个东西,所以我不需要替代方法(没有 GL 扩展)。只是希望有人能看到我使用 GLES 时的一个明显错误。

我想要获取小于 32x32 的字形位图(宽度和高度不一定是 2 的幂)并将其放入纹理中,以便我可以渲染它。我首先创建了一个空的 32x32 纹理,然后将像素复制到更大的纹理中。

Gluint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTextImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 32, 32, 0,
              GL_ALPHA, GL_UNSIGNED_BYTE NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
                GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.pixels());

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParamteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParamteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

然后我尝试使用纹理坐标仅绘制纹理的位图部分:

const GLfloat vertices[] = {
  x + bitmap.width(), y + bitmap.height(),
  x, y + bitmap.height(),
  x, y,
  x + bitmap.width(), y
};

const GLfloat texCoords[] = {
  0, bitmap.height() / 32,
  bitmap.width() / 32, bitmap.height() / 32,
  0, 0,
  bitmap.width() / 32, 0
};

const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

现在,如果一切顺利,由顶点创建的正方形的大小将与纹理的位图部分的大小相同,并且它将准确地绘制我的位图。

举例来说,我的字形是 16x16,那么它应该占据 32x32 纹理的左下象限。那么 texCoords 似乎是正确的 (0, 0.5)、(0.5, 0.5)、(0, 0) 和 (0.5, 0)。

然而我的 12x12 'T' 字形看起来像这样: alt text

有人知道为什么吗?

顺便提一句。我首先为 2D 工作设置投影矩阵,如下所示:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 480, 800, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslate(0.375f, 0.375f, 0.0f); // for exact pixelization

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA);
glEnable(GL_TEXTURE_2D);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

I'm just testing this stuff out, so I don't need an alternate approach (no GL extensions). Just hoping someone sees an obvious mistake in my usage of GLES.

I want to take an bitmap of a glyph that is smaller than 32x32 (width and height are not necessarily powers of 2) and put it into a texture so I can render it. I've first created an empty 32x32 texture then I copy the pixels into the larger texture.

Gluint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTextImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 32, 32, 0,
              GL_ALPHA, GL_UNSIGNED_BYTE NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
                GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.pixels());

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParamteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParamteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Then I try to draw only the bitmap portion of the texture using the texture coordinates:

const GLfloat vertices[] = {
  x + bitmap.width(), y + bitmap.height(),
  x, y + bitmap.height(),
  x, y,
  x + bitmap.width(), y
};

const GLfloat texCoords[] = {
  0, bitmap.height() / 32,
  bitmap.width() / 32, bitmap.height() / 32,
  0, 0,
  bitmap.width() / 32, 0
};

const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

Now if all were well in the world, the size of the square created by the vertices would be the same size as the bitmap portion of the texture and it would draw my bitmap exactly.

Lets say for example that my glyph was 16x16, then it should take up the bottom left quadrant of the 32x32 texture. Then the texCoords would seem to be correct with (0, 0.5), (0.5, 0.5), (0, 0) and (0.5, 0).

However my 12x12 'T' glyph looks like this: alt text

Anyone know why?

BTW. I start by setting up the projection matrix for 2D work as such:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 480, 800, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslate(0.375f, 0.375f, 0.0f); // for exact pixelization

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA);
glEnable(GL_TEXTURE_2D);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叶落知秋 2024-10-01 13:07:47

顶点坐标和纹理坐标之间的映射似乎是混淆的。尝试将顶点坐标更改为:

const GLfloat vertices[] = {
  x, y + bitmap.height(),
  x + bitmap.width(), y + bitmap.height(),
  x, y,
  x + bitmap.width(), y
};

顺便说一句:
我认为在您的情况下您不需要通过顶点索引走路线。更简单的是调用 glDrawArrays:(

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

因为您已经设置了 glVertexPointer 和 glTexCoordPointer)。

The mapping between vertex coordinates and texture coordinates seems to be mixed up. Try changing your vertex coordinates to:

const GLfloat vertices[] = {
  x, y + bitmap.height(),
  x + bitmap.width(), y + bitmap.height(),
  x, y,
  x + bitmap.width(), y
};

As an aside:
I don't think you need to go the route via vertex indices in your case. Easier would be a call to glDrawArrays:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

(as you have already set up your glVertexPointer and glTexCoordPointer).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文