3
votes

I'm trying to convert OGL ES 1.1. code to GLKit. GLKit offers a pair of texture slots:

  1. texture2d0
  2. texture2d1

Each texture has an env mode:

  1. GLKTextureEnvModeReplace,
  2. GLKTextureEnvModeModulate,
  3. GLKTextureEnvModeDecal

Normally, you leave texture2d1 blank, and just set texture2d0. I assumed - from reading Apple's docs - that 2d1 was for blending/combining/modifying textures. Since GLKit is "merely" sitting on top of shaders, and it's standard for each shader to have a pair of texture slots - the "incoming" slot representing what's already on the material, and the "modification" slot representing the stuff that the shader is going to use as parameter to modiffy the material.

But that doesn't seem to work.

I tried:

self.baseEffect.texture2d0.envMode = GLKTextureEnvModeReplace;
self.baseEffect.texture2d0.target = GLKTextureTarget2D;
self.baseEffect.texture2d0.name = [earthTextureDefault name];

self.baseEffect.texture2d1.envMode =  GLKTextureEnvModeModulate;
self.baseEffect.texture2d1.target = GLKTextureTarget2D;
self.baseEffect.texture2d1.enabled = TRUE;
self.baseEffect.texture2d1.name = [textureClouds name];

...and all I got was a black non-texture. Either texture, placed into 0 (with nothing in 1), works fine. The second texture is shaded alpha-to-white, where the first texture is all opaque, but with a fairly rich pallette.

What I'd really like to do is start applying dynamicly-generated / updated blends, efficiently. e.g.:

  1. load a base texture
  2. load a second texture
  3. load a blend-mask that blends between them
  4. ...update the blend-mask frame-by-frame. Without having to re-upload the first two textures

NB: I'm not looking to throw-away GLKit and write custom shaders for this instead. I want to understand how GLKit works - and by the looks of things it should be a LOT easier to maintain for simple things like this than if I go around writing a bunch of shaders.

1
Would you be willing to entertain something that handles the blending mode shaders for you? github.com/BradLarson/GPUImage You could extract a texture out of that at the end, if you still wished to use this within your GLKView's scene.Brad Larson♦
Looks impressive but doesn't answer the core question: how do we use GLKit's built-in features?Adam
Sure, I'd be curious how this works myself, because I've only dealt with the shaders and textures directly via OpenGL ES. I haven't spent much time at all with the GLKit abstractions. Just thought I'd throw that out there in case you got frustrated with this and needed something in the near term.Brad Larson♦
No, if I give up on GLKit, I'd write shaders.Adam
No one seems to know, and Apple (in response to my bug report asking for docs) refuses to document GLKit further, even the bits where the docs are clearly missing. So i gave up and ported everhthing to shaders...Adam

1 Answers

0
votes

As noted in the documentation, GLKTextureEnvModeModulate multiplies the textures' color values together, which is probably why you're seeing black. If you want to overlay a texture with alpha on top of a texture without, use GLKTextureEnvAttribDecal instead.

I don't see a way to do your dynamic blend-mask idea using only GLKit API, but you don't have to toss it out entirely. Try something like this:

  1. Load three texture objects: your base texture, your second texture, and your blending mask.
  2. Create a framebuffer object whose color attachment is a fourth texture.
  3. Render to the texture FBO using a shader that fills it with the RGB values from the second texture and the alpha values from the blending mask.
  4. Use the base texture as texture0 and the FBO texture as texture1 with your GLKBaseEffect and render your main scene to the screen.
  5. Repeat steps 3-4 when you update your blending mask.

It's probably less efficient than a fragment shader that does it all in one rendering pass, but it should work.