OpenGL、GL_MODULATE 和多重纹理

发布于 2025-01-01 14:40:34 字数 2038 浏览 3 评论 0原文

我已经成功绘制了一个多纹理多边形,但不幸的是,整个纹理区域仅使用了重叠纹理的第一个像素。

以下是纹理(GL_TEXTURE0 和 GL_TEXTURE1):

icon overlay

结果是这样的:

result

仅位于顶部正在使用中。我尝试在顶部仅使用 1x1 蓝色像素,并且使用蓝色叠加得到相同的结果。

我的代码:

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

const CGPoint vertices[] = {
    ccp(0,0),
    ccp(100,0),
    ccp(0,100),
    ccp(100,100),
};

// This will flip the image for us as well
const CGPoint coordinates[] = {
    ccp(0,1),
    ccp(1,1),
    ccp(0,0),
    ccp(1,0),
};

// Config multitextures
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, icon.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, overlay.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

GLubyte points = 4;

// Draw the square
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, points);

// Revert back
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);

// glClientActiveTexture(GL_TEXTURE0); // breaks multitexturing
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_COLOR_ARRAY);

这是一个 OpenGL 问题,但感兴趣的人可以在这里找到 iOS 项目: http://dl.dropbox.com/u/33811812/cocos2d/OpenGLTest.zip

编辑: 摘自红皮书:

如果您使用多重纹理并使用 glTexCoord*(),则您正在设置 第一个纹理单元的纹理坐标。换句话说, 使用 glTexCoord*() 相当于使用 glMultiTexCoord* (GL_TEXTURE0,...)

有关如何传递坐标数组的任何提示? OpenGL ES 1.1 不支持 glBegin() 等。

I have successfully drawn a multi-textured polygon but unfortunately only the first pixel of the overlaying texture is being used across the entire texture area.

Here are the textures (GL_TEXTURE0 and GL_TEXTURE1):

icon overlay

The result is this:

result

Only the red pixel at the top is being used. I've tried with just a 1x1 blue pixel up the top and I get the same result with blue overlay.

My code:

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

const CGPoint vertices[] = {
    ccp(0,0),
    ccp(100,0),
    ccp(0,100),
    ccp(100,100),
};

// This will flip the image for us as well
const CGPoint coordinates[] = {
    ccp(0,1),
    ccp(1,1),
    ccp(0,0),
    ccp(1,0),
};

// Config multitextures
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, icon.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, overlay.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

GLubyte points = 4;

// Draw the square
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, points);

// Revert back
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);

// glClientActiveTexture(GL_TEXTURE0); // breaks multitexturing
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_COLOR_ARRAY);

This is an OpenGL problem, but the iOS project is available here for those interested: http://dl.dropbox.com/u/33811812/cocos2d/OpenGLTest.zip

EDIT:
From the Red Book:

If you are multitexturing and you use glTexCoord*(), you are setting
the texture coordinates for the first texture unit. In other words,
using glTexCoord*() is equivalent to using glMultiTexCoord*
(GL_TEXTURE0,...)

Any hints as to how to pass an array of coordinates? OpenGL ES 1.1 doesn't support glBegin() etc.

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

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

发布评论

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

评论(1

为你鎻心 2025-01-08 14:40:34

最后!解决方案是我必须做三件事:

  • 在 glTexCoordPointer 之前对 0 和 1 使用 glClientActiveTexture(GL_TEXTURE*
  • ) 对每个纹理也使用 glEnableClientState(GL_TEXTURE_COORD_ARRAY)
  • 恢复回 glClientActiveTexture(GL_TEXTURE0) 以避免与进一步的绘制发生冲突

这是代码有效:

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

const CGPoint vertices[] = {
    ccp(0,0),
    ccp(100,0),
    ccp(0,100),
    ccp(100,100),
};

// This will flip the image for us as well
const CGPoint coordinates[] = {
    ccp(0,1),
    ccp(1,1),
    ccp(0,0),
    ccp(1,0),
};

// Config multitextures
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, icon.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, overlay.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

GLubyte points = 4;

// Draw the square
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, points);

// Revert back
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_COLOR_ARRAY);

结果:

works

Finally! The solution was that I had to do three things:

  • Use glClientActiveTexture(GL_TEXTURE*) for 0 and 1 before the glTexCoordPointer
  • Use glEnableClientState(GL_TEXTURE_COORD_ARRAY) for each texture as well
  • Revert back to glClientActiveTexture(GL_TEXTURE0) to avoid conflicting with further draws

Here's the code that works:

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

const CGPoint vertices[] = {
    ccp(0,0),
    ccp(100,0),
    ccp(0,100),
    ccp(100,100),
};

// This will flip the image for us as well
const CGPoint coordinates[] = {
    ccp(0,1),
    ccp(1,1),
    ccp(0,0),
    ccp(1,0),
};

// Config multitextures
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, icon.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, overlay.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

GLubyte points = 4;

// Draw the square
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, points);

// Revert back
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_COLOR_ARRAY);

And the result:

works

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