2016-09-23 77 views
0

我一直在開發一個立方體程序,它提供了許多具有所需品質的立方體。但是,每當我嘗試點亮紋理立方體時,立方體就會變得非常黑暗。照明與非紋理立方體效果很好,所以我被引導認爲它正確地做了一個簡單的紋理立方體沒有照明工程。似乎沒有關於如何在OpenGL 2.0+中解決這個問題的重要文檔,但是有一些與舊版本有關的內容。在OpenGL 2.0+中照明紋理對象

以下link提供信息,爲什麼我的立方體行爲,因爲它是,但我無法翻譯解決方案的新版本,尤其是在我的shader代碼在那裏我不確定是否應該進行進一步的修改。我正在使用Android Studio 2.1.3,如果它和它包含的模擬器會導致問題達到預期的效果。如果任何人可以提供任何建議,我將不勝感激。我有一個單獨的(大)渲染器,要求繪製立方體,讓我知道如果該代碼除了我的立方體之外也是有益的。下面是我的魔方:

public class TexturedLightCube { 


/** Cube vertices */ 
private static final float VERTICES[] = { 
     -0.3f, -0.3f, -0.3f, //top front right 
     0.3f, -0.3f, -0.3f, //bottom front right 
     0.3f, 0.3f, -0.3f, //bottom front left 
     -0.3f, 0.3f, -0.3f, //top front left 
     -0.3f, -0.3f, 0.3f, //top back right 
     0.3f, -0.3f, 0.3f, //bottom back right 
     0.3f, 0.3f, 0.3f, //bottom back left 
     -0.3f, 0.3f, 0.3f // top back left 
}; 

/** Vertex colors. */ 
private static final float COLORS[] = { 
     0.0f, 1.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 0.0f, 1.0f, 
     1.0f, 1.0f, 0.0f, 1.0f, 
     0.0f, 1.0f, 0.0f, 1.0f, 
     0.0f, 0.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 1.0f, 1.0f, 
     1.0f, 1.0f, 1.0f, 1.0f, 
     0.0f, 1.0f, 1.0f, 1.0f, 
}; 


/** Order to draw vertices as triangles. */ 
private static final byte INDICES[] = { 
     0, 1, 3, 3, 1, 2, // Front face. 
     0, 1, 4, 4, 5, 1, // Bottom face. 
     1, 2, 5, 5, 6, 2, // Right face. 
     2, 3, 6, 6, 7, 3, // Top face. 
     3, 7, 4, 4, 3, 0, // Left face. 
     4, 5, 7, 7, 6, 5, // Rear face. 
}; 


private static final float TEXTURECOORDS[] = 
     { 

       0.0f, 1.0f, //left-bottom 
       0.0f, 0.0f, //right bottom 
       1.0f, 0.0f, //left top 
       1.0f, 1.0f, //right top 

       0.0f, 1.0f, //left-bottom 
       0.0f, 0.0f, //right bottom 
       1.0f, 0.0f, //left top 
       1.0f, 1.0f, //right top 


     }; 


private static final float NORMALS[] = { 

     //set all normals to all light for testing 
     1.0f, 1.0f, 1.0f, //top front right 
     1.0f, 0.0f, 1.0f, //bottom front right 
     0.0f, 0.0f, 1.0f, //bottom front left 
     0.0f, 1.0f, 1.0f, //top front left 
     1.0f, 1.0f, 0.0f, //top back right 
     1.0f, 0.0f, 0.0f, //bottom back right 
     0.0f, 0.0f, 0.0f, //bottom back left 
     0.0f, 1.0f, 0.0f //top back left 
}; 

static final int COORDS_PER_VERTEX = 3; 

private static final int VALUES_PER_COLOR = 4; 

/** Vertex size in bytes. */ 
final int VERTEX_STRIDE = COORDS_PER_VERTEX * 4; 

/** Color size in bytes. */ 
private final int COLOR_STRIDE = VALUES_PER_COLOR * 4; 

/** Shader code for the vertex. */ 
private static final String VERTEX_SHADER_CODE = 
     "uniform mat4 uMVPMatrix;" + 
     "uniform mat4 uMVMatrix;" + 
     "uniform vec3 u_LightPos;" + 
     "attribute vec4 vPosition;" + 
     "attribute vec4 a_Color;" + 
     "attribute vec3 a_Normal;" + 
     "varying vec4 v_Color;" + 
     "attribute vec2 a_TexCoordinate;" + 
     "varying vec2 v_TexCoordinate;" + 
     "void main() {" + 
     "vec3 modelViewVertex = vec3(uMVMatrix * vPosition);"+ 
     "vec3 modelViewNormal = vec3(uMVMatrix * vec4(a_Normal, 0.0));" + 
     "float distance = length(u_LightPos - modelViewVertex);" + 
     "vec3 lightVector = normalize(u_LightPos - modelViewVertex);" + 
     "float diffuse = max(dot(modelViewNormal, lightVector), 0.1);" + 
     "diffuse = diffuse * (1.0/(1.0 + (0.00000000000002 * distance * distance)));" + //attenuation factor 
     "v_Color = a_Color * a_Color * diffuse;" + 
     "gl_Position = uMVPMatrix * vPosition;" + 
     "v_TexCoordinate = a_TexCoordinate;" + 
     "}"; 



/** Shader code for the fragment. */ 
private static final String FRAGMENT_SHADER_CODE = 
     "precision mediump float;" + 
       "varying vec4 v_Color;" + 
       "uniform sampler2D u_Texture;"+ //The input texture 
       "varying vec2 v_TexCoordinate;" + 
       "void main() {" + 
       " gl_FragColor = v_Color * texture2D(u_Texture, v_TexCoordinate) ;" + //still works with just color 
       "}"; 


private int mTextureUniformHandle; //Pass in texture. 
private int mTextureCoordinateHandle; //Pass in model texture coordinate information. 
private final int mTextureCoordinateDataSize = 2; //Size of texture coordinate data in elements 
public static int mTextureDataHandle; //Handle to texturedata; 
private final FloatBuffer mTextureBuffer; //Store model data in float buffer. 
private final FloatBuffer mVertexBuffer; 
private final FloatBuffer mColorBuffer; 
private final FloatBuffer mNormalBuffer; 
private final ByteBuffer mIndexBuffer; 
private final int mProgram; 
private final int mPositionHandle; 
private final int mColorHandle; 
private final int mMVPMatrixHandle; 
private final int mNormalHandle; 
public static int mLightPosHandle; 
public final int mMVMatrixHandle; 



public static int loadTexture(final Context context, final int resourceId) { 
    //Get the texture from the Android resource directory 
    final int[] textureHandle = new int[1]; 

    InputStream is = context.getResources().openRawResource(+ R.drawable.teneighty); 
    Bitmap bitmap = null; 
    try { 
     //BitmapFactory is an Android graphics utility for images 
     bitmap = BitmapFactory.decodeStream(is); 

    } finally { 
     //Always clear and close 
     try { 
      is.close(); 
      is = null; 
     } catch (IOException e) { 
     } 
    } 

    //Generate one texture pointer... 
    GLES20.glGenTextures(1, textureHandle, 0); 
    //and bind it to our array. 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 

    //Create Nearest Filtered Texture. 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    //Accounting for different texture parameters. 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap. 
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

    //Clean up 
    bitmap.recycle(); 


    if (textureHandle[0] == 0) 

    { 
     throw new RuntimeException("Error loading texture"); 
    } 

    return textureHandle[0]; 
} 



public TexturedLightCube() { 

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(VERTICES.length * 4); 
    byteBuffer.order(ByteOrder.nativeOrder()); 
    mVertexBuffer = byteBuffer.asFloatBuffer(); 
    mVertexBuffer.put(VERTICES); 
    mVertexBuffer.position(0); 


    byteBuffer = ByteBuffer.allocateDirect(COLORS.length * 4); 
    byteBuffer.order(ByteOrder.nativeOrder()); 
    mColorBuffer = byteBuffer.asFloatBuffer(); 
    mColorBuffer.put(COLORS); 
    mColorBuffer.position(0); 

    byteBuffer = ByteBuffer.allocateDirect(NORMALS.length * 4); 
    byteBuffer.order(ByteOrder.nativeOrder()); 
    mNormalBuffer = byteBuffer.asFloatBuffer(); 
    mNormalBuffer.put(NORMALS); 
    mNormalBuffer.position(0); 

    byteBuffer = ByteBuffer.allocateDirect(TEXTURECOORDS.length * 4); 
    byteBuffer.order(ByteOrder.nativeOrder()); 
    mTextureBuffer = byteBuffer.asFloatBuffer(); 
    mTextureBuffer.put(TEXTURECOORDS); 
    mTextureBuffer.position(0); 


    mIndexBuffer = ByteBuffer.allocateDirect(INDICES.length); 
    mIndexBuffer.put(INDICES); 
    mIndexBuffer.position(0); 

    mProgram = GLES20.glCreateProgram(); 
    GLES20.glAttachShader(mProgram, loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER_CODE)); 
    GLES20.glAttachShader(mProgram, loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_CODE)); 
    GLES20.glLinkProgram(mProgram); 


    mTextureDataHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture"); 
    mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate"); 
    mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture"); 
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVMatrix"); 
    mLightPosHandle = GLES20.glGetUniformLocation(mProgram, "u_LightPos"); 
    mNormalHandle = GLES20.glGetAttribLocation(mProgram, "a_Normal"); 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "a_Color"); 

} 

/** 
* Encapsulates the OpenGL ES instructions for drawing this shape. 
* 
* @param mvpMatrix The Model View Project matrix in which to draw this shape 
*/ 
public void draw(float[] mvpMatrix) { 
    // Add program to OpenGL environment. 
    GLES20.glUseProgram(mProgram); 

    //set active texture unit to texture unit 0. 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle); 

    // Prepare the cube coordinate data. 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 
    GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, VERTEX_STRIDE, mVertexBuffer); 


    // Prepare the cube color data. 
    GLES20.glEnableVertexAttribArray(mColorHandle); 
    GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, COLOR_STRIDE, mColorBuffer); 

    //Will have the same size as Vertex as we are implementing per vertex lighting 
    GLES20.glEnableVertexAttribArray(mNormalHandle); 
    GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, VERTEX_STRIDE, mNormalBuffer); 

    // Prepare the cube texture data. 
    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); 
    //Pass texture coordinate information. 
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle,4, GLES20.GL_FLOAT, false, mTextureCoordinateDataSize, mTextureBuffer); 

    // Apply the projection and view transformation. 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 

    GLES20.glUniform3f(LightCube.mLightPosHandle, MyGLRenderer.mLightPosInEyeSpace[0], MyGLRenderer.mLightPosInEyeSpace[1], MyGLRenderer.mLightPosInEyeSpace[2]); 


    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glUniform1i(mTextureUniformHandle, 0); 


    // Draw the cube. 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, INDICES.length, GLES20.GL_UNSIGNED_BYTE, mIndexBuffer); //-removed indices- 

    // Disable vertex arrays. 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
    GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle); 
    GLES20.glDisableVertexAttribArray(mColorHandle); 
    GLES20.glDisableVertexAttribArray(mNormalHandle); 


} 

/** Loads the provided shader in the program. */ 
private static int loadShader(int type, String shaderCode){ 
    int shader = GLES20.glCreateShader(type); 

    GLES20.glShaderSource(shader, shaderCode); 
    GLES20.glCompileShader(shader); 

    return shader; 
} 



} 

回答

1
  1. 你錯過的環境組件添加到您的照明器,模擬二階(或更高)的反射,你會得到在現實生活中,但不能直接在光柵化得到。
  2. 不確定爲什麼你在片段着色器中將a_Color平方。這肯定會使事情變暗,因爲所有的值都在0到1之間;例如0.1^2 == 0.01
  3. 請記住,您的點積可能是負值,因此您需要去除負漫射分量(例如,背離光線的表面上沒有光強度)。