Custom primitive not shown ?

Hello, I’m trying to learn how to use cesium rendering.

I’ve been trying to create a vary simple primitive that will just draw a simple line and go from there.

I’ve created an update method that creates a vertexArray with 2 points, then I create a simple Vshader and a Fshader and a draw command.

I get no errors and cesium continues normally but I dont see the line anywhere, can anyone please try and help me?

    update(frameState) {
        if (!this._show) {
            return;
        }

        let context = frameState.context;
        let vertexArray = this.createVertexArray(context);
        this._shaderProgram = Cesium.ShaderProgram.replaceCache({
            context: context,
            shaderProgram: this._shaderProgram,
            vertexShaderSource: `
            attribute vec3 position;

            void main() {
                gl_Position = czm_modelViewProjection * vec4(position, 1.0);
            }
`,
            fragmentShaderSource: `
            void main()
            {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }`
        });

        this._renderState = Cesium.RenderState.fromCache({
            cull: {
                enabled: true,
                face: Cesium.CullFace.FRONT
            },
            depthTest: {
                enabled: false
            },
            depthMask: true,
            blending: undefined
        });

        this._drawCommand.modelMatrix = this._computedModelMatrix;
        this._drawCommand.renderState = this._renderState;
        this._drawCommand.shaderProgram = this._shaderProgram;
        this._drawCommand.vertexArray = vertexArray;
        this._drawCommand.pass = Cesium.Pass.OVERLAY;

        let commandList = frameState.commandList;
        commandList.push(this._drawCommand);
    }

    private createVertexArray(context: any) {
        var vertexBuffer = Cesium.Buffer.createVertexBuffer({
            context: context,
            typedArray:new Float32Array([3648448.5117112226, 997327.3223067619, 5118713.136337872, 0.0332181295, 0.284035355, 0.431658396]),
            usage: Cesium.BufferUsage.STATIC_DRAW
        });

        var indexBuffer = Cesium.Buffer.createIndexBuffer({
            context: context,
            typedArray: new Uint16Array([0,1]),
            usage: Cesium.BufferUsage.STATIC_DRAW,
            indexDatatype: Cesium.IndexDatatype.UNSIGNED_SHORT
        });

        let attributes = [
            {
                index: 0,
                enabled: true,
                vertexBuffer: vertexBuffer,
                componentsPerAttribute: 3,
                componentDatatype : Cesium.ComponentDatatype.FLOAT,
                normalize: false,
                offsetInBytes: 0,
                strideInBytes: 0
            }
        ];

        return new Cesium.VertexArray({context:context, attributes:attributes, indexBuffer:indexBuffer});
    }

While recreating this in Sandcastle I noticed a few issues. Since you are rendering a line you’ll need to set the draw command’s primitive type to LINES. It’s also usually a good idea to set the draw command’s bounding volume so that cesium renders it in the correct frustum and not clipped by the near plane. It didn’t really matter in this example though. I didn’t change too much else, but check out the code below in Sandcastle in case there are other differences.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

scene.primitives.add(new MyPrimitive());

function MyPrimitive() {

this.drawCommand = undefined;

}

MyPrimitive.prototype.update = function(frameState) {

if (Cesium.defined(this.drawCommand)) {

frameState.commandList.push(this.drawCommand);

}

var context = frameState.context;

var vertexBuffer = Cesium.Buffer.createVertexBuffer({

context: context,

typedArray:new Float32Array([3648448.5117112226, 997327.3223067619, 5118713.136337872, 0.0332181295, 0.284035355, 0.431658396]),

usage: Cesium.BufferUsage.STATIC_DRAW

});

var indexBuffer = Cesium.Buffer.createIndexBuffer({

context: context,

typedArray: new Uint16Array([0,1]),

usage: Cesium.BufferUsage.STATIC_DRAW,

indexDatatype: Cesium.IndexDatatype.UNSIGNED_SHORT

});

var attributes = [{

index: 0,

enabled: true,

vertexBuffer: vertexBuffer,

componentsPerAttribute: 3,

componentDatatype : Cesium.ComponentDatatype.FLOAT,

normalize: false,

offsetInBytes: 0,

strideInBytes: 0

}];

var vs = “attribute vec3 position; \n” +

“void main() { \n” +

" gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n" +

“} \n”;

var fs = “void main() { \n” +

" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" +

“} \n”;

var shaderProgram = Cesium.ShaderProgram.fromCache({

context: context,

vertexShaderSource: vs,

fragmentShaderSource: fs

});

var vertexArray = new Cesium.VertexArray({

context : context,

attributes : attributes,

indexBuffer : indexBuffer

});

var renderState = Cesium.RenderState.fromCache({

cull: {

enabled: true,

face: Cesium.CullFace.FRONT

},

depthTest: {

enabled: false

},

depthMask: true,

blending: undefined

});

var drawCommand = new Cesium.DrawCommand({

vertexArray : vertexArray,

shaderProgram : shaderProgram,

modelMatrix : Cesium.Matrix4.IDENTITY,

cull : false,

primitiveType : Cesium.PrimitiveType.LINES,

pass : Cesium.Pass.OPAQUE

});

this.drawCommand = drawCommand;

};

``

Hi!, First of all thanks alot it is now working, I have a few follow up questions that I would like an answer to if you may.

First of all why do we need to use the primitiveType : Cesium.PrimitiveType.LINES, I’ve searched quite a lot cesium code (polyline collection for example) and I’ve not seen you use it there.

My second question is of a bug I’m seem to be having, for some reason it looks like anything I draw floats above the earth, for example I now compute and draw ellipses but the just float above the earth and not on it like they should :

Here is my updated code: (or in the attached file)

my update function :

update(frameState) {
    if (!this._show) {
        return;
    }

    let context = frameState.context;

    this.vertexArray = (this._dirty || !this.vertexArray) ? this.createVertexArray(context) : this.vertexArray;

    this.setupShaderProgram(context);
    this.setupRenderState();
    this.setupDrawCommand();

    frameState.commandList.push(this._drawCommand);
}

I create the shaders:

    private setupShaderProgram(context: any) {
        EllipsePrimitive._shaderProgram = EllipsePrimitive._shaderProgram || Cesium.ShaderProgram.replaceCache({
                context: context,
                shaderProgram: EllipsePrimitive._shaderProgram,
                vertexShaderSource: `
            attribute vec3 position;

void main() {
    gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
`,
                fragmentShaderSource: `

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}`
            });
    }

vertexArray:

private createVertexArray(context: any) {

    this._dirty = false;

    var vertexBuffer = Cesium.Buffer.createVertexBuffer({
        context: context,
        typedArray:new Float32Array(this._points.outerPositions),
        usage: Cesium.BufferUsage.STATIC_DRAW
    });

    let attributes = [
        {
            index: 0,
            enabled: true,
            vertexBuffer: vertexBuffer,
            componentsPerAttribute: 3,
            componentDatatype : Cesium.ComponentDatatype.FLOAT,
            normalize: false,
            offsetInBytes: 0,
            strideInBytes: 0
        }
    ];

    return new Cesium.VertexArray({context:context, attributes:attributes, indexBuffer:this.createIndexBuffer(context)});
}

ellipsePrimitive.ts (5.36 KB)

Polylines often contain thickness to them which makes triangles a better primitive type to use. Some other geometries in Cesium use LINES however (like SimplePolylineGeometry).

At a quick glance, I don’t think the model matrix should include the center translation since the positions are already positioned on the globe. The extra translation seems to be pushing them out further.

Ho I completely forgot that I made that haha, thank you for pointing that out.