web-dev-qa-db-fra.com

Quelle est la façon la plus simple de tracer une ligne à l'aide d'OpenGL-ES (Android)

Si j'ai un rendu personnalisé en opengl-es préparé:

public void onDrawFrame(GL10 gl)
{
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    // here i want to draw line from [0, 0, 0] to [1, 0, 0]
}

Quelle est la manière la plus simple et la plus courte de tracer une ligne?

En OpenGL ordinaire, c'est:

glBegin(GL_LINES);
    glVertex3f(0, 0, 0);
    glVertex3f(1, 0, 0);
glEnd();

Mais comment puis-je obtenir le même effet avec OpenGL ES?

22
Michal

Je suis nouveau dans OpenGL ES 2.0 mais j'ai créé une classe de ligne.

public class Line {
    private FloatBuffer VertexBuffer;

    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
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

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

    protected int GlProgram;
    protected int PositionHandle;
    protected int ColorHandle;
    protected int MVPMatrixHandle;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float LineCoords[] = {
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f
    };

    private final int VertexCount = LineCoords.length / COORDS_PER_VERTEX;
    private final int VertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

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

    public Line() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            LineCoords.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(LineCoords);
        // set the buffer to read the first coordinate
        VertexBuffer.position(0);

        int vertexShader = ArRenderer.loadShader(GLES20.GL_VERTEX_SHADER, VertexShaderCode);
        int fragmentShader = ArRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, FragmentShaderCode);

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

    public void SetVerts(float v0, float v1, float v2, float v3, float v4, float v5) {
        LineCoords[0] = v0;
        LineCoords[1] = v1;
        LineCoords[2] = v2;
        LineCoords[3] = v3;
        LineCoords[4] = v4;
        LineCoords[5] = v5;

        VertexBuffer.put(LineCoords);
        // set the buffer to read the first coordinate
        VertexBuffer.position(0);
    }

    public void SetColor(float red, float green, float blue, float alpha) {
        color[0] = red;
        color[1] = green;
        color[2] = blue;
        color[3] = alpha;
    }

    public void draw(float[] mvpMatrix) {
        // Add program to OpenGL ES environment
        GLES20.glUseProgram(GlProgram);

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

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

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(PositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 VertexStride, VertexBuffer);

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

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

        // get handle to shape's transformation matrix
        MVPMatrixHandle = GLES20.glGetUniformLocation(GlProgram, "uMVPMatrix");
        ArRenderer.checkGlError("glGetUniformLocation");

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

        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_LINES, 0, VertexCount);

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

Et puis, dans ma classe Render, je crée mes objets de ligne et un conteneur afin que le get soit dessiné dans en itérant sur les éléments et en appelant la méthode Line.draw dans onDrawFrame.

Voici quelques lignes que je crée pour faire un horizon:

    Line eastHorz = new Line();
    eastHorz.SetVerts(10f, 10f, 0f, 10f, -10f, 0f);
    eastHorz.SetColor(.8f, .8f, 0f, 1.0f);
    Line northHorz = new Line();
    northHorz.SetVerts(-10f, 10f, 0f, 10f, 10f, 0f);
    northHorz.SetColor(0.8f, 0.8f, 0f, 1.0f);
    Line westHorz = new Line();
    westHorz.SetVerts(-10f, -10f, 0f, -10f, 10f, 0f);
    westHorz.SetColor(0.8f, 0.8f, 0f, 1.0f);
    Line southHorz = new Line();
    southHorz.SetVerts(-10f, -10f, 0f, 10f, -10f, 0f);
    southHorz.SetColor(0.8f, 0.8f, 0f, 1.0f);
    Lines.add(eastHorz);
    Lines.add(northHorz);
    Lines.add(westHorz);
    Lines.add(southHorz);
37
Rodney Lambert

Merci Rodney Lambert pour la classe Line que vous avez fournie. Cependant, il serait également agréable de fournir un appel plus simple dans onDrawFrame, quelque chose comme:

Line vertLine = new Line();
vertLine.SetVerts(-0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f);
vertLine.SetColor(.8f, .8f, 0f, 1.0f);
vertLine.draw(mMVPMatrix);

vertLine.SetVerts (-0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f);

crée définitivement une ligne visible à l'intérieur de la fenêtre

7
escalator