【问题标题】:When drawing a shape over my texture, OpenGL makes my texture semi-transparent在我的纹理上绘制形状时,OpenGL 使我的纹理半透明
【发布时间】:2012-06-18 21:07:55
【问题描述】:

概述

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

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

我想要什么:

我得到的却是:

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

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

代码片段

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

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(...) 可能包含我的答案。但我不明白不同的模式。我在正确的轨道上吗?

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

【问题讨论】:

  • 你的顶点颜色又是什么?请列出它们好吗?
  • 我希望能够使顶点具有任何 alpha 的任何颜色,但是对于上面的示例,两个是纯黑色 (GLKVector4Make(0, 0, 0, 1.0f) ) 另一个是完全透明的 (GLKVector4Make(0, 0, 0, 0.0f))。我习惯于把这个问题当作画布来处理,所以在已经渲染的东西上绘制半透明像素应该会影响它的 alpha。显然,在 OpenGL 中情况并非如此。
  • 我假设您并不是真的“在纹理上绘制三角形”,而是使用该纹理绘制一个三角形并由这些顶点颜色调制。这就是人们在 OpenGL 术语中的看法。使用白色 (1, 1, 1, 1) 作为第三个顶点颜色,一切都应该很好。
  • 啊,你正在做两个渲染通道。如果您设置黑色、黑色和白色并一次性渲染纹理三角形,会容易得多。
  • 实际上,对于您想要的(对于熟悉 OpenGL/DirectX 的任何人)来说,这是一种简单(直接且高效)的方式。使用像 OpenGL 这样的 API,有很多方法可以做很多事情。例如,对于您的“偏移绘图”,我建议使用多通道渲染并渲染另一个图像而不是渐变,我会建议使用多重纹理等等。

标签: ios opengl-es textures alpha glkit


【解决方案1】:

我不确定你的问题是否理解,所以我会在我得到它时尝试重述它。

  1. 您绘制棋盘格背景
  2. 您使用嘈杂的纹理绘制不透明的三角形纹理
  3. 您绘制了一个带有颜色渐变的三角形,您想影响它下面的颜色。

我知道是第 3 步导致您出现问题。

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

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

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

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

【讨论】:

  • 哇哦!你搞定了。就像我在上面的 cmets 中所说的那样,我无法弄清楚混合函数参数的正确组合。非常感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多