OpenGL ES 3.0 / GLSL无法呈现数据 (Kotlin)

3

我正在尝试使用OpenGL ES 3.0实现一个基本的着色程序,并从各种教程中拼凑出了这段代码。在我的眼里,一切都看起来正确,并且编译也没有问题,但是屏幕上却什么也没有显示。

在添加了法线和光源位置数据之前,它还可以正常渲染,但在添加后就会出问题,而我也找不到解决办法。

有人能看出问题在哪里吗?

import android.opengl.GLES30.*
import android.opengl.GLSurfaceView.Renderer
import android.opengl.Matrix.*
import java.nio.*
import java.nio.ByteBuffer.allocateDirect
import java.nio.ByteOrder.nativeOrder
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class GLRenderer:Renderer{
    lateinit var vBuf: FloatBuffer
    lateinit var nBuf: FloatBuffer
    var glProgram = -1
    var uMV       = -1
    var uMVP      = -1
    var uLightPos = -1
    val aPosition =  0
    val aNormal   =  1
    val aColor    =  2
    val modelM = FloatArray(16)
    val viewM  = FloatArray(16)
    val projM  = FloatArray(16)
    val mvM    = FloatArray(16)
    val mvpM   = FloatArray(16)
    val lPos   = FloatArray(4)
    val lightPos = floatArrayOf(0f,10f,0f,1f)

    override fun onSurfaceCreated(g:GL10,c:EGLConfig) {
        glClearColor(0f,0f,0f,1f)
        setLookAtM(viewM,0,0f,0f,5f,0f,0f,0f,0f,1f,0f)

        val vShader = glCreateShader(GL_VERTEX_SHADER)
        val fShader = glCreateShader(GL_FRAGMENT_SHADER)
        glShaderSource(vShader,"#version 300 es\n" +
            " uniform mat4 u_mvpM;                              " +
            " uniform mat4 u_mvM;                               " +
            " layout(location=0) in vec4 aPos;                  " +
            " layout(location=1) in vec4 aCol;                  " +
            " layout(location=2) in vec3 aNorm;                 " +
            " out vec3 vPos;                                    " +
            " out vec4 vCol;                                    " +
            " out vec3 vNorm;                                   " +
            " void main(){                                      " +
            "   vPos        = vec3(u_mvM * aPos);               " +
            "   vCol        = aCol;                             " +
            "   vNorm       = vec3(u_mvM * vec4(aNorm,0.0));    " +
            "   gl_Position = u_mvpM * aPos;}                   " )
        glShaderSource(fShader,"#version 300 es\n" +
            " precision mediump float;                          " +
            " uniform vec3 u_LightPos;                          " +
            " in  vec3 vPos;                                    " +
            " in  vec4 vCol;                                    " +
            " in  vec3 vNorm;                                   " +
            " out vec4 fColor;                                  " +
            " void main(){                                      " +
            "   float distance = length(u_LightPos - vPos);     " +
            "   vec3  lightPos = normalize(u_LightPos - vPos);  " +
            "   float diffuse  = max(dot(vNorm,lightPos),0.1)/  " +
            "                    (distance*distance/4.0 + 1.0); " +
            "   fColor         = vCol * diffuse;}               " )
        glCompileShader(vShader)
        glCompileShader(fShader)
        glProgram = glCreateProgram()
        glAttachShader(glProgram,vShader)
        glAttachShader(glProgram,fShader)
        glLinkProgram(glProgram)
        glUseProgram(glProgram)
        uMV       = glGetUniformLocation(glProgram,"u_mvM")
        uMVP      = glGetUniformLocation(glProgram,"u_mvpM")
        uLightPos = glGetUniformLocation(glProgram,"u_LightPos")

        vBuf = allocateDirect(9*4).order(nativeOrder()).asFloatBuffer().put(floatArrayOf(
               0f,1f,0f, -1f,0f,0f, 1f,0f,0f))
        nBuf = allocateDirect(9*4).order(nativeOrder()).asFloatBuffer().put(floatArrayOf(
               0f,0f,-1f, 0f,0f,-1f, 0f,0f,-1f))
        vBuf.position(0)
        nBuf.position(0)
    }
    override fun onSurfaceChanged(g:GL10,w:Int,h:Int) {
        glViewport(0,0,w,h)
        val ratio = (w/h).toFloat()
        frustumM(projM,0,-ratio,ratio,1f,-1f,1f,10f)
    }
    override fun onDrawFrame(g:GL10){
        glClear(GL_COLOR_BUFFER_BIT)
        setIdentityM(modelM,0)
        multiplyMM(mvM, 0,viewM,0,modelM,0)
        multiplyMM(mvpM,0,projM,0,mvM,0)
        multiplyMV(lPos,0,mvpM,0,lightPos,0)

        glUniformMatrix4fv(uMV, 1,false,mvM, 0)
        glUniformMatrix4fv(uMVP,1,false,mvpM,0)
        glUniform3f(uLightPos,lPos[0],lPos[1],lPos[2])
        glVertexAttribPointer(aPosition,3,GL_FLOAT,false,0,vBuf)
        glVertexAttribPointer(aNormal,  3,GL_FLOAT,false,0,nBuf)
        glVertexAttrib4f(aColor,1f,1f,1f,1f)
        glEnableVertexAttribArray(aPosition)
        glEnableVertexAttribArray(aNormal)
        glDrawArrays(GL_TRIANGLES,0,vBuf.capacity()/4)
    }
}

1
如果你执行 fColor = vCol * diffuse + 0.5;,你能看到任何东西吗? - Rabbid76
请参见此处 - greeble31
是的!这次成功了...不过似乎扩散结果为0,原因不明。 - Jonah M
1个回答

2
在着色器程序和应用程序的资源索引之间存在不匹配的情况:布局限定符aPosaColaNorm 的布局位置分别为0、1、2。请注意保留 HTML 标记。
layout(location=0) in vec4 aPos;
layout(location=1) in vec4 aCol;
layout(location=2) in vec3 aNorm;

但是应用程序中对应的变量 (aPosition, aColor, aNormal) 初值分别为 0、2 和 1:

val aPosition =  0
val aNormal   =  1
val aColor    =  2

1
谢谢!我应该采用一种约定来排序我的属性... - Jonah M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接