• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Colorful vectorgraphics

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,414
When drawing vector graphics for a 2d game I decided to instead use drawPrimitives. The problem is that I have a few sprites that uses a total of 250 lines and are using 28 different colors. It would be so useful to be able to draw everything with one command instead of splitting up the graphics and change the color in-between each drawing command. Is there a way to include multiple colors inside one draw command?
 
you could sort your drawing by color aka material and use DrawIndexedPrimitive. That would reduce your amount of draw calls.
 
There is a DrawPrimitives function where you can specify a color for each vertex, so you might be able to render a lot of colorful primitives with only a single draw call as long as you don't change material, blendmode or primitive type.
 
Thanks, I found them in the documentation:

DrawPrimitives : Void ( order:Int, count:Int, vertices:Float[], texcoords:Float[], vertcols:Int[], material:Material=Null )

DrawIndexedPrimitives : Void ( order:Int, count:Int, vertices:Float[], texcoords:Float[], vertcols:Int[], indices:Int[], material:Material=Null )

I read somewhere that someone made a version that could use two colors at once by using negative coordinates for one color and positive coordinates to make switching between two colors quick and save space, but this is amazing as you can have any number of colors here, thanks!
 
Trying to use the API to draw multicolor polygons but It seems that you need to give it texturecoordintes even if you do not use textures.

Why are some white? Note that it seem to work if you replace all 65535 with c in in the If statement?
Code:
#HTML5_CANVAS_ANTIALIAS=False
#GLFW_WINDOW_FULLSCREEN = True
#GLFW_WINDOW_RESIZABLE = True
#GLFW_WINDOW_RENDER_WHILE_RESIZING = True
#MOJO_AUTO_SUSPEND_ENABLED=False
Import mojo2

Function Main ()
    New Game
    Return 0
End   

Class Game Extends App

    Field vertices:Float[]
    Field vertcol:Int[]
    Field indices:Int[]
    Field canvas:Canvas

    Method OnCreate ()
        canvas=New Canvas   
        
        ' Define some polygons
        vertices=New Float[4*2*1000]
        vertcol=New Int[4*2*1000]
            Local sz:=80.0,p:=0
            For Local i:=0 Until 1000
                Local x:=Rnd(DeviceWidth)-sz/2-DeviceWidth/2
                Local y:=Rnd(DeviceHeight)-sz/2-DeviceHeight/2
                vertices[p+0]=x
                vertices[p+1]=y
                vertices[p+2]=x+sz
                vertices[p+3]=y
                vertices[p+4]=x+sz
                vertices[p+5]=y+sz
                vertices[p+6]=x
                vertices[p+7]=y+sz
                
                ' Set polygon color
                Local c:Int ' Purple
                c = PremultiplyColors(1.0,0.0,1.0,1.0) ' r,g,b,a
                vertcol[p+0] = c
                vertcol[p+1] = c
                vertcol[p+2] = c
                vertcol[p+3] = c
                vertcol[p+4] = c
                vertcol[p+5] = c
                vertcol[p+6] = c
                vertcol[p+7] = c
                
                ' Set some polygons to another color
                If Rnd(1) > 0.5
                    ' Yellow
                    c = PremultiplyColors(1.0,1.0,0.0,1.0)
                    vertcol[p+0] = 65535 ' c works fine but 65535 gives a weird overlap white effect
                    vertcol[p+1] = 65535 '
                    vertcol[p+2] = 65535 '
                    vertcol[p+3] = 65535 '
                    vertcol[p+4] = 65535 '
                    vertcol[p+5] = 65535 '
                    vertcol[p+6] = 65535 '
                    vertcol[p+7] = 65535 '
                Endif
                
                p+=8
            Next
            indices=New Int[4000]
            For Local i:=0 Until 4000
                indices[i]=i
            Next   
    End

    Method OnRender : Int()
        canvas.Clear
        ' DRAW POLYGONS
        canvas.SetColor 1,0,0
        For Local i:Int = 0 Until vertices.Length()           
            vertices[i] += Rnd(-1.25, 1.25)
        Next           
        ' API Reference
        ' DrawPrimitives : Void ( order:Int, count:Int, vertices:Float[], texcoords:Float[], vertcols:Int[] )
        ' DrawPrimitives : Void ( order:Int, count:Int, vertices:Float[])
        ' canvas.DrawPrimitives 4,100,vertices ' one color (works)
        canvas.DrawPrimitives 4,100,vertices,vertices,vertcol ' Multicolor (works but weird (texcoords is not interesting bt you need the parameter)
        ' canvas.DrawPrimitives 4,100,vertices,,vertcol ' Multicolor (does now work)
        canvas.Flush
        Return 0     
    End
    
    Function PremultiplyColors:Int(r:Float, g:Float, b:Float, a:Float)
         a *= 255
        Return Int(a) Shl 24 | Int(b * a) Shl 16 | Int(g * a) Shl 8 | Int(r * a)
    End

End
 
Last edited:
I use the variable c now, but i still did not resolve why values such as 65535 gives an XOR kind of effect, bc even if the number is way off and changes alpha by accident it's such a weird thing to create that kind of effect.

It's not easy to understand the indexed version, it seems to need additional parameters "order" and "indices".
What kind of feature does indexed version gives you?
 
I gave each one an indice of it's own. So I got these 4 versions going now.

Code:
#HTML5_CANVAS_ANTIALIAS=False
#GLFW_WINDOW_FULLSCREEN = True
#GLFW_WINDOW_RESIZABLE = True
#GLFW_WINDOW_RENDER_WHILE_RESIZING = True
#MOJO_AUTO_SUSPEND_ENABLED=False
Import mojo2

Function Main ()
    New Game
    Return 0
End   

Class Game Extends App

    Field vertices:Float[]
    Field vertcol:Int[]
    Field indices:Int[]
    Field canvas:Canvas

    Method OnCreate ()
        canvas=New Canvas   
        
        ' Define some polygons
        vertices=New Float[4*2*1000]
        vertcol=New Int[4*2*1000]
            Local sz:=80.0,p:=0
            For Local i:=0 Until 1000
                Local x:=Rnd(DeviceWidth)-sz/2-DeviceWidth/2
                Local y:=Rnd(DeviceHeight)-sz/2-DeviceHeight/2
                vertices[p+0]=x
                vertices[p+1]=y
                vertices[p+2]=x+sz
                vertices[p+3]=y
                vertices[p+4]=x+sz
                vertices[p+5]=y+sz
                vertices[p+6]=x
                vertices[p+7]=y+sz
                
                ' Set polygon color
                Local c:Int ' Purple
                c = PremultiplyColors(1.0,0.0,1.0,1.0) ' r,g,b,a
                vertcol[p+0] = c
                vertcol[p+1] = c
                vertcol[p+2] = c
                vertcol[p+3] = c
                vertcol[p+4] = c
                vertcol[p+5] = c
                vertcol[p+6] = c
                vertcol[p+7] = c
                
                ' Set some polygons to another color
                If Rnd(1) > 0.5
                    ' Yellow
                    c = PremultiplyColors(1.0,1.0,0.0,1.0)
                    vertcol[p+0] = c
                    vertcol[p+1] = c
                    vertcol[p+2] = c
                    vertcol[p+3] = c
                    vertcol[p+4] = c
                    vertcol[p+5] = c
                    vertcol[p+6] = c
                    vertcol[p+7] = c
                Endif
                p+=8
            Next
            indices=New Int[4000]
            For Local i:=0 Until 4000
                indices[i]=i
            Next   
    End

    Method OnRender : Int()
        canvas.Clear
        ' DRAW POLYGONS
        canvas.SetColor 1,0,0
        For Local i:Int = 0 Until vertices.Length()           
            vertices[i] += Rnd(-1.25, 1.25)
        Next           

        ' canvas.DrawPrimitives 4,100,vertices ' Normal
        ' canvas.DrawPrimitives 4,100,vertices,vertices,vertcol ' Multicolor
        ' canvas.DrawIndexedPrimitives 4,100,vertices,indices ' Indexed version of Normal
        canvas.DrawIndexedPrimitives 4,100,vertices,vertices,vertcol,indices ' Indexed version of Multicolor
        
        canvas.Flush
        Return 0     
    End
    
    Function PremultiplyColors:Int(r:Float, g:Float, b:Float, a:Float)
         a *= 255
        Return Int(a) Shl 24 | Int(b * a) Shl 16 | Int(g * a) Shl 8 | Int(r * a)
    End

End
 
Indices are just a way to reuse vertices that you have already defined. For example if you are drawing a rectangle, you do so by defining two triangles constisting of three vertices each. But the two vertices on the shared line are the same. With indices you specify which of the vertices should be used for each triangle so you end up having six indices but only four vertices needed for those two triangles.

BTW We don't have real polygons to draw. If you have primitives of a high order, they are drawn as triangle fans. So be aware that you draw the center of that fan first and then you are pretty free in choosing the positions of all the other corners. Have a look here: https://www.cerberus-x.com/communit...a-poly-with-tile-image-inside.1497/post-12018
 
Last edited:
Thanks, this is a useful command to know. I don't mind that it does not handle polygons of all complexities,
it's still amazing. It was a bit was tricky to understand but this thread cleared everything up.
 
Btw is it okay to use a really high number as a count? I mean instead of several triangles or quads, can you draw one single supercomplex
polygon at once?
 
Back
Top Bottom