2012-12-31 59 views
1

我目前正在學習OpenGL 2.0,並且正在創建一個基本的iPhone應用程序。我在攪拌機中創建了一個模型,並將它導出到.obj文件,並編寫了一個解析器來抽取座標。形狀顯示很好,但沒有顏色(黑色)。這意味着法線有問題。但我已經檢查了法線,並發現螞蟻有任何問題。我的代碼中是否存在缺失?OpenGL ES 2.0照明不適用於iOS應用程序

我會非常感激任何幫助!

截屏

enter image description here

這裏是我的OpenGL代碼

glEnable(GL_DEPTH_TEST); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 


glGenVertexArraysOES(1, &_vertexArray); 
glBindVertexArrayOES(_vertexArray); 

glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfVerticies * sizeof(GLfloat) * 3, arrayOfVerticies, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0)); 

glGenVertexArraysOES(1, &_normalArray); 
glBindVertexArrayOES(_normalArray); 

glGenBuffers(1, &_normalBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _normalBuffer); 
glBufferData(GLKVertexAttribNormal, loader.currentCountOfNormals * sizeof(GLfloat) * 3,loader.arrayOfNormals , GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0)); 

glGenVertexArraysOES(1, &_textureArray); 
glBindVertexArrayOES(_textureArray); 

glGenBuffers(1, &_textureBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer); 
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfTextureCoordinates * sizeof(GLfloat) * 2, loader.arrayOftextureCoOrdinates, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8, BUFFER_OFFSET(0)); 


glBindVertexArrayOES(0); 

而且我DrawRect方法

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glBindVertexArrayOES(_vertexArray); 

    glUseProgram(_program); 

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); 

    #ifdef DEBUG_VERTEX_DATA_LOOP 
    NSLog(@"size of c array * type %ld", loader.currentCountOfVerticies *sizeof(GLfloat)); 
    #endif 

    //Takes in the ammout of indicies not triangels! 
    glDrawArrays(GL_TRIANGLES, 0, loader.currentCountOfVerticies); 
} 

從負載着色器方法的代碼

glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); 
glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); 
glBindAttribLocation(_program, GLKVertexAttribTexCoord0, "TextCo"); 

頂點着色器

// Created by Jake Cunningham on 13/10/2012. 
// Copyright (c) 2012 Jake Cunningham. All rights reserved. 
// 

attribute vec4 position; 
attribute vec3 normal; 

varying lowp vec4 colorVarying; 

uniform mat4 modelViewProjectionMatrix; 
uniform mat3 normalMatrix; 

attribute vec2 TextCo; 
varying vec2 textCoOut; 

void main() 
{ 
    vec3 eyeNormal = normalize(normalMatrix * normal); 
    vec3 lightPosition = vec3(0.0, 0.0, 1.0); 
    vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0); 

    float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); 

    colorVarying = diffuseColor * nDotVP; 

    gl_Position = modelViewProjectionMatrix * position; 
    textCoOut = TextCo; 
} 

片段着色器

// 
// Created by Jake Cunningham on 13/10/2012. 
// Copyright (c) 2012 Jake Cunningham. All rights reserved. 
// 

varying lowp vec4 colorVarying; 

varying lowp vec2 textCoOut; 
uniform sampler2D texture; 

void main() 
{ 
    gl_FragColor = colorVarying * texture2D(texture, textCoOut); 
} 

回答

2

我建議第一測試照明從紋理分離。片段着色器中的乘法意味着,如果紋理元素是黑色的 - 如果您無法加載紋理或出現其他紋理問題,很可能會出現這種情況 - 您將無法看到照明代碼的輸出。

+0

良好的提示。我嘗試過,但仍然有同樣的問題? – geminiCoder

0

我已經解決了這個問題,但我必須承認我仍然不確定問題是什麼。我改變了我的代碼從上面

glEnable(GL_DEPTH_TEST); 

glGenVertexArraysOES(1, &_vertexArray); 
glBindVertexArrayOES(_vertexArray); 

glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, total * sizeof(GLfloat), mergedArray, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 

glBindVertexArrayOES(0); 

合併頂點和法線的兩個數組到一個單一的緩衝解決了這個問題。我現在有照明。爲什麼我無法使用2個緩衝區我不知道如果任何人能發現我不能提供的東西,我會很感激任何反饋。

許多感謝所有G.C

+0

這不是將兩個VBO合併爲一個能夠解決您的問題的解決方案(從不同緩衝區獲取不同屬性絕對沒有問題),而是合併了兩個VAO,就像我在答案中詳細描述的那樣。 –

0

的問題是您的多個頂點數組對象的使用。頂點數組對象(VAO)是一個輕量級對象(意味着它不包含任何實際的頂點屬性數據),封裝了用一次繪製調用渲染一堆頂點數組所需的所有狀態,具體如下:

  • glVertexAttribPointer針對每個屬性索引
  • 啓用的屬性陣列進行的設置
  • 結合的元件陣列緩衝器

因此它比個人頂點高一個級別屬性陣列,其包括所有的頂點ATT單個(概念性)場景對象的ribute數組設置,或者更準確地說,單個繪製調用。

但是在你的代碼中,你爲每個單獨的屬性創建一個新的頂點數組對象。當然後渲染你只綁定_vertexArray而這又只會設置和啓用GLKVertexAttribPosition屬性,因此沒有法線或texCoords或其他任何。

所以,你應該有相當取代他們的是原代碼:

glGenVertexArraysOES(1, &_vertexArray); 
glBindVertexArrayOES(_vertexArray); 

glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfVerticies * sizeof(GLfloat) * 3, arrayOfVerticies, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0)); 

//forget this 
//glGenVertexArraysOES(1, &_normalArray); 
//glBindVertexArrayOES(_normalArray); 

glGenBuffers(1, &_normalBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _normalBuffer); 
glBufferData(GLKVertexAttribNormal, loader.currentCountOfNormals * sizeof(GLfloat) * 3,loader.arrayOfNormals , GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0)); 

//and this, too 
//glGenVertexArraysOES(1, &_textureArray); 
//glBindVertexArrayOES(_textureArray); 

glGenBuffers(1, &_textureBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer); 
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfTextureCoordinates * sizeof(GLfloat) * 2, loader.arrayOftextureCoOrdinates, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8, BUFFER_OFFSET(0)); 

glBindVertexArrayOES(0);