Rendering same vertex-array in different modes

Started by
0 comments, last by 21st Century Moose 7 years, 9 months ago

Hi folks here is my vertex array I am using:


    vertices = [
         -1.0, 1.0, 0.0,
        0.0, 1.0, 0.0,
        -0.5, 1.0, 0.0,
         0.5, 1.0, 0.0,
        1.0, 1.0, 0.0,
        1.0, 0.5, 0.0,
        0.0, 0.5, 0.0,
        0.5, 0.5, 0.0,
        -0.5, 0.5, 0.0,
        -1.0, 0.5, 0.0,

        -1.0, 0.0, 0.0,
        -0.5, 0.0, 0.0,
        0.0, 0.0, 0.0,
        0.5, 0.0, 0.0,
        1.0, 0.0, 0.0,

        -1.0, -0.5, 0.0,
        0.0, -0.5, 0.0,
        -0.5, -0.5, 0.0,
         0.5, -0.5, 0.0,
        1.0, -0.5, 0.0,
        1.0, -1.0, 0.0,
        0.0, -1.0, 0.0,
        0.5, -1.0, 0.0,
        -0.5, -1.0, 0.0,
        -1.0, -1.0, 0.0,
    ];

In a html-select I want to select a rendering mode and use it inmy drawScene-method:


    var renderModeSelector = document.getElementById("renderModeDropDown");
    var selectedRenderModeValue = renderModeSelector.options[renderModeSelector.selectedIndex].value;

    switch (selectedRenderModeValue) {
        case "0":
            gl.drawArrays(gl.POINTS, 0, squareVertexPositionBuffer.numItems);
            break;
        case "1":
            gl.drawArrays(gl.TRIANGLE_FAN, 0, squareVertexPositionBuffer.numItems);
            break;
        case "2":
            gl.drawArrays(gl.LINE_LOOP, 0, squareVertexPositionBuffer.numItems);
            break;
        default:
            console.log("No rendering mode selected.");

    }


  1. Case '0' is supposed to draw the points which works fine

ZiyIL.png

  1. Case '1' should draw a filled rectangle, with the shader below. Unfortunately it is messed up, see also in the picture below.

Fragment shader:


    precision mediump float;

    varying vec4 vColor;

    void main(void) {
    gl_FragColor = vColor;
    }

Vertex-shader:


    attribute vec3 aVertexPosition;
    attribute vec4 aVertexColor;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    varying vec4 vColor;

    void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vColor = aVertexColor;
    gl_PointSize = 5.0;
    }

vahR1.png

3. And finally in case '2' it is supposed to draw only the outlines, which also does not work as expected, see below.

23zah.png

So I wonder if it is possible to meet my requirements while using one vertexPositionBuffer. Also if it is not what would be another appropriate solution? Should I create another vertexPositionBuffer or can I just change mine "on the fly", before rendering?


Advertisement

The vertex order requirements will be different for different modes. Typically you can't really expect a triangle fan and a line loop, for example, to be representable by the same vertices in the same order.

For a triangle fan, for example, the first vertex you specify is common to all triangles in the fan. Every subsequent pair of vertices defines a triangle, with an overlap of 1 vertex between triangles, such that the vertex order is 0|1|2, 0|2|3, 0|3|4, 0|4|5, etc. The number of triangles in the fan is equal to the number of vertices - 2. A line loop is completely different.

One way to deal with this type of drawing is to switch the polygon mode (using glPolygonMode) between GL_LINE and GL_FILL. This of course assumes that your actual objective is to provide a "wireframe mode" view of your regular geometry, and will allow you to use GL_TRIANGLE_FAN for both the fill and line options, so you only need be concerned about getting the correct vertex order for that mode. I don't think this is available on ES (or WebGL, which it looks like you're using), however.

Another way is to define every vertex you're going to need in your vertex buffer, then add index buffers specifying the actual vertices (and their order) for each different mode. Select the appropriate index buffer and draw using glDrawElements.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement