1

我是 OpenGL 的新手,我正在尝试找到一种方法来为绘制的对象(例如三角形)赋予某种 ID。通过这种方式,我可以调用 Id 并为其赋予动作以及广告触摸事件。

我不确定这是否是正确的方法,或者是否有更好的方法来做到这一点。我制作了对象,但不知道如何调用它们并赋予它们动作或 onClick 事件。我环顾四周,但是很多方法似乎已经过时并且不起作用,或者链接现在已经死了。

我有一个这样的渲染器:

public class MyGLRenderer implements GLSurfaceView.Renderer {
    private Triangle mTriangle;

    // Called once to set up the view's opengl es environment
    public void onSurfaceCreated(GL10 unused, EGLConfig config){

        //Set the background frame color
        GLES30.glClearColor(255.0f,255.0f,255.0f,0.0f);

        mTriangle = new Triangle();
    }

    // Called for each redraw of the view
    public void onDrawFrame(GL10 gl){
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        //Redraw background color
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);

        mTriangle.draw();
    }

    // Called if the geometry of the view changes (example is when the screen orientation changes from landscape to portrait
    public void onSurfaceChanged(GL10 unused, int width, int height){
        // Called if the geometry of the viewport changes
        GLES30.glViewport(0, 0, width, height);
    }

    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES30.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES30.GL_FRAGMENT_SHADER)
        int shader = GLES30.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES30.glShaderSource(shader, shaderCode);
        GLES30.glCompileShader(shader);

        return shader;
    }
}

表面视图如下:

public class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

    public MyGLSurfaceView(Context context, AttributeSet attrs){
        super(context, attrs);

        //Create an OpenGl 3.0 context
        setEGLContextClientVersion(3);

        mRenderer = new MyGLRenderer();

        //Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);

        //Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}

还有一个三角形类:

public class Triangle {

    private FloatBuffer vertexBuffer;

    private final String vertexShaderCode =
            "attribute vec4 vPosition;" +
                    "void main() {" +
                    "  gl_Position = vPosition;" +
                    "}";

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

    private final int mProgram;

    // 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
    };

    // Set color with red, green, blue and alpha (opacity) values
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

    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);

        int vertexShader = MyGLRenderer.loadShader(GLES30.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader =    MyGLRenderer.loadShader(GLES30.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES30.glCreateProgram();

        // add the vertex shader to program
        GLES30.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES30.glAttachShader(mProgram, fragmentShader);

        // creates OpenGL ES program executables
        GLES30.glLinkProgram(mProgram);
    }

    private int mPositionHandle;
    private int mColorHandle;

    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    public void draw() {
        // Add program to OpenGL ES environment
        GLES30.glUseProgram(mProgram);

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

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

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

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

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

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

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

我想做以下事情:

drawnTriangleObject_ID.Add gravity to move down or up

drawnTriangleObject_ID.OnClick( // Do Something when this object is clicked )
4

1 回答 1

0

在您的三角形类中,添加定位数据

float x = 0.0f;
float y = 0.0f;
float z = 0.0f;

绘制三角形时,您必须应用平移

Matrix.setIdentityM(modelmatrix, 0);
Matrix.translateM(modelmatrix, 0, x, y, z);

然后将模型矩阵乘以视图矩阵

Matrix.multiplyMM(resultmodelview, 0, viewmatrix, 0, modelmatrix, 0);

然后将结果与投影矩阵相乘

Matrix.multiplyMM(resultresultprojection, 0, ProjectionMatrix, 0, resultmodelview, 0);

并发布

World.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, resultresultprojection, 0);

这一切都假设您已经构建了截锥体、投影和视图矩阵(如果您看到三角形,则可能已经完成)..

祝你好运,玩得开心编码!

至于“OnClick”,则有点棘手: - 单击屏幕后,将光线从您的 XY 平面(屏幕)投射到 3D 世界。射线(线)将有 2 个坐标,一个 X、Y、Z 形式的起点和终点,或者可能有一个起点和一个向量(线的方向)......在每一帧上你必须检查如果创建了这条射线,如果是,您需要使用一些数学来检查该线是否与您的三角形相交(在检查与射线的交点之前,不要忘记将三角形的旋转和平移应用到它的顶点)。当框架被绘制时不要忘记删除射线

于 2016-07-22T14:10:01.087 回答