OpenGL ES 2.0 / GLSL не отображает данные (Котлин) - PullRequest
1 голос
/ 23 декабря 2019

Я пытаюсь реализовать базовую программу затенения с 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  = 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 Ответ

1 голос
/ 23 декабря 2019

Если вы хотите использовать значения цвета в диапазоне [0.0, 1.0], вам нужно использовать glVertexAttrib4f вместо glVertexAttribI4i:

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

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

glVertexAttribI* предполагает значения со знаком или без знака значения с фиксированной точкой в ​​диапазоне [-2147483647, 2147483647] или [0, 4294967295]. Значение 1 почти чёрное.


Тип u_LightPos является плавающей точкой (vec3):

uniform vec3 u_LightPos; 

Вы должны использовать glUniform3f вместо glUniform3i для установки значения равномерной переменной с плавающей запятой:

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

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

Iрекомендуем проверить, успешно ли выполняется шейдер, с помощью glGetShaderiv (параметр GL_COMPILE_STATUS). Сообщения об ошибках компиляции можно получить с помощью glGetShaderInfoLog


Я рекомендую добавить компонент окружающего освещения (по причинам отладки), например:

v_Color = a_Color*(diffuse + 0.5);

ЕслиВы можете «увидеть» геометрию с помощью внешнего освещения, тогда есть несколько возможных проблем:

  1. источник света находится на обратной стороне геометрии, поэтому задняя сторона горит,но не лицевая сторона. Это потому, что с точки зрения видна только почти черная неосвещенная сторона.

  2. Расстояние от источника света до геометрии слишком велико. distance становится очень большим значением, поэтому diffuse очень мало, и вся геометрия почти черная.

  3. Источник света находится в замкнутом объеме геометрии.

  4. Все векторы нормалей направлены в сторону от камеры. Это может привести к тому, что dot(normal, lightVector) меньше 0,0.

...