2011-06-04 17 views
5

Estoy tratando de aplicar diferentes texturas en el cubo con sombreadores usando samplerCube y textureCube.aplicando textura al cubo, textura diferente en cada cara del cubo

Pero no puedo obtener textura dibujada en las caras del cubo, solo aparece un solo color.

Screenshots of output

A continuación se muestra el código de sombreado:

Vertex Shader

String strVShader = "attribute vec4 a_position;" + 
      "uniform mat4 u_VPMatrix;" + 
      "attribute vec3 a_normal;" + 
      "varying vec3 v_normal;" + 
      "void main()" + 
      "{" + 
       "gl_Position = u_VPMatrix * a_position;" + 
       "v_normal = a_normal;" + 
      "}"; 

Fragmento Shader

String strFShader = "precision mediump float;" + 
      "uniform samplerCube u_texId;" + 
      "varying vec3 v_normal;" + 
      "void main()" + 
      "{" + 
       "gl_FragColor = textureCube(u_texId, v_normal);" + 
      "}"; 

definición de cubos

float[] cube = { 
     2,2,2, -2,2,2, -2,-2,2, 2,-2,2, //0-1-2-3 front 
     2,2,2, 2,-2,2, 2,-2,-2, 2,2,-2,//0-3-4-5 right 
     2,-2,-2, -2,-2,-2, -2,2,-2, 2,2,-2,//4-7-6-5 back 
     -2,2,2, -2,2,-2, -2,-2,-2, -2,-2,2,//1-6-7-2 left 
     2,2,2, 2,2,-2, -2,2,-2, -2,2,2, //top 
     2,-2,2, -2,-2,2, -2,-2,-2, 2,-2,-2,//bottom 
    }; 

short[] indeces = {0,1,2, 0,2,3, 
      4,5,6, 4,6,7, 
      8,9,10, 8,10,11, 
      12,13,14, 12,14,15, 
      16,17,18, 16,18,19, 
      20,21,22, 20,22,23, 
      }; 




float[] normals = { 
        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,  //front 
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,  // right 
        0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1,  //back 
        -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,  // left 
        0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,  // top     
        0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0,  // bottom 

    }; 

OnDrawFrame

public void onDrawFrame(GL10 arg0) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
     GLES20.glUseProgram(iProgId); 
     cubeBuffer.position(0); 
     GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, cubeBuffer); 
     GLES20.glEnableVertexAttribArray(iPosition); 

     GLES20.glVertexAttribPointer(iNormal, 3, GLES20.GL_FLOAT, false, 0, normBuffer); 
     GLES20.glEnableVertexAttribArray(iNormal); 

     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, iTexId); 
     GLES20.glUniform1i(iTexLoc, 0); 

     Matrix.setIdentityM(m_fIdentity, 0); 
     Matrix.rotateM(m_fIdentity, 0, -xAngle, 0, 1, 0); 
     Matrix.rotateM(m_fIdentity, 0, -yAngle, 1, 0, 0); 
     Matrix.multiplyMM(m_fVPMatrix, 0, m_fViewMatrix, 0, m_fIdentity, 0); 
     Matrix.multiplyMM(m_fVPMatrix, 0, m_fProjMatrix, 0, m_fVPMatrix, 0); 
     GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, m_fVPMatrix, 0); 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer); 
    } 

Creación de código Cubo Mapa

public int CreateCubeTexture() 
    { 
      ByteBuffer fcbuffer = null; 

      int[] cubeTex = new int[1]; 

      GLES20.glGenTextures(1, cubeTex, 0); 
      GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP,cubeTex[0]); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
      Bitmap img = null; 
      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick1); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 

      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      Log.d("alpha",""+img.hasAlpha()); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight() , 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 

      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick2); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 
      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 

      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick3); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 
      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 


      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick4); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 
      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 

      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick5); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 
      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GLES20.GL_RGBA,img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 

      img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick6); 
      fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); 
      img.copyPixelsToBuffer(fcbuffer); 
      fcbuffer.position(0); 
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); 
      fcbuffer = null; 
      img.recycle(); 

      GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_CUBE_MAP); 

      return cubeTex[0]; 
    } 

no soy capaz de entender dónde estoy haciendo error.

Si quieres ver el código completo.

Solución:

usados ​​mismo cubo de dibujo coordenadas de textura coordina

Gracias toda

CODE Link

+0

favor active su respuesta en una respuesta real a continuación. Puede marcarlo como aceptado después de dos días. Eso hará que la pregunta desaparezca de la pestaña de Preguntas sin respuesta. –

Respuesta

4

aunque la cuestión queda resuelta, me gustaría ofrecer una explicación de por qué usar coordenadas diferentes realmente ayudó (porque falta eso arriba).

Cuando implementé por primera vez el mapeo de cubos, tuve el mismo error, debido a una idea errónea de cómo funcionaban los mapas de cubos. Cube-map es internamente un conjunto de 6 texturas 2D, dispuestas en seis caras de un cubo. Desde un punto de vista matemático, define una función de búsqueda, donde el argumento es 3D dirección y la salida es de color RGBA.

Esto es importante, porque en el ejemplo anterior, el argumento para la búsqueda era normal. Normal es una dirección, que es correcta. Pero lo normal también es constante en toda la cara del cubo (excepto cuando se calculan las normales de estilo de sombreado uniforme, que no era el caso). Si lo normal (entrada a la búsqueda) es constante, eso significa, por supuesto, que la salida (color) también debe ser constante. Mi concepto erróneo en esto fue que supuse que OpenGL de alguna manera tendría en cuenta la posición y la dirección, pero desafortunadamente no es el caso.

Lo que interesa en este caso en particular es que uno puede usar cubeMap (posición) o cuboMap (posición + dirección), y obtendrá resultados bastante similares.Es debido a otra propiedad importante de los mapas de cubo, y es que la dirección de entrada se normaliza primero (la longitud cambiada a 1, sin cambiar su dirección) antes de leer el color de la textura. Esto se usó en tarjetas gráficas más antiguas para calcular la normalización rápida de vectores, usando una textura de mapa de cubo especial (porque el cálculo de la raíz cuadrada en el sombreado era más lento que la búsqueda de textura).

Una última reflexión sobre los cubos: el mapa de cubo no es la forma correcta de asignar diferentes texturas a cada cara de un cubo. Funciona para casos simples, pero sería difícil hacerlo práctico, p. en un juego, porque I) el número de combinaciones de diferentes texturas en un cubo probablemente requeriría innecesariamente muchas texturas y II) porque de esta manera, la repetición de textura no se puede usar.

0

es necesario agregar devDept.DataSet.dll en su aplicación y aplicarlo a su objeto:

string brickMatName = "Wall bricks"; 
viewportLayout1.Materials.Add(brickMatName, new Material(devDept.DataSet.DataSet.GetBricks()));