OpenGL 2D:glColor4 没有效果 - 我错过了什么?

发布于 2024-11-26 04:51:38 字数 3391 浏览 1 评论 0原文

我正在将游戏从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞慾 2024-12-03 04:51:38

不要使用 GL_REPLACE,而是将 glTexEnvf() 函数的第三个参数更改为 GL_MODULATE

我将参考我的 今天早些时候的回答

Instead of using GL_REPLACE, change the third argument of your glTexEnvf() function to GL_MODULATE.

I'll refer to my earlier answer from today.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文