0

我正在尝试将一些顶点渲染到 Open GL ES 窗口。我的程序在 GLDrawElements 命令上不断崩溃。我正在尝试为 GLFloat 类型的顶点“bindPosition”、“bindNorml”和“Index”传递一些 VBO。

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

- (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];
}

设置 VBOS:

- (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);
}

任何人都可以在我的渲染方法中看到我做错了什么吗?

4

3 回答 3

1

如果您将 GLFloat 值绑定到您的 GL_ELEMENT_ARRAY_BUFFER,这可能是个问题。您应该绑定 GL_UNSIGNED_BYTE 或 GL_UNSIGNED_SHORT。
http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml

于 2013-07-04T08:05:09.260 回答
0

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

于 2013-03-09T16:00:07.503 回答
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应该是要渲染的元素数量。我在这个问题中遇到了类似的问题,有人很有帮助地指出我犯了同样的错误。希望它对你也有帮助。

于 2013-07-04T08:31:43.647 回答