我正在尝试使用GLES 2/3实现基本的着色程序,并已将各种教程中的代码拼凑而成。对我来说,一切看起来都正确,并且可以正常编译,但是屏幕上没有任何显示。
直到我添加了法线和光照位置数据,它都表现良好,然后它破裂了,我仍无法找到解决它的方法。
谁能看到这里有什么问题吗?
class MyRenderer:GLSurfaceView.Renderer{
var glProgram = -1
var uMV = -1
var uMVP = -1
var uLightPos = -1
var aPosition = -1
var aNormal = -1
var aColor = -1
val verts = arrayOf(0f,1f,0f, -1f,0f,0f, 1f,0f,0f)
val vBuf: FloatBuffer = allocateDirect(verts.size*4).order(nativeOrder()).asFloatBuffer()
val norms = arrayOf(0f,0f,-1f, 0f,0f,-1f, 0f,0f,-1f)
val nBuf: FloatBuffer = allocateDirect(norms.size*4).order(nativeOrder()).asFloatBuffer()
override fun onSurfaceCreated(g:GL10,c:EGLConfig) {
glClearColor(0f,0f,0f,1f)
glClearDepthf(1f)
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glProgram = glCreateProgram()
val vShader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vShader,"#version 100\n " +
"uniform mat4 u_mvMat; " +
"uniform mat4 u_mvpMat; " +
"uniform vec3 u_LightPos; " +
"attribute vec4 a_Position; " +
"attribute vec3 a_Normal; " +
"attribute vec4 a_Color; " +
"varying vec4 v_Color; " +
"void main(){ " +
" vec3 vertex = vec3(u_mvMat*a_Position); " +
" vec3 normal = vec3(u_mvMat*vec4(a_Normal,0.0)); " +
" vec3 lightVector = normalize(u_LightPos-vertex); " +
" float distance = length(u_LightPos-vertex); " +
" float diffuse = max(dot(normal,lightVector),0.1) " +
" / (1.0+distance*distance/4.0); " +
" v_Color = a_Color*diffuse; " +
" gl_Position = u_mvpMat*a_Position;} " )
glCompileShader(vShader)
glAttachShader(glProgram,vShader)
val fShader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fShader,"#version 100\n " +
"precision mediump float; " +
"varying vec4 v_Color; " +
"void main(){ " +
" gl_FragColor = v_Color;} " )
glCompileShader(fShader)
glAttachShader(glProgram,fShader)
glLinkProgram(glProgram)
glUseProgram(glProgram)
uMVP = glGetUniformLocation(glProgram,"u_mvpMat")
uMV = glGetUniformLocation(glProgram,"u_mvMat")
uLightPos = glGetUniformLocation(glProgram,"u_LightPos")
aPosition = glGetAttribLocation (glProgram,"a_Position")
aNormal = glGetAttribLocation (glProgram,"a_Normal")
aColor = glGetAttribLocation (glProgram,"a_Color")
glVertexAttribPointer(aPosition,4,GL_FLOAT,false,3*4,vBuf)
glEnableVertexAttribArray(aPosition)
glVertexAttribPointer(aNormal,4,GL_FLOAT,false,3*4,nBuf)
glEnableVertexAttribArray(aNormal)
val modelM = FloatArray(16)
setIdentityM(modelM,0)
val viewM = FloatArray(16)
setLookAtM(viewM,0, 0f,0f,-5f, 0f,0f,0f, 0f,0f,1f)
val projM = FloatArray(16)
frustumM(projM,0, -2f,2f, 1f,-1f, 1f,50f)
val mvM = FloatArray(16)
multiplyMM(mvM,0,viewM,0,modelM,0)
glUniformMatrix4fv(uMV,1,false,mvM,0)
val mvpM = FloatArray(16)
multiplyMM(mvpM,0,projM,0,mvM,0)
glUniformMatrix4fv(uMVP,1,false,mvpM,0)
glUniform3v(uLightPos,-1f,-10f,-1f)
glVertexAttribI4i(aColor,1,1,1,1)
glDrawArrays(GL_TRIANGLES,0,verts.size/3)
}
override fun onSurfaceChanged(g:GL10,w:Int,h:Int){}
override fun onDrawFrame(g:GL10){}
}
u_LightPos
的类型是浮点(vec3
):
uniform vec3 u_LightPos;
您必须使用glUniform3f
而不是glUniform3f
来设置浮点统一变量的值:
glUniform3i
glUniform3i(uLightPos,-1,-10,-1)
我建议验证glUniform3f(uLightPos,-1f,-10f,-1f)
(参数glGetShaderiv
)是否成功编译了着色器。可以通过glGetShaderiv
我建议添加环境光组件(出于调试原因)例如:
GL_COMPILE_STATUS
如果您可以通过环境光“看到”几何,则可能存在一些问题:
光源位于几何图形的背面,因此背面被照亮,但正面不被照亮。这导致从视图的角度来看几乎只有黑色,不发光的一面可见。
光源到几何的距离“太大”。 glGetShaderInfoLog
变为非常大的值,因此glGetShaderInfoLog
很小,所有几何图形几乎都是黑色的。
光源在几何的封闭空间中。
所有法线向量都指向远离摄像机的方向。这可能会导致v_Color = a_Color*(diffuse + 0.5);
小于0.0。