gpt4 book ai didi

ios - OpenGL ES 2.0 如何在iOS中用不同的Shader程序绘制多个VBO

转载 作者:可可西里 更新时间:2023-11-01 05:42:18 28 4
gpt4 key购买 nike

我正在尝试破解通用 Xcode iOS OpenGL 游戏模板以绘制两个顶点缓冲区对象并使用不同的 GLSL 着色器渲染它们。我“认为”我正确地渲染了两个 VBO? (因为我在通过第一个着色器程序运行两个 VBO 时都看到了它们)但是,我的第二个着色器似乎根本没有渲染我的第二个对象。

这是两个正方形的顶点数据:

GLfloat gCubeVertexData[36] = 
{
// Data layout for each line below is:
// positionX, positionY, positionZ, normalX, normalY, normalZ,

0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f

};

GLfloat fooVertexData[36] =
{
// Data layout for each line below is:
// positionX, positionY, positionZ, normalX, normalY, normalZ

0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};

这里是我尝试生成两个 VBO 并将它们绑定(bind)到数据的地方。不确定最后“glBindVertexArrayOES(0)”的目的是什么?:

- (void)setupGL
{
[EAGLContext setCurrentContext:self.context];

[self loadShaders];

//---- First Vertex Array Object --------
glGenVertexArraysOES(1, &_vertexArray1);
glGenBuffers(1, &_vertexBuffer1);

glBindVertexArrayOES(_vertexArray1);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, 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));

//----- Second Vertex Array Object ----------
glGenVertexArraysOES(1, &_vertexArray2);
glGenBuffers(1, &_vertexBuffer2);

glBindVertexArrayOES(_vertexArray2);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(fooVertexData), fooVertexData, 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));

glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArrayOES(0);
}

我正在使用此更新代码来制作模型- View -投影矩阵的动画:

- (void)update
{
_rotation += self.timeSinceLastUpdate * 0.2f;

float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f, 1.0f, -1.0f / aspect, 1.0f / aspect, -10.0f, 10.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.5f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeZRotation(0.0 - _rotation));
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);

GLKMatrix4 modelViewMatrix2 = GLKMatrix4MakeTranslation(-0.5f, 0.0f, 0.0f);
modelViewMatrix2 = GLKMatrix4Multiply(modelViewMatrix2, GLKMatrix4MakeZRotation(_rotation));
_modelViewProjectionMatrix2 = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix2);
}

当我调用“_program2”着色器时,我没有看到第二个方 block :

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

glBindVertexArrayOES(_vertexArray1);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);

glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 6);

///////// second object and shader program:
glBindVertexArrayOES(_vertexArray2);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);

glUseProgram(_program2);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX2], 1, 0, _modelViewProjectionMatrix2.m);
glDrawArrays(GL_TRIANGLES, 0, 6);

}

我基本上尝试复制用于加载第一个着色器的代码,以加载第二个。我怀疑我可能在这里做错了什么……但我不确定是什么:

- (BOOL)loadShaders
{
GLuint vertShader, fragShader, vertShader2, fragShader2;
NSString *vertShaderPathname, *fragShaderPathname, *vertShaderPathname2, *fragShaderPathname2;

// Create shader program.
_program = glCreateProgram();


// Create and compile vertex shader.
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"Failed to compile vertex shader");
return NO;
}

// Create and compile fragment shader.
fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
NSLog(@"Failed to compile fragment shader");
return NO;
}

// Attach vertex shader to program.
glAttachShader(_program, vertShader);

// Attach fragment shader to program.
glAttachShader(_program, fragShader);

// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(_program, ATTRIB_VERTEX, "position");

// Link program.
if (![self linkProgram:_program]) {
NSLog(@"Failed to link program: %d", _program);

if (vertShader) {
glDeleteShader(vertShader);
vertShader = 0;
}
if (fragShader) {
glDeleteShader(fragShader);
fragShader = 0;
}
if (_program) {
glDeleteProgram(_program);
_program = 0;
}

return NO;
}

// Get uniform locations.
uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");

// Release vertex and fragment shaders.
if (vertShader) {
glDetachShader(_program, vertShader);
glDeleteShader(vertShader);
}
if (fragShader) {
glDetachShader(_program, fragShader);
glDeleteShader(fragShader);
}


///////////////// the second shader:

_program2 = glCreateProgram();

vertShaderPathname2 = [[NSBundle mainBundle] pathForResource:@"Shader2" ofType:@"vsh"];
if (![self compileShader:&vertShader2 type:GL_VERTEX_SHADER file:vertShaderPathname2]) {
NSLog(@"Failed to compile vertex shader2");
return NO;
}

fragShaderPathname2 = [[NSBundle mainBundle] pathForResource:@"Shader2" ofType:@"fsh"];
if (![self compileShader:&fragShader2 type:GL_FRAGMENT_SHADER file:fragShaderPathname2]) {
NSLog(@"Failed to compile fragment shader2");
return NO;
}

glAttachShader(_program2, vertShader2);
glAttachShader(_program2, fragShader2);

glBindAttribLocation(_program2, ATTRIB_VERTEX2, "position2");

if (![self linkProgram:_program2]) {
NSLog(@"Failed to link program: %d", _program2);

if (vertShader2) {
glDeleteShader(vertShader2);
vertShader2 = 0;
}
if (fragShader2) {
glDeleteShader(fragShader2);
fragShader2 = 0;
}
if (_program2) {
glDeleteProgram(_program2);
_program2 = 0;
}

return NO;
}

uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX2] = glGetUniformLocation(_program2, "modelViewProjectionMatrix2");
if (vertShader2) {
glDetachShader(_program2, vertShader2);
glDeleteShader(vertShader2);
}
if (fragShader2) {
glDetachShader(_program2, fragShader2);
glDeleteShader(fragShader2);
}



return YES;
}

- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
GLint status;
const GLchar *source;

source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
NSLog(@"Failed to load vertex shader");
return NO;
}

*shader = glCreateShader(type);
glShaderSource(*shader, 1, &source, NULL);
glCompileShader(*shader);

#if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
NSLog(@"Shader compile log:\n%s", log);
free(log);
}
#endif

glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
glDeleteShader(*shader);
return NO;
}

return YES;
}

- (BOOL)linkProgram:(GLuint)prog
{
GLint status;
glLinkProgram(prog);

#if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program link log:\n%s", log);
free(log);
}
#endif

glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == 0) {
return NO;
}

return YES;
}

- (BOOL)validateProgram:(GLuint)prog
{
GLint logLength, status;

glValidateProgram(prog);
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program validate log:\n%s", log);
free(log);
}

glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
if (status == 0) {
return NO;
}

return YES;
}

我的顶点和片段着色器很简单:

// vert shader1:
attribute vec4 position;
uniform mat4 modelViewProjectionMatrix;

void main()
{
gl_Position = modelViewProjectionMatrix * position;
}


// vert shader2:
attribute vec4 position2;
uniform mat4 modelViewProjectionMatrix2;

void main()
{
gl_Position = modelViewProjectionMatrix2 * position2;
}


// frag shader(s):
void main()
{
gl_FragColor = vec4(0.12,0.32,0.54,1.0);
}

最佳答案

使用 OpenGL ES 最重要的一点是,您是在 OOP 语言中使用过程语言。

您一次只能将一个顶点数组绑定(bind)到顶点缓冲区。

将两个顶点数组一个接一个地绑定(bind)到 VBO,然后应用变换,只会变换附加到 VBO 的最后一个顶点数组。

在您的主循环中,您必须遍历您的顶点数组列表。对于每个顶点数组,将其绑定(bind)到 VBO,然后执行任何转换。

关于ios - OpenGL ES 2.0 如何在iOS中用不同的Shader程序绘制多个VBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10067447/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com