OpenGL ES 2.0灯光不适用于iOS应用程序

我目前正在学习OpenGL 2.0和我创build一个基本的iPhone应用程序。 我已经在搅拌器中创build了一个模型,并将其导出到.obj文件,并写入了一个parsing器,用于抽取坐标。 形状显示很好,但没有颜色(黑色)。 这意味着法线有问题。 但是我已经检查了法线,ant发现了任何错误。 有没有从我的代码中缺less的东西?

我会非常感激任何帮助!

屏幕截图

在这里输入图像说明

这里是我的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); } 

我build议首先testing与纹理分开的照明。 片段着色器中的乘法意味着,如果纹理元素是黑色的(如果您无法加载纹理或者存在其他纹理问题,则很可能是这种情况),则不会看到照明代码的输出。

我已经解决了这个问题,但是我必须承认我仍然不确定问题是什么。 我从上面改变了我的代码

 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缓冲区我不知道如果任何人可以发现我不能,我会感激任何反馈。

非常感谢所有的GC

问题是你使用多个顶点数组对象。 顶点数组对象(VAO)是一个轻量级的对象(意味着它不包含任何实际的顶点属性数据),封装了用一个绘制调用渲染一堆顶点数组所需的所有状态,特别是:

  • 使用glVertexAttribPointer为每个属性索引进行的设置
  • 启用的属性数组
  • 绑定的元素数组缓冲区

因此它比单个顶点属性数组高一级,包括单个(概念性)场景对象的所有顶点属性数组设置,或者更准确地说,是单个绘制调用。

但在你的代码中,你为每个单独的属性创build一个新的顶点数组对象。 当然后渲染你只绑定_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);