2013-03-09 143 views
0

我想呈现一些顶点到Open GL ES窗口。我的程序不断在GLDrawElements命令上崩溃。我正在尝试通过一些VBO为GLFloat类型的顶点“bindPosition”,“bindNorml”和“Index”。GLDrawElements崩溃程序

这里是我的渲染方法的链接:

- (void)render:(CADisplayLink*)displayLink { 

glViewport(0, 0, self.frame.size.width, self.frame.size.height); 

glClearColor(0.3, 0.5, 0.9, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glEnable(GL_DEPTH_TEST); 
glEnable(GL_CULL_FACE); 

GLKMatrix4 modelView = GLKMatrix4Make(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -10, -30, 1); 
GLKMatrix4 projectionView = GLKMatrix4Make(3.6213202476501465, 0, 0, 0, 0, 2.4142136573791504, 0, 0, 0, 0, -1.0020020008087158, -1, 0, -24.142135620117188, 28.05805778503418, 30); 

// Upload Transforms 
glUniformMatrix4fv(_modelViewMatrixUniform, 1, 0, modelView.m); 
glUniformMatrix4fv(_modelViewProjMatrixUniform, 1, 0, projectionView.m); 

// Upload Bones 
glUniformMatrix4fv(_bonesUniform, 1, 0, bones); 

glBindBuffer(GL_ARRAY_BUFFER, _bindPositionBuffer); 
glVertexAttribPointer(_VertexPositionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(bindPosition), 0); 

glBindBuffer(GL_ARRAY_BUFFER, _bindNormalBuffer); 
glVertexAttribPointer(_VertexNormalAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(bindNormal), 0); 


// 3 
glBindBuffer(GL_ARRAY_BUFFER, _indexBuffer); 
glDrawElements(GL_TRIANGLE_STRIP, sizeof(Index)/sizeof(Index[0]), GL_UNSIGNED_SHORT, 0); 

[_context presentRenderbuffer:GL_RENDERBUFFER]; 
} 

设置维也纳组织:

- (void)setupVBOs { 

glGenBuffers(1, &_bindPositionBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _bindPositionBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(bindPosition), bindPosition, GL_STATIC_DRAW); 

glGenBuffers(1, &_bindNormalBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _bindNormalBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(bindNormal), bindNormal, GL_STATIC_DRAW); 

glGenBuffers(1, &_indexBuffer); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Index), Index, GL_STATIC_DRAW); 

} 

编译着色器:

- (void)compileShaders { 

// 1 
GLuint vertexShader = [self compileShader:@"SimpleVertex" withType:GL_VERTEX_SHADER]; 
GLuint fragmentShader = [self compileShader:@"SimpleFragment" withType:GL_FRAGMENT_SHADER]; 

// 2 
GLuint programHandle = glCreateProgram(); 
glAttachShader(programHandle, vertexShader); 
glAttachShader(programHandle, fragmentShader); 
glLinkProgram(programHandle); 

// 3 
GLint linkSuccess; 
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); 
if (linkSuccess == GL_FALSE) { 
    GLchar messages[256]; 
    glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]); 
    NSString *messageString = [NSString stringWithUTF8String:messages]; 
    NSLog(@"%@", messageString); 
    exit(1); 
} 

// 4 
glUseProgram(programHandle); 

// 5  
// Uniform Locations 
_bonesUniform    = glGetUniformLocation(programHandle, "Bones[0]"); 
_modelViewMatrixUniform  = glGetUniformLocation(programHandle, "ModelViewMatrix"); 
_modelViewProjMatrixUniform = glGetUniformLocation(programHandle, "ModelViewProjMatrix"); 
_textureUniform    = glGetUniformLocation(programHandle, "Texture"); 

// Attribute Locations 
_VertexBoneWeightAttribute = glGetAttribLocation(programHandle, "VertexBoneWeight"); 
_VertexBoneIDAttribute  = glGetAttribLocation(programHandle, "VertexBoneID"); 
_VertexTexCoord0Attribute = glGetAttribLocation(programHandle, "VertexTexCoord0"); 
_VertexNormalAttribute  = glGetAttribLocation(programHandle, "VertexNormal"); 
_VertexPositionAttribute = glGetAttribLocation(programHandle, "VertexPosition");  

// Enable vertex pointers 
glEnableVertexAttribArray(_VertexBoneWeightAttribute); 
glEnableVertexAttribArray(_VertexBoneIDAttribute); 
glEnableVertexAttribArray(_VertexTexCoord0Attribute); 
glEnableVertexAttribArray(_VertexNormalAttribute); 
glEnableVertexAttribArray(_VertexPositionAttribute); 

} 

这里是我的着色器的链接:

attribute vec3 VertexPosition; 
attribute vec3 VertexNormal; 
attribute vec2 VertexTexCoord0; 
attribute vec4 VertexBoneID; 
attribute vec4 VertexBoneWeight; 


uniform mat4 ModelViewMatrix; 
uniform mat4 ModelViewProjMatrix; 

uniform vec4 Bones[222]; 


varying vec3 Normal; 
varying vec2 TexCoord0; 


void main(void) 
{ 
TexCoord0 = VertexTexCoord0; 

// Build 4x3 skinning matrix. 
vec4 r0 = Bones[int(VertexBoneID.x) * 3 + 0] * VertexBoneWeight.x; 
vec4 r1 = Bones[int(VertexBoneID.x) * 3 + 1] * VertexBoneWeight.x; 
vec4 r2 = Bones[int(VertexBoneID.x) * 3 + 2] * VertexBoneWeight.x; 

r0 += Bones[int(VertexBoneID.y) * 3 + 0] * VertexBoneWeight.y; 
r1 += Bones[int(VertexBoneID.y) * 3 + 1] * VertexBoneWeight.y; 
r2 += Bones[int(VertexBoneID.y) * 3 + 2] * VertexBoneWeight.y; 

r0 += Bones[int(VertexBoneID.z) * 3 + 0] * VertexBoneWeight.z; 
r1 += Bones[int(VertexBoneID.z) * 3 + 1] * VertexBoneWeight.z; 
r2 += Bones[int(VertexBoneID.z) * 3 + 2] * VertexBoneWeight.z; 

r0 += Bones[int(VertexBoneID.w) * 3 + 0] * VertexBoneWeight.w; 
r1 += Bones[int(VertexBoneID.w) * 3 + 1] * VertexBoneWeight.w; 
r2 += Bones[int(VertexBoneID.w) * 3 + 2] * VertexBoneWeight.w; 

// Skin and transform position. 
float px = dot(r0, vec4(VertexPosition, 1.0)); 
float py = dot(r1, vec4(VertexPosition, 1.0)); 
float pz = dot(r2, vec4(VertexPosition, 1.0)); 

gl_Position = ModelViewProjMatrix * vec4(px, py, pz, 1.0); 

/* Skin and transform normal into view-space. We assume that the modelview matrix 
doesn't contain a scale. Should pass pass in the inverse-transpose really. */ 
float nx = dot(r0, vec4(VertexNormal, 0.0)); 
float ny = dot(r1, vec4(VertexNormal, 0.0)); 
float nz = dot(r2, vec4(VertexNormal, 0.0)); 

Normal = normalize((ModelViewMatrix * vec4(nx, ny, nz, 0.0)).xyz); 
} 

破片着色器:

#ifdef GL_ES 
precision highp float; 
#endif 


uniform sampler2D Texture; 


varying vec3 Normal; 
varying vec2 TexCoord0; 


void main(void) 
{ 
// Ambient term. 
vec3 lighting = vec3(0.5,0.5,0.5) * 0.7; 

/* Very cheap lighting. Three directional lights, one shining slighting upwards to  illuminate 
underneath the chin, and then one each shining from the left and right. Light directional 
are in view-space and follow the camera rotation by default. */ 
lighting += dot(Normal, normalize(vec3(0.0, -0.2, 0.8))) * vec3(0.8, 0.8, 0.6) * 0.6;  // Shines forwards and slightly upwards. 
lighting += dot(Normal, normalize(vec3(-0.8, 0.4, 0.8))) * vec3(0.8, 0.8, 0.6) * 0.4;  // Shines forwards and from left to right. 
lighting += dot(Normal, normalize(vec3(0.8, 0.4, 0.8))) * vec3(0.8, 0.8, 0.6) * 0.4;  // Shines forwards and from right to left. 

//gl_FragColor = vec4(Normal * 0.5 + vec3(0.5), 1.0); 
gl_FragColor = vec4(texture2D(Texture, TexCoord0).xyz * lighting, 1.0); 
} 

任何人都可以看到什么在我的渲染方法,我有什么错呢?

+0

错误消息是:EXC_BAD_ACCESS(code = 2,address = 0x0) – samb90 2013-03-09 01:53:11

+0

也许你发布的代码是不完整的,但我似乎没有看到你在哪里调用glBufferData。就我看来,问题似乎是你实际上没有将任何数据绑定到OpenGL。您必须调用glBufferData以将数据绑定到顶点属性指针。 – aeskreis 2013-03-09 04:10:38

+0

你好,我已经包含了一些我的程序代码 – samb90 2013-03-09 11:13:25

回答

0

在渲染方法中绑定索引缓冲区时,应该使用GL_ELEMENT_ARRAY_BUFFER而不是GL_ARRAY_BUFFER

+0

嘿,谢谢你的回复。我做了你所建议的更改,但仍然遇到同样的问题 – samb90 2013-03-09 17:12:47

+0

“glVertexAttribPointer”的第五个参数应该是一个顶点与下一个顶点之间的步长(以字节为单位)。您也可以传递0来获得紧密压缩的属性。我不确定你的'bindPosition'变量是什么,但我想我会提到它。 – prideout 2013-03-10 00:06:47

0

您拨打glDrawElements看起来不正确。您拨打glBufferData也不会。

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Index), Index, GL_STATIC_DRAW); 

glDrawElements(GL_TRIANGLE_STRIP, sizeof(Index)/sizeof(Index[0]), GL_UNSIGNED_SHORT, 0); 

它看起来像你传递一个结构glBufferData而不是索引数组。除非你的参数被称为Index,但由于你的使用方式,它看起来并不如此。您需要构建一系列顶点索引并将其传入以告诉GPU要绘制的内容。

glDrawElement的第二个参数应该是要渲染的元素的数量。我在this question有类似的问题,有人帮忙指出我犯了同样的错误。希望这对你也有帮助。