0

我正在嘗試使用Android的OpenGL ES 2.0來顯示具有法線和顏色的簡單立方體。要做到這一點,我創建了一個着色器程序,附上我的頂點和片段着色器和鏈接我的程序,具體如下:頂點着色器中的Phong照明

// Create empty OpenGL ES Program 
mProgram = GLES20.glCreateProgram(); 
MyGLRenderer.checkGlError("glCreateProgram"); 

// Add the vertex shader to program 
vertexShaderCode = Utilities.convertResourceToString(context, R.raw.vert_shader_hw3); 
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
GLES20.glAttachShader(mProgram, vertexShader); 
MyGLRenderer.checkGlError("glAttachShader"); 

// Add the fragment shader to program 
fragmentShaderCode = Utilities.convertResourceToString(context, R.raw.frag_shader_hw3); 
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 
GLES20.glAttachShader(mProgram, fragmentShader); 
MyGLRenderer.checkGlError("glAttachShader"); 

// Bind attributes 
GLES20.glBindAttribLocation(mProgram, 0, "aPosition"); 
MyGLRenderer.checkGlError("glBindAttribLocation"); 

GLES20.glBindAttribLocation(mProgram, 1, "aNormal"); 
MyGLRenderer.checkGlError("glBindAttribLocation"); 

GLES20.glBindAttribLocation(mProgram, 2, "aColor"); 
MyGLRenderer.checkGlError("glBindAttribLocation"); 

// Create OpenGL program executables 
GLES20.glLinkProgram(mProgram); 
MyGLRenderer.checkGlError("glLinkProgram"); 

// Add program to OpenGL ES environment 
GLES20.glUseProgram(mProgram); 
MyGLRenderer.checkGlError("glUseProgram"); 

而且它在最後崩潰就在那裏,印刷到logcat的:glUseProgram: glError 1281我查如果程序既不是0也不是由OpenGL生成的值,則生成glError 1281,即GL_INVALID_VALUE

現在谷歌搜索了大約10個小時之後,我決定轉向StackOverflow尋求幫助。任何想法是什麼可能是我的頂點着色器代碼錯誤,使glUseProgram這樣的行爲?

這裏是我的頂點着色器的代碼,我嘗試實現Phong光照:

uniform mat4 uMVPMatrix; 
uniform mat4 uMVMatrix; 
uniform vec3 uLightPosition; 
uniform vec4 uAmbient; 
uniform vec4 uDiffuse; 
uniform vec4 uSpecular; 
uniform vec4 uEmission; 
uniform float uShininess; 

attribute vec4 aPosition; 
attribute vec3 aNormal; 
attribute vec4 aColor; 

varying vec4 vColor; 

vec4 phong() 
{ 
    // P is the vertex coordinate on body 
    vec3 P = vec3(uMVMatrix * aPosition); 

    // N is the object normal at P 
    vec3 N = vec3(uMVMatrix * vec4(aNormal, 0.0)); 

    // Light Position for light 0 
    vec3 LightPos = uLightPosition; 

    // L is the light vector 
    vec3 L = normalize(LightPos - P); 

    // R is the reflected light vector R = 2(L.N)N - L 
    vec3 R = reflect(-L, N); 

    // V is the view vector (eye at the origin) 
    vec3 V = normalize(-P); 

    // Diffuse light intensity is cosine of light and normal vectors 
    float Id = max(dot(L,N) , 0.0); 

    // Shininess intensity is cosine of light and reflection vectors to a power 
    float Is = (Id>0.0) ? pow(max(dot(R,V) , 0.0) , uShininess) : 0.0; 

    // Vertex color 
    return uEmission + uAmbient + Id*uDiffuse + Is*uSpecular; 
} 

void main() 
{ 
    gl_Position = uMVPMatrix * aPosition; 
    vColor = phong() * 0.5*(gl_Position/gl_Position.w + 1.0); 
} 
+0

您是否檢查過硬件是否支持所需數量的屬性,使用類似 >> getIntegerv(MAX_VERTEX_ATTRIBS,&n) – prabindh

+0

感謝您的迅速響應。是的,我通過將它打印到LogCat來檢查它。我的Nexus 7平板電腦上的MAX_VERTEX_ATTRIBS是16. – Luke

+1

您是否嘗試檢查LINK_STATUS和着色器信息日誌? – rotoglup

回答

2

感謝您的幫助球員。我終於弄明白了。問題是,在我的頂點着色器中,我聲明「屬性vec4 aColor;」然後在我的代碼後,我試着這樣做:

mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor"); 
GLES20.glEnableVertexAttribArray(mColorHandle); 
GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, 16, colorsBuffer); 

然而,aColor是從來沒有真正的頂點着色器代碼中使用,並優化了編譯着色器,這樣當我試圖得到了處理它並填充它,這導致我的程序的其餘部分失敗。

0

我看到一個潛在的問題,在你checkGLError的使用。 MyGLRenderer.loadShader之後沒有檢查錯誤。你可以在那裏添加一個檢查,看看它是否真的編譯正確(在glAttachShader之後的錯誤檢查之前)?請注意,loadShader調用內部有2個GL調用 - 一個用於加載字符串,另一個用於編譯着色器本身。

vertexShaderCode = Utilities.convertResourceToString(上下文,R.raw.vert_shader_hw3);

int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);

GLES20.glAttachShader(mProgram,vertexShader); MyGLRenderer.checkGlError(「glAttachShader」);