OpenGL 2D:glColor4 没有效果 - 我错过了什么?
我正在将游戏从 WP7 XNA 移植到 Android;使用 Canvas 一切正常,但速度太慢,所以我按照 Replica Island 和 SpriteMethodTest 的示例切换到 OpenGL ES。
我的问题是,当我在绘制纹理之前设置 glColor 时,我的纹理没有被着色或变得透明 - 它被完全忽略,并且纹理在加载的状态下绘制。纹理本身固有的所有颜色和透明度信息均已正确应用。我还使用 setPixels 以编程方式生成一些位图,并且我在那里遇到了完全相同的问题。
我仍然处于“OpenGL 只是魔法咒语”的理解阶段:-( 这使得遵循现有文档(似乎针对中级或高级编码员)相当令人沮丧。我希望复制/从这些示例中粘贴是可行的,但我一定错过了一些东西,而且我无法弄清楚它是什么,我已经到了代码盲的地步,无法区分他们的代码和我的代码之间的区别。 .
glColor4 显然可以在 复制岛,当我在同一个模拟器中运行它时,当不透明度发生变化时,所有文本都会淡入和淡出,就像它应该的那样,但它在我的代码中不起作用:-(
这是我的 GL 初始化代码:
surfaceCreated:
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
// gl.glDisable(GL10.GL_DITHER);
// gl.glDisable(GL10.GL_LIGHTING);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
sizeChanged:
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0.0f, width, 0.0f, height, 0.0f, 1.0f);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
我注释掉了。禁用抖动和照明,以防万一……但没有。
位图是从资源加载的:
gl.glGenTextures(1, mTextureNameWorkspace, 0);
textureName = mTextureNameWorkspace[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, srcBitmap, 0);
最后我的绘制代码:
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop(src), 0);
gl.glColor4f(tint.R(), tint.G(), tint.B(), tint.A());
((GL11Ext) gl).glDrawTexfOES(dst.left, screenHeight - dst.bottom, 0.0f, dst.width(), dst.height());
色调成员的范围是 0.0..1.0,因为它应该是。如果我设置了一个无效的纹理:
gl.glBindTexture(GL10.GL_TEXTURE_2D, -1);
...那么 OpenGL 会在正确的位置绘制正确的阴影和不透明度的矩形。
我必须尝试过 glBlendFunc 的所有可能参数组合 - 其中一些参数会部分影响透明度,但它们都不能正常工作,也不会导致 glColor 色调产生任何效果。
我想做的就是相当于:
PorterDuff.Mode mode = PorterDuff.Mode.MULTIPLY;
if (tint.A() < 1.0f && tint.R() == 1.0 && tint.G() == 1.0
&& tint.B() == 1.0)
mode = PorterDuff.Mode.DST_IN;
Paint paint = new Paint();
PorterDuffColorFilter cf = new PorterDuffColorFilter(tint, mode);
paint.setColorFilter(cf);
canvas.drawBitmap(texture.bitmap, srcRect, dstRect, Paint(tint));
I'm porting a game from WP7 XNA to Android; everything was working using Canvas but it was too slow so I've switched to OpenGL ES, following the examples of Replica Island and SpriteMethodTest.
My problem is that my textures aren't being coloured or made transparent when I set glColor immediately before drawing the texture - it is completely ignored and the texture is drawn in the state it was loaded. All the colour and transparency information inherent in the texture itself is applied correctly. I'm also generating some bitmaps programatically using setPixels and I have exactly the same issue there.
I'm still at the "OpenGL is just magic spells" stage of understanding :-( which makes following the existing documentation, which seems to be aimed at mid- or high-level coders, rather frustrating. I'd hoped that copy/pasting from those samples would work, but I must have missed something and I can't work out what it is. I've got to the point where I'm code-blind and can't tell the difference between their code and mine.
glColor4 clearly works in Replica Island, when I run that in the same emulator all the text fades in and out when the opacity changes, just as it should. But it doesn't work in my code :-(
Here is my GL initialisation code:
surfaceCreated:
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
// gl.glDisable(GL10.GL_DITHER);
// gl.glDisable(GL10.GL_LIGHTING);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
sizeChanged:
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0.0f, width, 0.0f, height, 0.0f, 1.0f);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
I commented out disabling Dither and Lighting in case that was it... but no. It makes no difference.
Bitmaps are loaded from resources thus:
gl.glGenTextures(1, mTextureNameWorkspace, 0);
textureName = mTextureNameWorkspace[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, srcBitmap, 0);
And finally my draw code:
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop(src), 0);
gl.glColor4f(tint.R(), tint.G(), tint.B(), tint.A());
((GL11Ext) gl).glDrawTexfOES(dst.left, screenHeight - dst.bottom, 0.0f, dst.width(), dst.height());
The range of the tint members is 0.0..1.0 as it should be. If I set an invalid texture:
gl.glBindTexture(GL10.GL_TEXTURE_2D, -1);
...then OpenGL obligingly draws rectangles of the right shade and opacity in the right location.
I must have tried every combination of possible parameters for glBlendFunc - some of them partly affect the transparency, but none of them work properly and none of them cause the glColor tint to have any effect.
All I'm trying to do is the equivalent of:
PorterDuff.Mode mode = PorterDuff.Mode.MULTIPLY;
if (tint.A() < 1.0f && tint.R() == 1.0 && tint.G() == 1.0
&& tint.B() == 1.0)
mode = PorterDuff.Mode.DST_IN;
Paint paint = new Paint();
PorterDuffColorFilter cf = new PorterDuffColorFilter(tint, mode);
paint.setColorFilter(cf);
canvas.drawBitmap(texture.bitmap, srcRect, dstRect, Paint(tint));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要使用
GL_REPLACE
,而是将glTexEnvf()
函数的第三个参数更改为GL_MODULATE
。我将参考我的 今天早些时候的回答。
Instead of using
GL_REPLACE
, change the third argument of yourglTexEnvf()
function toGL_MODULATE
.I'll refer to my earlier answer from today.