我試圖破解通用Xcode iOS OpenGL遊戲模板來繪製兩個頂點緩衝區對象並使用不同的GLSL着色器渲染它們。 我'想'我正確渲染兩個VBO? (因爲我在通過第一個着色器程序運行兩個VBO時都看到它們)但是,我的第二個着色器似乎根本沒有渲染我的第二個對象。OpenGL ES 2.0如何在iOS中使用不同着色器程序繪製多個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
};
這裏就是我想產生兩個維也納組織,並將其綁定到數據。不知道什麼是「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);
}
我使用此更新的代碼進行動畫處理的模型 - 視圖 - 投影矩陣:
- (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」着色我沒有看到第二方:
- (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和片段着色器很簡單:
// 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);
}
的OES後綴不用於OpenGL ES 2.0 – 2012-04-10 18:03:14
@MatisseVerDuyn這是誤導。這些函數不在OpenGL-ES 2規範的基礎上,所以它們不是默認定義的,但它們*作爲擴展提供(通過支持的設備)。 – 2014-09-30 18:33:54