【问题标题】:OpenGL, GL_MODULATE and MultitexturingOpenGL、GL_MODULATE 和多重纹理
【发布时间】:2023-03-30 19:37:01
【问题描述】:

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

这是纹理(GL_TEXTURE0 和 GL_TEXTURE1):

结果是这样的:

仅使用顶部的红色像素。我尝试在顶部仅使用 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() 等。

【问题讨论】:

  • 您似乎在寻找glClientActiveTexture
  • 太棒了!工作,除了在绘图后设置glClientActiveTexture(GL_TEXTURE0); 会导致它再次失败。我还有其他需要恢复状态的绘制方法。如何做到这一点?
  • 我也看过 glVertexAttribPointer 但我不知道如何使用它来指定 GL_TEXTURE1 的坐标...
  • 我已经更新了我的代码,非常感谢任何帮助!

标签: opengl-es texturing multitexturing


【解决方案1】:

终于!解决方案是我必须做三件事:

  • 在 glTexCoordPointer 之前将 glClientActiveTexture(GL_TEXTURE*) 用于 0 和 1
  • 对每个纹理也使用 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);

结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多