Android 顶点着色器不应用第二个属性数组
考虑一个简单的游戏,有两类对象:球和墙。我发现的教程建议以如下方式使用单个顶点数据数组: […正在初始化…]Android 顶点着色器不应用第二个属性数组,android,opengl-es,Android,Opengl Es,考虑一个简单的游戏,有两类对象:球和墙。我发现的教程建议以如下方式使用单个顶点数据数组: […正在初始化…] vdata = new float[ENOUGH_FOR_ALL]; vertexData = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); aPositionLocation = glGetAttribLocation(programId, "
vdata = new float[ENOUGH_FOR_ALL];
vertexData = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
aPositionLocation = glGetAttribLocation(programId, "a_Position");
glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, false, 0, vertexData);
glEnableVertexAttribArray(aPositionLocation);
[…绘图…]
vertexData.position(0);
vertexData.put(vdata);
glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f); // ball is red
glDrawArrays(GL_TRIANGLE_FAN, 0, BALL_VERTICES + 2);
glUniform4f(uColorLocation, 0.0f, 1.0f, 0.0f, 1.0f); // wall is green
glDrawArrays(GL_LINES, BALL_VERTICES + 2, 2); // wall as a single line
ballVertexData.position(0);
ballVertexData.put(ball_data);
glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f); // ball is red
glUniform1f(uWhatDrawLocation, 1.0f);
glDrawArrays(GL_TRIANGLE_FAN, 0, BALL_VERTICES + 2);
glUniform4f(uColorLocation, 0.0f, 1.0f, 0.0f, 1.0f); // wall is green
glUniform1f(uWhatDrawLocation, 2.0f);
glDrawArrays(GL_LINES, 0, 2); // wall as a single line
而且,顶点着色器非常简单:
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
}
这是可行的,但需要在单个缓冲区中进行繁琐的偏移计算,当某些对象大小改变时移动
考虑以下顶点着色器
attribute vec4 a_Ball;
attribute vec4 a_Wall;
uniform float u_WhatDraw;
void main() {
if (u_WhatDraw == 1.0) {
gl_Position = a_Ball;
}
else if (u_WhatDraw == 2.0) {
gl_Position = a_Wall;
}
}
数据编制如下:
ball_data = new float[BALL_VERTICES + 2];
wall_data = new float[4]; // a single line
ballVertexData = ByteBuffer.allocateDirect(ball_data.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
wallVertexData = ByteBuffer.allocateDirect(wall_data.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
aBallLocation = glGetAttribLocation(programId, "a_Ball");
glVertexAttribPointer(aBallLocation, 2, GL_FLOAT, false, 0, ballVertexData);
glEnableVertexAttribArray(aBallLocation);
aWallLocation = glGetAttribLocation(programId, "a_Wall");
glVertexAttribPointer(aWallLocation, 2, GL_FLOAT, false, 0, wallVertexData);
glEnableVertexAttribArray(aWallLocation);
[…跳过了静态墙_数据的生成…]
[…绘图…]
vertexData.position(0);
vertexData.put(vdata);
glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f); // ball is red
glDrawArrays(GL_TRIANGLE_FAN, 0, BALL_VERTICES + 2);
glUniform4f(uColorLocation, 0.0f, 1.0f, 0.0f, 1.0f); // wall is green
glDrawArrays(GL_LINES, BALL_VERTICES + 2, 2); // wall as a single line
ballVertexData.position(0);
ballVertexData.put(ball_data);
glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f); // ball is red
glUniform1f(uWhatDrawLocation, 1.0f);
glDrawArrays(GL_TRIANGLE_FAN, 0, BALL_VERTICES + 2);
glUniform4f(uColorLocation, 0.0f, 1.0f, 0.0f, 1.0f); // wall is green
glUniform1f(uWhatDrawLocation, 2.0f);
glDrawArrays(GL_LINES, 0, 2); // wall as a single line
这根本不会画墙,尽管球是画出来的
请建议使用2-array方法解决此问题,或者解释为什么我应该在所有活动中使用单个数组的限制
这是可行的,但需要在单个缓冲区中进行繁琐的偏移计算,当某些对象大小改变时移动
如果对象大小发生变化,则需要重新加载新的网格数据,因此计算偏移似乎是最小的问题
或者解释一个限制,为什么我应该为所有活动使用单个数组
添加第三个对象、第四个对象或第五个对象时会发生什么
你优化了错误的问题
任何时候都需要使用if生成着色器。。。你做错了-当应用程序只能做一次时,千万不要让GPU为每个顶点做控制平面决策