OpenGL ES 2.0 / GLSL not rendering data (Kotlin)

本秂侑毒 提交于 2020-02-05 02:53:50

问题


I am trying to implement a basic shading program with GLES 2/3, and have pieced together this code from various tutorials. Everything looks correct to me, and it compiles fine, but nothing appears on my screen.

It rendered fine until I added Normal and Light Position data, then it broke and I haven't been able to find a way to fix it.

Can anyone see what's wrong here?

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  = allocateDirect(verts.size*4).order(nativeOrder()).asFloatBuffer()
    val norms = arrayOf(0f,0f,-1f,  0f,0f,-1f,  0f,0f,-1f)
    val nBuf  = 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)

        glVertexAttrib4f(aColor,1f,1f,1f,1f)
        glDrawArrays(GL_TRIANGLES,0,verts.size/3)
    }
    override fun onSurfaceChanged(g:GL10,w:Int,h:Int){}
    override fun onDrawFrame(g:GL10){}
}

回答1:


If you want to use color values in range [0.0, 1.0] then you've to use glVertexAttrib4f rather than glVertexAttribI4i:

glVertexAttribI4i(aColor,1,1,1,1)

glVertexAttrib4f(aColor,1.0f,1.0f,1.0f,1.0f)

glVertexAttribI* assumes the values to be signed or unsigned fixed-point values in range [-2147483647, 2147483647] or [0, 4294967295]. A value of 1 is almost black.


The type of the u_LightPos is floating point (vec3):

uniform vec3 u_LightPos; 

You've to use glUniform3f rather than glUniform3ito set the value of a floating point uniform variable:

glUniform3i(uLightPos,-1,-10,-1)

glUniform3f(uLightPos,-1f,-10f,-1f)

I recommend to verify if the shader is complied successfully by glGetShaderiv (parameter GL_COMPILE_STATUS). Compile error messages can be retrieved by glGetShaderInfoLog


I recommend to add an ambient light component (for debug reasons) e.g.:

v_Color = a_Color*(diffuse + 0.5);

If you can "see" the geometry with the ambient light, then there are some possible issues:

  1. the light source is on the back side of the geometry, so the back side is lit, but not the front side. That cause that only the almost black, unlit side is visible from the point of view.

  2. The distance of the light source to the geometry is "too large". distance becomes a very huge value and so diffuse is very small and all the geometry is almost black.

  3. The light source is in the closed volume of the geometry.

  4. All the normal vectors point away from the camera. That may cause that dot(normal, lightVector) is less than 0.0.



来源:https://stackoverflow.com/questions/59449194/opengl-es-2-0-glsl-not-rendering-data-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!