在我的纹理上绘制形状时,OpenGL使我的纹理半透明

时间:2012-06-15 19:03:52

标签: ios opengl-es textures alpha glkit

概述

我正在尝试通过组合一些图像和渐变来在我的游戏中构建图形。我开始使用Core Graphics,它运行得非常好,但非常慢。我现在尝试使用GLKit将它移植到OpenGL,我非常接近,但最后一个问题是:

我已经在屏幕上将纹理绘制成三角形。现在,在它的顶部,我想画一个渐变。为了绘制渐变,我认为最简单的方法是在两个顶点绘制一个黑色的三角形,在第三个顶点绘制一个完全透明的(alpha = 0)颜色。渐变渲染本身很好,但是当它渲染在纹理的顶部时,看起来好像纹理的alpha也会受到影响并导致背景显示。

我想要的是什么:

enter image description here

我得到了什么:

enter image description here

我承认我对OpenGL或GLKit不太熟悉。我怀疑三角形上每个点的纹理alpha都是(1 - 渐变alpha),这可以解释为什么纹理在角落里是完全不透明的,为什么纹理和渐变在中间似乎都有部分透明度。

我能用GLKit完成我想要的吗?它甚至与GLKit和GLKBaseEffect有关,还是我只是在OpenGL中做一些时髦的多纹理事情,我可以关闭它?

Code Snippets

在我的精灵类中渲染函数,用于绘制纹理:

typedef struct {
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

- (void)renderTriangleStrip:(TexturedVertex *)coordinates ofSize:(NSInteger)size {
    self.effect.texture2d0.envMode = GLKTextureEnvModeReplace;
    self.effect.texture2d0.name = self.textureInfo.name;
    self.effect.texture2d0.enabled = YES;

    self.effect.transform.modelviewMatrix = self.transform;

    [self.effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    long offset = (long)coordinates;        
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, size);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
}

在我的形状类中渲染函数,用于绘制带渐变的三角形:

typedef struct {
    CGPoint position;
    GLKVector4 color;
} ColoredVertex;

- (void)renderVertices:(ColoredVertex *)vertices ofSize:(NSInteger)size {
    self.effect.texture2d0.envMode = GLKTextureEnvModeDecal;
    self.effect.texture2d0.enabled = NO;

    self.effect.useConstantColor = NO;

    self.effect.transform.modelviewMatrix = self.transform;

    [self.effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribColor);

    long offset = (long)vertices;
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ColoredVertex), (void *) (offset + offsetof(ColoredVertex, position)));
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(ColoredVertex), (void *) (offset + offsetof(ColoredVertex, color)));

    glDrawArrays(GL_TRIANGLE_FAN, 0, size);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribColor);
}

提前感谢您的帮助!

编辑:似乎glBlendFunc(...)可能包含我的答案。但我不明白不同的模式。我在这里走在正确的轨道上吗?

编辑:还没有解决方案,但我已在问题中更新了我的假设。

1 个答案:

答案 0 :(得分:1)

我不确定你的问题是什么,所以我会在我得到它的时候尝试重述它。

  1. 您绘制检查背景
  2. 使用嘈杂的纹理绘制不透明的三角形纹理
  3. 您绘制一个带有颜色渐变的三角形,您想要影响它下面的颜色。
  4. 我知道通过3会导致你出现问题。

    如果是这样,获取参考图像需要做的是使用适当的混合模式和适当的顶点颜色绘制渐变三角形。在您的情况下,两种黑色和一种白色。

    对于您的情况,混合将使用以下方式设置:

    glEnable(GL_BLEND);
    glBlendFunc(GL_ZERO, GL_SRC_COLOR);
    

    这将指示OpenGL绘制三角形,以便生成的像素颜色由dst = 0 * src + src * dst给出,即dst = dst * src