[SOLVED] Trying to create a simple red triangle

To get a little closer to the metal with PlayCanvas, I set out to create a simple red triangle entirely in code. Here is the code I’m trying:

CreateTriangle.prototype.initialize = function() {
    // Create Mesh
    var mesh = pc.createMesh(this.app.graphicsDevice, [0,0,0,0,-1,0,1,-1,0]);
    
    // Create Material and set diffuse color to red
    var material = new pc.StandardMaterial();
    material.diffuse.set(1, 0, 0);
    material.update();
    
    // Create mesh instance
    var node = new pc.GraphNode();
    var meshInstance = new pc.MeshInstance(node, mesh, material);
    
    // Create model
    var model = new pc.Model();
    model.meshInstances.push(meshInstance);
    
    // Create entity
    var entity = new pc.Entity();

    // Add a new Model Component to the entity
    entity.addComponent("model", {
        model: model
    });
    
    // Add Entity to the scene hierarchy
    this.app.root.addChild(entity);    
};

Unfortunately, it’s not working. I don’t get any errors but the triangle does not appear on screen. What am I doing wrong?

Not tested, but here are two things might be missing for you to try:

model.graph = node;
this.app.scene.addModel(model);

Thanks for the quick reply, unfortunately your solution didn’t work.

Additional info: I noticed by using console.log() that entity.model.model is null. Which leads me to believe that something isn’t right with

entity.addComponent("model", {
        model: model
});

but I can’t figure out what.

Have you tried just assigning the model after?

1 Like

Ok, we may be on to something. Assigning the model after seems to work. Now the model component no longer shows null but actually has a model. I’m still not seeing anything on screen though. And now I’m getting the following warning in the console:

570479:1 [.Offscreen-For-WebGL-000001F90E484A10]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 1
570479:1 WebGL: too many errors, no more errors will be reported to the console for this context.

Any other ideas?

Ok, I have finally figured it out. Here is what I believe to be the minimal code necessary to create a simple, flat, red, triangle. Explanations follow.

CreateTriangle.prototype.initialize = function() {
    // Create Mesh
    var mesh = pc.createMesh(this.app.graphicsDevice, [0,0,0,0,0,5,5,0,0], {
        normals: [0,1,0,0,1,0,0,1,0],
        uvs: [0,0,0,1,1,0]
    });
    
    // Create Material and set diffuse color to red
    var material = new pc.StandardMaterial();
    material.diffuse.set(1, 0, 0);    
    
    // Create mesh instance
    var node = new pc.GraphNode();
    var meshInstance = new pc.MeshInstance(node, mesh, material);
    
    // Create model
    var model = new pc.Model();
    model.meshInstances.push(meshInstance);
    
    // Create entity
    var entity = new pc.Entity();

    // Add a new Model Component to the entity
    entity.addComponent("model", {
        model: model
    });
    
    // Add Entity to the scene hierarchy
    this.app.root.addChild(entity);
};

How did I figure this out?
At first, I thought the problem was with the material. To test my theory, I replaced pc.createMesh with pc.createPlane. I figured a plane was the closest thing to what I was trying to create and I knew there wouldn’t be any trouble with the mesh since it was being created behind the scenes by PlayCanvas. Lo and behold, a red plane appeared on screen. Conclusion: the material was fine, the problem was with the way I created the mesh. But what was I doing wrong?

I decided to take a look at the engine source code for pc.createPlane, to see how it was using pc.createMesh. That’s where I realized that it was passing more than just vertex positions, but it was also passing normals, uvs, uvs1, indices and tangents. I figured that this might be the problem with my mesh; I was only passing vertex positions. So I started by passing normals. Still nothing on screen. Then I added uvs… Bingo, my red triangle appeared. uvs1, indices and tangents were not necessary.

I think that the pc.createMesh(device, positions, opts) documentation could be improved. Right now it says that the third argument, opts, is “An object that specifies optional inputs for the function”. In my mind, optional means not necessary, not compulsory. In practice, though, if you don’t pass normals and uvs to the function, your mesh won’t work. Unless I’m wrong about this, the documentation should probably be updated to reflect this reality.

3 Likes

i use this code,I don’t get any errors but the triangle does not appear on screen.

2 Likes

I recognize the age of the initial posting, yet … still get the exact same error/no-appearance as youxiaohui

PS: Have tried to turn camera angle 180 degrees as well - no difference

me too