- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试破解通用 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/
我正在编写一个着色器,对场景渲染的纹理产生模糊效果。 我需要在 2 遍中做到这一点,所以通过 P0 进行水平模糊,并在 P1 中进行垂直模糊。 问题是: 我如何在 P0 channel 上获取 PS
我正在尝试从源代码运行 python 应用程序,它具有: from shader import ShaderProgram,ShaderCode 我不知道要下载+安装什么才能获得“着色器”。它非常不具
着色器编译成功,但程序在渲染开始后立即崩溃...这是我得到的错误:“着色器中没有名称为‘u_texture’的制服”。这是我的着色器的样子: #ifdef GL_ES precision medium
当我使用 xcode 8 在 ios 10 中运行我的应用程序时,我在调试控制台中收到以下消息,并且通过 UI 卡住,任何人都可以知道为什么会发生这种情况 ERROR /BuildRoot/Lib
我第一次实现延迟渲染/着色时遇到了一些我自己无法解决的问题:/。 同时渲染几何 channel 和延迟 channel 时,我得到了这个看起来很奇怪的输出 在设置拓扑、输入布局等之前,我在延迟传递的开
我正在为教程开发法线贴图实现,出于教学目的,我想将 TBN 矩阵传递给片段着色器(从顶点着色器),这样我就可以将切线空间中的法线 vector 转换为世界 -照明计算的空间。法线贴图应用于二维平面,其
我第一次尝试将 bool 值传递到我的顶点着色器中;到目前为止我只使用过 float 。 所讨论的 bool 值是特定于原语的,因此不能作为统一传递。然而,对于任何给定图元的所有顶点,它具有相同的值。
这两个是我的 VertexShader 和 Fragment Shader 文件: 顶点着色器文件: attribute vec4 position; attribute vec4 input
我正在尝试在 Unity 中创建线框顶点/片段着色器。根据 this paper 似乎可能.一般的想法似乎是将顶点着色器中计算的距离向量传递给片段着色器中的每个片段,它可以使用它来确定根据线框线在多边
当前正在制作游戏,并试图在单击“菜单”按钮时获得覆盖屏幕的覆盖层-我想这应该是相当普遍/简单的,但是在实现它时仍然有问题。 我当前的设置是: TiledMapRenderer:渲染TMX切片(背景/
什么是应用亮度和对比度的简单像素着色器脚本效果? 我找到了这个,但它似乎不正确: sampler2D input : register(s0); float brightness : register
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在编写一个 PixelShader(HLSL、SM40)并尝试在某些情况下完全跳过输出。我当前的代码如下所示: float4 PS( PS_INPUT input) : SV_Target {
我有一个变量,可以是负数,也可以是正数。 确保其始终为正值的一种方法是: if (var < 0) var = -var; 但是,我认为必须有一个着色器函数可以做到这一点。我正在使用 Cg,但是如果我
就会出现标准 Assets 效应Screen Space Ambient Obscurance不适用于正交相机。这很奇怪,因为基本 SSAO脚本工作得很好。我怀疑问题在于片段深度的计算错误。 有没有办
我需要 CG 片段着色器方面的帮助。我有一个大纹理可以容纳所有瓷砖。我真的不知道从哪里开始。 现在,当四边形/ Sprite 超过一定大小时,我需要重复纹理,因为它是一个纹理。 最佳答案 0Matth
对于运行时生成的着色器代码,我有兴趣探索是否可以直接自动生成编译的 Metal 着色器语言 (MSL) 代码(如 .metallib 文件,并与 newLibraryWithData:error: 方
我正在编写一个 PixelShader(HLSL、SM40)并尝试在某些情况下完全跳过输出。我当前的代码如下所示: float4 PS( PS_INPUT input) : SV_Target {
我有一个变量,它可以是负数也可以是正数。 确保它始终为正的一种方法是: if (var < 0) var = -var; 但是,我认为必须有一个着色器函数可以做到这一点。我正在使用 Cg,但是如果我知
在像素着色器中,您可以丢弃一个像素,但我想即使是为每个像素调用的快速失败着色器也需要花费大量时间?顶点着色器有什么办法可以丢弃整个三角形......我很确定VS无法访问图元但是有什么技巧可以让我们得到
我是一名优秀的程序员,十分优秀!