Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 顶点着色器不应用第二个属性数组_Android_Opengl Es - Fatal编程技术网

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为每个顶点做控制平面决策