【发布时间】: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