gpt4 book ai didi

java - 使用 Android OpenGL ES 2.0 创建 3D 立方体

转载 作者:行者123 更新时间:2023-11-29 10:11:58 25 4
gpt4 key购买 nike

我想在我的屏幕上制作 3D 立方体。不幸的是,在结合了来自不同网站的一些代码后,我仍然无法制作立方体。

有人可以看看我的代码并建议我做错了什么吗?我的想法是让立方体的每个面都有不同的颜色,并且一切都在屏幕上居中。

import android.opengl.GLES20;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Cube {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private ShortBuffer indexBuffer;
private int numFaces = 6;
private int colorHandle;
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";

private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private int MVPMatrixHandle;
private int positionHandle;
private final int program;

static final int COORDS_PER_VERTEX = 3;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

private float[][] colors = { // Colors of the 6 faces
{1.0f, 0.5f, 0.0f, 1.0f}, // 0. orange
{1.0f, 0.0f, 1.0f, 1.0f}, // 1. violet
{0.0f, 1.0f, 0.0f, 1.0f}, // 2. green
{0.0f, 0.0f, 1.0f, 1.0f}, // 3. blue
{1.0f, 0.0f, 0.0f, 1.0f}, // 4. red
{1.0f, 1.0f, 0.0f, 1.0f} // 5. yellow
};

private float[] vertices = { // Vertices of the 6 faces
// FRONT
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
1.0f, -1.0f, 1.0f, // 1. right-bottom-front
-1.0f, 1.0f, 1.0f, // 2. left-top-front
1.0f, 1.0f, 1.0f, // 3. right-top-front
// BACK
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
1.0f, 1.0f, -1.0f, // 7. right-top-back
-1.0f, 1.0f, -1.0f, // 5. left-top-back
// LEFT
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
-1.0f, 1.0f, -1.0f, // 5. left-top-back
-1.0f, 1.0f, 1.0f, // 2. left-top-front
// RIGHT
1.0f, -1.0f, 1.0f, // 1. right-bottom-front
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
1.0f, 1.0f, 1.0f, // 3. right-top-front
1.0f, 1.0f, -1.0f, // 7. right-top-back
// TOP
-1.0f, 1.0f, 1.0f, // 2. left-top-front
1.0f, 1.0f, 1.0f, // 3. right-top-front
-1.0f, 1.0f, -1.0f, // 5. left-top-back
1.0f, 1.0f, -1.0f, // 7. right-top-back
// BOTTOM
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
1.0f, -1.0f, 1.0f // 1. right-bottom-front
};

short[] indeces = {
0, 1, 3, 1, 2, 3,
4, 5, 7, 5, 6, 7,
8, 9, 11, 9, 10, 11,
12, 13, 15, 13, 14, 15,
16, 17, 19, 17, 18, 19,
20, 21, 23, 21, 22, 23,

};

// Constructor - Set up the buffers
public Cube() {
// Setup vertex-array buffer. Vertices in float. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
vertexBuffer.put(vertices); // Copy data into buffer
vertexBuffer.position(0); // Rewind

indexBuffer = ByteBuffer.allocateDirect(indeces.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
indexBuffer.put(indeces).position(0);

int vertexShader = StageRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = StageRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
}

// Draw the shape
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(program);

positionHandle = GLES20.glGetAttribLocation(program, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

MVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);
// Render all the faces
for (int face = 0; face < numFaces; face++) {
// Set the color for each of the faces
colorHandle = GLES20.glGetUniformLocation(program, "vColor");
GLES20.glUniform4fv(colorHandle, 1, colors[face], 0);
}

GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

GLES20.glDisableVertexAttribArray(positionHandle);
}
}

目前我收到这样的结果:

enter image description here

最佳答案

您的索引根本不匹配您的顶点。让我们只看第一张脸。前4个顶点的坐标为:

-1.0f, -1.0f,  1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,

在 x/y 平面上绘制草图,并标明索引:

2---3
| |
| |
| |
0---1

第一个面的索引数组中的条目是:

0, 1, 3, 1, 2, 3,

将其映射到上图中,这些索引定义了以下两个三角形:

    3    2---3
/| \ |
/ | \ |
/ | \|
0---1 1

如您所知,这两个三角形重叠,并没有覆盖整个四边形。您需要的是:

2---3
|\ |
| \ |
| \|
0---1

所以这张脸的一个正确索引序列是:

0, 1, 2, 2, 1, 3,

前 3 个和后 3 个索引现在与两个三角形匹配。另请注意,它们都是按逆时针方向枚举的,如果启用背面剔除,这一点就变得很重要。您将需要以相同的方式为所有其他面修复索引序列。

您的代码中存在一个次要问题,一旦您整理好索引,颜色将无法正常工作:

for (int face = 0; face < numFaces; face++) {
// Set the color for each of the faces
colorHandle = GLES20.glGetUniformLocation(program, "vColor");
GLES20.glUniform4fv(colorHandle, 1, colors[face], 0);
}

由于您在设置每个统一值后没有绘制任何东西,因此在此处使用循环是没有用的。最后,将为颜色设置最后一个值,其他颜色将不使用。

要使其正常工作,您必须在该循环内一次只绘制一张脸(6 个索引)。或者您必须为颜色引入顶点属性,就像您用于位置的顶点属性一样。

关于java - 使用 Android OpenGL ES 2.0 创建 3D 立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30202248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com