如何从Objective C客户端将纹理数据传递给此openGL顶点着色器?(How do I pass texture data to this openGL vertex shader from an Objective C client?)

我试图通过Cozzi和Ring的“3D引擎设计虚拟地球仪”来举例说明。

我正在尝试使用它们的顶点着色器(11.2.2,第319页),因为它似乎提供了我需要完成的起点(从密集的,基于数组的地形数据渲染地形):

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

问题是我不清楚如何在Objective C客户端代码中设置必要的数据。 构建输出显示

TerrainShaderTest[10429:607] Shader compile log: ERROR: 0:31: Invalid qualifiers 'in' in global variable context ERROR: 0:33: 'sampler2DRect' : declaration must include a precision qualifier for type ERROR: 0:37: Use of undeclared identifier 'position' ERROR: 0:37: Use of undeclared identifier 'u_heightMap' ERROR: 0:37: Use of undeclared identifier 'position' 2015-01-08 10:33:30.532 TerrainShaderTest[10429:607] Failed to compile vertex shader 2015-01-08 10:33:30.545 TerrainShaderTest[10429:607] GL ERROR: 0x0500

如果我使用不同的顶点着色器(下图),我得到一个基本但有效的结果,在客户端使用相同的位置设置(但显然不是高度图/纹理。)

// WORKS - very simple case attribute vec4 position; varying lowp vec4 colorVarying; uniform mat4 modelViewProjectionMatrix; void main() { colorVarying = (position + vec4(0.5,0.5,0.0,0)); gl_Position = modelViewProjectionMatrix * position; }

来自客户的代码片段(目标C):

... glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); ... #pragma mark - OpenGL ES 2 shader compilation - (BOOL)loadShaders { GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // 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, GLKVertexAttribPosition, "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"); uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(_program, "u_heightMap"); glProgramUniform1fvEXT (_program, uniforms[UNIFORM_TEXTURE], nTerrainElements, _pTerrainScaled); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return YES; }

有关设置客户端数据的任何帮助吗?

I'm trying to follow an example from "3D Engine Design for Virtual Globes" by Cozzi and Ring.

I'm trying to use their vertex shader (11.2.2, p. 319), as it seems to provide exactly the starting point for what I need to accomplish (rendering terrain from dense, array-based terrain data):

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

The problem is that I'm not clear how to set up the necessary data in the Objective C client code. Build output shows

TerrainShaderTest[10429:607] Shader compile log: ERROR: 0:31: Invalid qualifiers 'in' in global variable context ERROR: 0:33: 'sampler2DRect' : declaration must include a precision qualifier for type ERROR: 0:37: Use of undeclared identifier 'position' ERROR: 0:37: Use of undeclared identifier 'u_heightMap' ERROR: 0:37: Use of undeclared identifier 'position' 2015-01-08 10:33:30.532 TerrainShaderTest[10429:607] Failed to compile vertex shader 2015-01-08 10:33:30.545 TerrainShaderTest[10429:607] GL ERROR: 0x0500

If I use a different vertex shader instead (below), I get a basic but working result, using the same set up for position on the client side (but obviously not heightmap/texture.)

// WORKS - very simple case attribute vec4 position; varying lowp vec4 colorVarying; uniform mat4 modelViewProjectionMatrix; void main() { colorVarying = (position + vec4(0.5,0.5,0.0,0)); gl_Position = modelViewProjectionMatrix * position; }

Code snippets from client (Objective C):

... glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); ... #pragma mark - OpenGL ES 2 shader compilation - (BOOL)loadShaders { GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // 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, GLKVertexAttribPosition, "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"); uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(_program, "u_heightMap"); glProgramUniform1fvEXT (_program, uniforms[UNIFORM_TEXTURE], nTerrainElements, _pTerrainScaled); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return YES; }

Any help on setting up the client side data?

最满意答案

在iOS上,您将使用OpenGL ES。 最常用的版本是ES 2.0。 从2013年开始发布的设备也支持ES 3.0。

您的着色器代码与ES 2.0不兼容:

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

要使这与ES 2.0一起使用:

ES 2.0仍然使用顶点属性的属性,而不是使用完整OpenGL和ES 3.0+的当前版本。 没有版本的ES支持RECT纹理,因此sampler2DRect类型无效。 使用常规2D纹理,而使用着色器代码中的相应sampler2D 。 ES 2.0使用texture2D()作为纹理采样函数的名称,而不是较新版本中的texture() 。

然后着色器应如下所示:

attribute vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2D u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture2D(u_heightMap, position).r, 1.0); }

On iOS, you will be using OpenGL ES. The most commonly used version is ES 2.0. Devices released starting in 2013 also support ES 3.0.

Your shader code is not compatible with ES 2.0:

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

To make this work with ES 2.0:

ES 2.0 still uses attribute for vertex attributes, instead of in like current versions of full OpenGL, and ES 3.0+. No version of ES supports RECT textures, so the type sampler2DRect is invalid. Use regular 2D textures, with the corresponding sampler2D in the shader code, instead. ES 2.0 uses texture2D() as the name of the texture sampling function, instead of texture() in newer versions.

The shader should then look like this:

attribute vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2D u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture2D(u_heightMap, position).r, 1.0); }如何从Objective C客户端将纹理数据传递给此openGL顶点着色器?(How do I pass texture data to this openGL vertex shader from an Objective C client?)

我试图通过Cozzi和Ring的“3D引擎设计虚拟地球仪”来举例说明。

我正在尝试使用它们的顶点着色器(11.2.2,第319页),因为它似乎提供了我需要完成的起点(从密集的,基于数组的地形数据渲染地形):

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

问题是我不清楚如何在Objective C客户端代码中设置必要的数据。 构建输出显示

TerrainShaderTest[10429:607] Shader compile log: ERROR: 0:31: Invalid qualifiers 'in' in global variable context ERROR: 0:33: 'sampler2DRect' : declaration must include a precision qualifier for type ERROR: 0:37: Use of undeclared identifier 'position' ERROR: 0:37: Use of undeclared identifier 'u_heightMap' ERROR: 0:37: Use of undeclared identifier 'position' 2015-01-08 10:33:30.532 TerrainShaderTest[10429:607] Failed to compile vertex shader 2015-01-08 10:33:30.545 TerrainShaderTest[10429:607] GL ERROR: 0x0500

如果我使用不同的顶点着色器(下图),我得到一个基本但有效的结果,在客户端使用相同的位置设置(但显然不是高度图/纹理。)

// WORKS - very simple case attribute vec4 position; varying lowp vec4 colorVarying; uniform mat4 modelViewProjectionMatrix; void main() { colorVarying = (position + vec4(0.5,0.5,0.0,0)); gl_Position = modelViewProjectionMatrix * position; }

来自客户的代码片段(目标C):

... glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); ... #pragma mark - OpenGL ES 2 shader compilation - (BOOL)loadShaders { GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // 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, GLKVertexAttribPosition, "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"); uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(_program, "u_heightMap"); glProgramUniform1fvEXT (_program, uniforms[UNIFORM_TEXTURE], nTerrainElements, _pTerrainScaled); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return YES; }

有关设置客户端数据的任何帮助吗?

I'm trying to follow an example from "3D Engine Design for Virtual Globes" by Cozzi and Ring.

I'm trying to use their vertex shader (11.2.2, p. 319), as it seems to provide exactly the starting point for what I need to accomplish (rendering terrain from dense, array-based terrain data):

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

The problem is that I'm not clear how to set up the necessary data in the Objective C client code. Build output shows

TerrainShaderTest[10429:607] Shader compile log: ERROR: 0:31: Invalid qualifiers 'in' in global variable context ERROR: 0:33: 'sampler2DRect' : declaration must include a precision qualifier for type ERROR: 0:37: Use of undeclared identifier 'position' ERROR: 0:37: Use of undeclared identifier 'u_heightMap' ERROR: 0:37: Use of undeclared identifier 'position' 2015-01-08 10:33:30.532 TerrainShaderTest[10429:607] Failed to compile vertex shader 2015-01-08 10:33:30.545 TerrainShaderTest[10429:607] GL ERROR: 0x0500

If I use a different vertex shader instead (below), I get a basic but working result, using the same set up for position on the client side (but obviously not heightmap/texture.)

// WORKS - very simple case attribute vec4 position; varying lowp vec4 colorVarying; uniform mat4 modelViewProjectionMatrix; void main() { colorVarying = (position + vec4(0.5,0.5,0.0,0)); gl_Position = modelViewProjectionMatrix * position; }

Code snippets from client (Objective C):

... glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); ... #pragma mark - OpenGL ES 2 shader compilation - (BOOL)loadShaders { GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // 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, GLKVertexAttribPosition, "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"); uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(_program, "u_heightMap"); glProgramUniform1fvEXT (_program, uniforms[UNIFORM_TEXTURE], nTerrainElements, _pTerrainScaled); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return YES; }

Any help on setting up the client side data?

最满意答案

在iOS上,您将使用OpenGL ES。 最常用的版本是ES 2.0。 从2013年开始发布的设备也支持ES 3.0。

您的着色器代码与ES 2.0不兼容:

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

要使这与ES 2.0一起使用:

ES 2.0仍然使用顶点属性的属性,而不是使用完整OpenGL和ES 3.0+的当前版本。 没有版本的ES支持RECT纹理,因此sampler2DRect类型无效。 使用常规2D纹理,而使用着色器代码中的相应sampler2D 。 ES 2.0使用texture2D()作为纹理采样函数的名称,而不是较新版本中的texture() 。

然后着色器应如下所示:

attribute vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2D u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture2D(u_heightMap, position).r, 1.0); }

On iOS, you will be using OpenGL ES. The most commonly used version is ES 2.0. Devices released starting in 2013 also support ES 3.0.

Your shader code is not compatible with ES 2.0:

in vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2DRect u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture(u_heightMap, position).r, 1.0); }

To make this work with ES 2.0:

ES 2.0 still uses attribute for vertex attributes, instead of in like current versions of full OpenGL, and ES 3.0+. No version of ES supports RECT textures, so the type sampler2DRect is invalid. Use regular 2D textures, with the corresponding sampler2D in the shader code, instead. ES 2.0 uses texture2D() as the name of the texture sampling function, instead of texture() in newer versions.

The shader should then look like this:

attribute vec2 position; uniform mat4 og_modelViewPerspectiveMatrix; uniform sampler2D u_heightMap; void main() { gl_Position = og_modelViewPerspectiveMatrix * vec4(position, texture2D(u_heightMap, position).r, 1.0); }