2011-06-04 58 views
5

我试图在使用samplerCube和textureCube着色器的多维数据集上应用不同的纹理。将纹理应用到多维数据集,立方体的每个表面上的不同纹理

但我无法在多维数据集的面上绘制纹理,只有单一颜色出现。

Screenshots of output

下面是我的shader代码:

的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;" + 
      "}"; 

片段着色器

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

多维数据集定义

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); 
    } 

创建立方体贴图代码

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]; 
    } 

我无法明白的地方,我会犯错。

如果你想看完整的代码。

解决方案:

使用相同的立方体绘制坐标的纹理坐标

感谢名单全部

CODE Link

+0

请把你的答案到下面一个真正的答案。您可以在两天后将其标记为已接受。这将使问题从“未答复的问题”选项卡中消失。 – 2012-01-12 08:58:51

回答

4

但现在的问题是解决了,我想提供一个解释为什么使用不同的坐标实际上有帮助(因为上面没有提到)。

当我第一次实现立方体映射时,由于误解了立方体贴图的工作原理,我有同样的错误。立方体贴图在内部是一组6个2D贴图,排列在立方体的六个面上。从数学的角度来看,它定义了一个查找函数,其中参数是3D 方向,输出是RGBA颜色。

这很重要,因为在上面的示例中,查找的参数是正常的。正常是一个方向,这是正确的。但是法线的整个面上的法线也是恒定的(除非平滑着色风格法线被计算出来,但情况并非如此)。如果法线(查找的输入)是常数,那当然意味着输出(颜色)也必须是恒定的。我的误解是,我认为OpenGL会以某种方式考虑的位置和方向,但不幸的是并非如此。

在这种特殊情况下的Interersting事情是,可以使用cubeMap(position)或cubeMap(position + direction),并且会得到非常相似的结果。这是因为立方体贴图的另一个重要属性,那就是在从纹理中读取颜色之前,首先将输入方向标准化(将长度更改为1,而不更改其方向)。在较早的图形卡上使用这种方法计算快速向量规范化,使用特殊的立方体贴图纹理(因为在着色器中计算平方根比纹理查找慢)。

最后一个关于立方体的想法 - 立方体贴图不是将正确方式分配给立方体的每个面的不同纹理。它适用于一些简单的案例,但它很难实用,例如在一个游戏中,因为我)一个立方体上不同纹理的组合的数量可能需要不必要的很多纹理,并且II)因为这样,纹理重复不能被使用。

0

您需要添加devDept.DataSet.dll在您的应用程序并将其应用到你的对象:

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