OpenGL,GL_MODULATE和Multitexturing

Ara*_*yan 5 opengl-es texturing multitexturing

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

这是纹理(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);
Run Code Online (Sandbox Code Playgroud)

这是一个OpenGL问题,但iOS项目可供感兴趣的人使用:http://dl.dropbox.com/u/33811812/cocos2d/OpenGLTest.zip

编辑: 从红皮书:

如果你是多纹理并且使用glTexCoord*(),则要设置第一个纹理单元的纹理坐标.换句话说,使用glTexCoord*()相当于使用glMultiTexCoord*(GL_TEXTURE0,...)

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

Ara*_*yan 6

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

  • 在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);
Run Code Online (Sandbox Code Playgroud)

结果如下:

作品