我试图用点光源照亮一个简单的方形物体,但我似乎无法将物体和光线一起渲染。我做错了什么?
这是我的渲染器:
public class Renderer implements GLSurfaceView.Renderer {
private static final String TAG="TAG";
private static final String A_COLOR = "a_Color";
private static final String U_MATRIX = "u_Matrix";
private static final String U_MVMATRIX = "u_MVMatrix";
private static final String A_POSITION = "a_Position";
private static final String A_NORMAL = "a_Normal" ;
private static final String U_LIGHT_POS = "u_LightPos";
private static final int BYTES_PER_FLOAT = 4 ;
private static final int POSITION_COMPONENT_COUNT = 3;
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int NORMAL_COMPONENT_COUNT = 3;
private static final int STRIDE = (POSITION_COMPONENT_COUNT+COLOR_COMPONENT_COUNT)*BYTES_PER_FLOAT;
private final Context context;
private final FloatBuffer vertexData;
private final FloatBuffer normalData;
private int program;
private int pointProgram ;
private int aPositionLocation;
private int aColorLocation;
private int aNormalLocation;
private int uMatrixLocation;
private int uPointMatrixLocation;
private int aPointPositionLocation;
private int uMVMatrixLocation;
private int uLightPos;
private float[] modelMatrix = new float[16];
private float[] projectionMatrix = new float[16];
private float[] mViewMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
private float[] lightModelMatrix = new float[16];
private final float[] mLightPosInModelSpace = new float[] {0f, 0.0f, -4.0f, 1.0f};
private final float[] mLightPosInWorldSpace = new float[4];
private final float[] mLightPosInEyeSpace = new float[4];
private static final float Z_VALUE = -5.0f;
public Renderer(Context context ) {
this.context = context ;
float[] table = {
//triangle fan
// X , Y , Z R , G , B
0 , 0 , Z_VALUE, 1f , 0f , 0f ,
-0.25f , -0.25f ,Z_VALUE, 1f , 0f , 0f ,
0.25f , -0.25f ,Z_VALUE, 1f , 0f , 0f ,
0.25f , 0.25f ,Z_VALUE, 1f , 0f , 0f ,
-0.25f , 0.25f ,Z_VALUE, 1f , 0f , 0f ,
-0.25f , -0.25f ,Z_VALUE, 1f , 0f , 0f
};
final float[] normal = {
0.0f , 0.0f , 1.0f ,
0.0f , 0.0f , 1.0f ,
0.0f , 0.0f , 1.0f ,
0.0f , 0.0f , 1.0f ,
0.0f , 0.0f , 1.0f ,
0.0f , 0.0f , 1.0f
};
vertexData = ByteBuffer.allocateDirect(table.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexData.put(table);
normalData = ByteBuffer.allocateDirect(normal.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
normalData.put(normal);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0f, 0f, 0f,0f);
String vertexShaderSource = TextResourceReader.readTextFileFromResource(context,R.raw.simple_vertex_shader); //read simple_vertex_shader.glsl
String fragmentShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader); //read simple_fragment_shader.glsl
String pointVertexShader = TextResourceReader.readTextFileFromResource(context , R.raw.point_vertex_shader);
String pointFragmentShader = TextResourceReader.readTextFileFromResource(context , R.raw.point_fragment_shader) ;
int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource); //compile the vertex shader
int pointShaderVertex = ShaderHelper.compileVertexShader(pointVertexShader);
int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderSource); //compile the fragment shader
int pointShaderFragment = ShaderHelper.compileFragmentShader(pointFragmentShader);
program=ShaderHelper.linkProgram(vertexShader,fragmentShader); //link the shaders into a program object
if (Logger.logging)
ShaderHelper.validateProgram(program);
pointProgram = ShaderHelper.linkProgram(pointShaderVertex, pointShaderFragment);
ShaderHelper.validateProgram(pointProgram);
aColorLocation = GLES20.glGetAttribLocation(program, A_COLOR); //get attribute for color
aNormalLocation = GLES20.glGetAttribLocation(program ,A_NORMAL);
uLightPos = GLES20.glGetUniformLocation(program, U_LIGHT_POS);
uMVMatrixLocation = GLES20.glGetUniformLocation(program , U_MVMATRIX);
//tell openGL where to find the attribute for color
vertexData.position(POSITION_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexData);
GLES20.glEnableVertexAttribArray(aColorLocation);
//tell openGL where to find the attribute for normal
normalData.position(0);
GLES20.glVertexAttribPointer(aNormalLocation, NORMAL_COMPONENT_COUNT, GLES20.GL_FLOAT, false, NORMAL_COMPONENT_COUNT * BYTES_PER_FLOAT, normalData);
GLES20.glEnableVertexAttribArray(aNormalLocation);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float aspect = (float)width/height;
Matrix.perspectiveM(projectionMatrix, 0, 40, aspect, 1.0f, -1.0f);
Matrix.setIdentityM(modelMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, 0f, 0f, 0f, 0f, 0f, -2.0f, 0f, 1.0f, 0.0f);
//Matrix.multiplyMM(mViewMatrix , 0 , mViewMatrix , 0 , modelMatrix , 0);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(program);
uMatrixLocation = GLES20.glGetUniformLocation(program, U_MATRIX);
aPositionLocation=GLES20.glGetAttribLocation(program, A_POSITION); //get attribute for position
//tell openGL where to find the attribute location
vertexData.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexData);
GLES20.glEnableVertexAttribArray(aPositionLocation); //enable the vertex array
GLES20.glUniformMatrix4fv(uMVMatrixLocation, 1, false, mViewMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, projectionMatrix, 0, mViewMatrix, 0);
Matrix.setIdentityM(lightModelMatrix, 0);
Matrix.translateM(lightModelMatrix, 0, 0.0f, 0.0f, -3.0f);
Matrix.multiplyMV(mLightPosInWorldSpace, 0, lightModelMatrix, 0, mLightPosInModelSpace, 0);
Matrix.multiplyMV(mLightPosInEyeSpace, 0, mViewMatrix, 0, mLightPosInWorldSpace, 0);
GLES20.glUniform3f(uLightPos, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glUseProgram(pointProgram);
uPointMatrixLocation = GLES20.glGetUniformLocation(pointProgram,U_MATRIX);
aPointPositionLocation = GLES20.glGetAttribLocation(pointProgram, A_POSITION); //get attribute for position
GLES20.glVertexAttrib3f(aPointPositionLocation, mLightPosInModelSpace[0], mLightPosInModelSpace[1], mLightPosInModelSpace[2]);
GLES20.glDisableVertexAttribArray(aPointPositionLocation);
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, lightModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, projectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(uPointMatrixLocation, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_POINTS , 0 , 1);
}
}
我的对象顶点着色器:
uniform mat4 u_Matrix;
uniform mat4 u_MVMatrix;
uniform vec3 u_LightPos;
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec3 a_Normal;
varying vec4 v_Color;
void main()
{
vec3 modelViewVertex = vec3(u_MVMatrix * a_Position) ;//transform the vertex into eye space
vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal,0.0)) ; //transform the normal into eye space
float distance = length(u_LightPos - modelViewVertex) ; //will be used for attenuation
vec3 lightVector = normalize(u_LightPos - modelViewVertex) ;
float diffuse = max(dot(modelViewNormal,lightVector) , 0.1 );
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));
v_Color=a_Color * diffuse;
//v_Color = a_Color;
gl_Position = u_Matrix * a_Position ;
}
我的对象片段着色器:
precision mediump float ;
varying vec4 v_Color;
void main ()
{
gl_FragColor = v_Color ;
}
我的点光顶点着色器:
uniform mat4 u_Matrix;
attribute vec4 a_Position;
void main() {
gl_Position = u_Matrix * a_Position ;
gl_PointSize = 5.0;
}
和我的点片段着色器:
precision mediump float;
void main() {
gl_FragColor = vec4(1.0,1.0,1.0,1.0);
}
编辑:我现在可以看到对象,但它非常暗淡。我改变了漫反射但不好的价值。