2012-09-03 22 views
9

Puedo mezclar dos texturas con diferentes modos de fusión en el sombreador de fragmentos cuando ambas texturas cubren los mismos rectángulos. Pero ahora mi problema es que una textura es un rectángulo simple sin rotación y la otra textura es otro rectángulo con rotación/escala y traslación. ¿Cómo combino estas texturas de la manera que quiero? (En la foto)¿Cómo puedo combinar dos texturas con diferentes coordenadas en OpenGL ES 2.0 en iPhone?

sé cómo hacer esto ...

enter image description here

Pero no está seguro de cómo hacer esto ...

enter image description here

Por mezcla de texturas en un rectángulo (la primera imagen), utilicé el siguiente código ...

Código de objetivo C ...

- (void) display { 
    [EAGLContext setCurrentContext:context]; 

    glBindFramebuffer(GL_FRAMEBUFFER, targetFBO); 

    glUseProgram(program); 

    glActiveTexture(GL_TEXTURE2); 
    glBindTexture(GL_TEXTURE_2D, textureTop); 

    glActiveTexture(GL_TEXTURE3); 
    glBindTexture(GL_TEXTURE_2D, textureBot); 

    glUniform1i(inputTextureTop, 2); 
    glUniform1i(inputTextureBot, 3); 

    glUniform1f(alphaTop, alpha); 

    glEnable (GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

    glVertexAttribPointer(position, 2, GL_FLOAT, 0, 0, imageVertices); 
    glVertexAttribPointer(inputTextureCoordinate, 2, GL_FLOAT, 0, 0, textureCoordinates); 

    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER]; 
} 

Vertex Shader ...

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 

varying vec2 textureCoordinate; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
} 

Fragmento de sombreado ...

varying highp vec2 textureCoordinate; 

uniform sampler2D inputTextureTop; 
uniform sampler2D inputTextureBot; 

uniform highp float alphaTop; 

void main() 
{ 
    lowp vec4 pixelTop = texture2D(inputTextureTop, textureCoordinate); 
    lowp vec4 pixelBot = texture2D(inputTextureBot, textureCoordinate); 

    gl_FragColor = someBlendOperation(pixelTop, pixelBot); 
} 
+0

Puede ser que pueda hacer alguna operación geométrica en el sombreador de fragmentos para obtener el XY del píxel superior. – abix

+3

Hola, estoy teniendo el mismo problema, la solución @Max no tiene sentido para lidiar con la necesidad de dibujar la imagen superior con un tamaño y rotación diferente a la imagen de fondo, ¿cómo lo logró? – Eyal

Respuesta

7

usted tiene que pasar 2 coordenadas de textura para Shader y modificar shader

Añadir a ObjectiveC

glVertexAttribPointer(inputTextureCoordinate2, 2, GL_FLOAT, 0, 0, textureCoordinates2); 

Vertex Shader

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 
attribute vec4 inputTextureCoordinate2; 

varying vec2 textureCoordinate; 
varying vec2 textureCoordinate2; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
    textureCoordinate2 = inputTextureCoordinate2.xy; 
} 

Frag Shader

varying highp vec2 textureCoordinate; 
varying highp vec2 textureCoordinate2; 

uniform sampler2D inputTextureTop; 
uniform sampler2D inputTextureBot; 

uniform highp float alphaTop; 

void main() 
{ 
    lowp vec4 pixelTop = texture2D(inputTextureTop, textureCoordinate); 
    lowp vec4 pixelBot = texture2D(inputTextureBot, textureCoordinate2); 

    gl_FragColor = someBlendOperation(pixelTop, pixelBot); 
} 

B No es necesario que TW inputTextureCoordinate sea vec4 pero podría ser vec2

+0

¡Gracias Max! ¡Trabajado como un encanto! – abix

+0

@Max, tengo una pregunta similar, ¿podrían ayudarme por favor? Gracias. –

+2

¿Lo has publicado en alguna parte? – Max

4

Si está mezclando dos texturas en la misma primitiva, a continuación, se pueden mezclar los colores en el sombreador.

Sin embargo, si desea mezclar dos primitivas diferentes, entonces lo que realmente desea utilizar es la fusión de hardware (GL_BLEND).

Dibuje la imagen inferior por sí mismo, luego habilite la combinación y dibuje la imagen superior. El valor alfa de la imagen superior controla cuán transparente será.

En realidad, no desea intentar dibujar los dos cuatrillos en la misma llamada, ya que no utilizan las mismas coordenadas.

+1

Sí, puedo hacer eso. Pero usando GL_BLEND solo puedo hacer una cierta cantidad de operaciones de fusión. Lo que realmente quiero hacer es definir la fórmula de fusión (como los modos de fusión de Photoshop ... multiplicar, superposición, pantalla, etc.). Estaba pensando si podría hacer alguna transformación 2D en textureCoordinate.xy antes de pasarla a la función texture2D (inputTextureTop, textureCoordinate), para hacerla rotar, traducir y escalar? – abix

+0

abix Tengo un código opencl que solíamos hacer una búsqueda de transformación inversa de coords de origen para píxeles de destino aquí hay un enlace fundamental https://gist.github.com/victusfate/bdbed266a73a19f81a94 –

Cuestiones relacionadas