有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

OpenGL 2.0中的java照明纹理对象+

我一直在开发一个多维数据集程序,它提供了许多具有所需质量的多维数据集。然而,每当我试图照亮一个纹理立方体,我的立方体就会变得非常暗。照明与非纹理立方体配合使用效果很好,因此我相信这是正确的,就像没有照明的简单纹理立方体一样。在OpenGL 2.0+中,似乎没有关于如何解决这个问题的重要文档,但是有一些与旧版本相关的内容

下面的link提供了有关我的多维数据集为何会如此运行的信息,但我在将解决方案转换为新版本时遇到了问题,特别是在我的着色器代码中,我不确定是否应该进行进一步的更改。我正在使用AndroidStudio 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. # 1 楼答案

    1. 您的照明缺少一个环境光组件,该组件模拟现实生活中可能获得的二阶(或更高)反射,但无法直接在光栅化器中获得
    2. 不确定为什么要在片段着色器中平方a_Color。因为所有的值都在0到1之间,所以这肯定会使颜色变暗;e、 g.0.1^2 == 0.01
    3. 请记住,您的点积可能是负数,因此您希望钳制负漫反射组件(例如,背向灯光的表面上没有灯光强度)