java - 在使用 java 的 ARCore 中,如何在我的世界中绘制 3D 三角形/线

标签 java android opengl-es-2.0 arcore

对 OpenGL/ArCore 完全陌生并且有一些问题。 我想简单地在 anchor 附近画一个三角形,但不知道该怎么做。 同时我还想画一条线,我有一个原点和一个方向 vector 。

我正在使用谷歌的 ARCore 示例项目作为基础。我可以使用带有以下 Triangle 类的 OpenGL 教程在此屏幕上绘制一个 2D 三角形:

private final String vertexShaderCode =
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "void main() {" +
        // the matrix must be included as a modifier of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

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

private final FloatBuffer vertexBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;

// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = {
        // in counterclockwise order:
        0.0f,  0.622008459f, 0.0f,   // top
       -0.5f, -0.311004243f, 0.0f,   // bottom left
        0.5f, -0.311004243f, 0.0f    // bottom right
};
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f };

/**
 * Sets up the drawing object data for use in an OpenGL ES context.
 */
public Triangle() {
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            triangleCoords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(triangleCoords);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);

    // prepare shaders and OpenGL program
    int vertexShader = MyGLRenderer.loadShader(
            GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = MyGLRenderer.loadShader(
            GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables

}

/**
 * Encapsulates the OpenGL ES instructions for drawing this shape.
 *
 * @param mvpMatrix - The Model View Project matrix in which to draw
 * this shape.
 */
public void draw(float[] mvpMatrix) {
    // Add program to OpenGL environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(
            mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    MyGLRenderer.checkGlError("glGetUniformLocation");

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    MyGLRenderer.checkGlError("glUniformMatrix4fv");

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

更改 trianglecoords 变量内的 z 值根本不会影响绘制三角形,因此我对如何继续感到困惑。

如果您需要知道原因,我正在尝试进行一些射线-三角形相交测试;它的效果不是很好,想测试它如何只用一个三角形。 我为此伤透了脑筋,这样一个看似简单的 Action 竟然如此复杂,这让我非常恼火。

提前致谢!

编辑 我知道 GL 很难进入 ARCore。然而,我的任务涉及玩弄 ARCore,并且由于我也在个人项目中使用 GL,所以我真的很想了解它,而不是使用 Unity/Unreal。

最佳答案

您可以通过设置正确的参数,使用 ShapeFactory.makeCylinder 模拟一条线。然而,这不会出现在 OpenGL 中,但对于一条简单的线来说肯定会产生更少的开销。

我的方法是获取两条线末端的开始和结束词坐标点。然后计算直线的方向和距离,将距离作为圆柱体的长度。将线定位在距离的中间,然后相应地旋转它以适合实际的起点和终点坐标。

关于java - 在使用 java 的 ARCore 中,如何在我的世界中绘制 3D 三角形/线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46547918/

相关文章:

java - 自定义jsp标签创建

android - 应用内视频托管的最佳解决方案

shader - GLES2 是否需要 glBindAttribLocation()?

触摸/释放屏幕时 Galaxy Note 2 上的 Android 线程性能/优先级

java - 重载公共(public)方法

java - 使用 xpath 根据标题选择元素时出现问题

android - 将 LifeCycleOwner 传递给 RecyclerView.Adapter 是否安全

c++ - 检索 gl_FragColor 的值

java - 调用访问器方法的良好做法?

java - 共享重复方法的单独对象