2011-06-04 75 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())); 
相關問題