Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top