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);
- 使用iOS8中的NSUrlSession使用stream请求进行背景上传
- 在顶部的tabbar控制器或分段
- 在iOS上自动启动Google Authenticator应用程序
- RestKit:JSON映射不起作用
- Facebooklogin使用FBSessionLoginBehaviorForcingWebView
- 在iOS 4.x和MacOS X 10.6中使用NSDateFormatterparsingrfc3339date:不可能?
- 使用CFTypeRef与ARC获取错误
- 由于缺lessinfo.plist和其他文件,OS X,iPhone和Android上的Worklight构build失败
- 什么是Mobile Safari的自定义urlscheme?