How to draw a triangle?

I’d like to draw a solid triangle either to screen or a bitmap that i can later use - how is this simple task to be accomplished?
Triangle will be a simple color (no pattern), partially transparent (yes alpha). I am looking at ifDraw2D and see no means for that. Graphic libraries usually have a polygon-fill primitive, which i’s even better - but i could live with a mere triangle (any polygon can be broken down to triangles anyway). No flood-fill either.

Drawing it with line segments, one end pinned at vertex A while the other end loops from B to C won’t work - color intensity near A will be higher than near BC due to alpha blending/addition of the lines. Don’t want to use pre-rasterized images in consideration of different screen resolutions (don’t want diagonal lines jagged by scaling) - also the number of images needed will be too big to package with channel.

You can’t draw a filled triangle (or a circle, or a polygon, or…) with the 2D API. If you want to hack it, you could potentially draw a rectangle, rotate it to the desired angle, clip it and then rotate it back. Or, you could carve it out of a rectangle with a fully transparent rectangle rotated to the desired angles and drawn on top with alpha blending disabled.

Endless beat me to it but it seems the only way is to hack it with squares and rectangles. Pretty glaring omission from a 2D API. IMO.

Library "v30/bslDefender.brs"
Sub Main()
	font_registry = CreateObject("roFontRegistry")
	font = font_registry.GetDefaultFont()
	codes = bslUniversalControlEventCodes()
    m.screen=CreateObject("roScreen", true)
    m.msgport=CreateObject("roMessagePort")
    m.screen.SetPort(m.msgport)
    m.screen.Clear(&h394837FF)
    m.screen.SetAlphaEnable(true)
    m.screen.DrawText("background", 530, 250, &hebebebFF, font)
    
    square = CreateObject("roBitmap", {width: 400, height: 400, AlphaEnable: true})
  	square.Clear(&h25344399)
  	rect = CreateObject("roBitmap", {width: 565, height: 280, AlphaEnable: false})
  	rect.drawRotatedobject( 0, 285, 45, square)
  	m.screen.drawobject(357, 220, rect)
    m.screen.Swapbuffers()
   	rowrow = 0	
   	
   	while true
   	m.screen.Clear(&h394837FF)
   	m.screen.DrawText("background", 530, 250, &hebebebFF, font)
   	msg = m.msgport.getmessage()
    if type(msg) = "roUniversalControlEvent"
   	button = msg.getint()
   	if button=codes.BUTTON_RIGHT_PRESSED	
   	rowrow = rowrow + 45
   	m.screen.drawRotatedobject(357, 220, rowrow, rect)
   	m.screen.Swapbuffers()
   	end if
  	end if
   	end while
End Sub

“TheEndless” wrote:
If you want to hack it, you could potentially draw a rectangle, rotate it to the desired angle, clip it and then rotate it back. Or, you could carve it out of a rectangle with a fully transparent rectangle rotated to the desired angles and drawn on top with alpha blending disabled.
That surely is an evil hack but i am interested in trying it. I understand it conceptually but for now the 2D mechanics (esp. roRegions) are way over my head. Can you sketch the two approaches - as sequence of steps/components used to form triangle in a new bitmap? Broad strokes, no need code to work or make actual triangle - i can RTFM and try for the rest.

Actually, nevermind. It seems that DrawRotatedObject() only supports arbitrary angles on devices with OpenGL support. I guess that’s why they never updated the documentation.

The only other way I can think to do it would be something like this, but it’s likely to produce jaggies. It does run faster than I expected, though…

' This will create a right triangle lying on its long side
' Create a bitmap the size of the outer bounds of the triangle
' Make sure alpha enable is false, so the lines cut through the bitmap
triangle = CreateObject("roBitmap", { Width: 400, Height: 200, AlphaEnable: False })
' Clear the bitmap to the color you want
triangle.Clear(&HFFFFFFFF)
' Clear out the left slope
For x = 0 To 200
    triangle.DrawLine(x, 0, x - 200, 200, &H00000000)
Next
' Clear out the right slope
For x = 200 To 400
    triangle.DrawLine(x, 0, x + 200, 200, &H00000000)
Next

“TheEndless” wrote:
It seems that DrawRotatedObject() only supports arbitrary angles on devices with OpenGL support. I guess that’s why they never updated the documentation.

What! :shock:
You mean the 27x0 line (RokuLT/Roku1/Roku2) - the joy and pride of RokuCo from Sep 2013 - cannot rotate to angles <> 90*n ?
What about Roku3, can it?

This shatters my belief, which was based on viewtopic.php?f=34&t=56314&p=432102#p432100
The suspicious silence of Roku* on the question suddenly seems to speak volumes. :oops:

“EnTerr” wrote:

“TheEndless” wrote:
It seems that DrawRotatedObject() only supports arbitrary angles on devices with OpenGL support. I guess that’s why they never updated the documentation.

What! :shock:
You mean the 27x0 line (RokuLT/Roku1/Roku2) - the joy and pride of RokuCo from Sep 2013 - cannot rotate to angles <> 90*n ?
What about Roku3, can it?

This shatters my belief, which was based on viewtopic.php?f=34&t=56314&p=432102#p432100
The suspicious silence of Roku* on the question suddenly seems to speak volumes. :oops:
I’m guessing at the “OpenGL” support being required, but if it is, then it should work on Roku 3. I have my dev Roku 3 disconnected at the moment, to avoid the temptation to use it while I work on a 2D API channel, so I can’t test it right now…

Here is a quick ROKU 3 example, since I don’t have your will power. I unplugged my 2XD

 
   Screen = CreateObject( "roScreen", True )
   Screen.Clear( &hFFFFFFFF )
   Screen.SwapBuffers()
   
   bitmap = CreateObject( "roBitmap", { width: 200, height: 200 , AlphaEnable: False } )
   bitmap.Clear( &h911820FF )
   width  = bitmap.GetWidth()
   height = bitmap.GetHeight()
   region = CreateObject( "roRegion", bitmap, 0, 0, width, height )
   
   x = int( width  / 2 )
   y = int( height / 2 )
   region.SetPretranslation( -x, -y )
   
   for theta = 360 to 0 step -1
      Screen.Clear( &hFFFFFFFF )
      Screen.DrawRotatedObject( 100 + x, 100 + y, theta, region )
      Screen.SwapBuffers()  
   end for

If an “Ode to the triangle” were needed, this video would do:
https://www.youtube.com/watch?v=KdyvizaygyY

I know this thread is a bit old, but since triangles are so common I thought I’d relay what I think is an important point…

You CAN draw solid-color triangles with any arbitrary 3 points as corners. You won’t be able to draw them quickly though, and you’ll need to do a lot of computation in B.Script.
Google/Bing/Search for “triangle rasterizer” and also maybe “Graphics Gems”. There’s even logic for triangle rasterization published in that Graphics Gems book (Maybe vol III…I don’t remember) if you can find it.

Basically, you decide which side (left/top or right/bottom) will get it’s end-points included, and then draw horizontal lines at the proper starting points and ending points moving from top to bottom. Think TV scan lines as the horizontal lines you’re drawing where they “fit” the triangle.

This type of stuff was common in “the old days” before GPUs.

This can be extended to other shapes also…polygons and even circles. Convex shapes or concave shapes where no horizontal line crosses multiple start/end points. You basically do the computations for the edges of the “scan line overlap” (AKA rasterize the shape) and pass an array of points to a rasterizer-drawing routine that draws the horizontal lines in a given color.

It’s slow in B.Script though. I wrote a simple one a year or two ago, but it wasn’t fast enough for my needs so I abandoned it. Maybe you’ll do better. Once you have the shape, you can always put it in a texture and blit it quickly…until you need to “reshape” it. Then you re-compute.

“MazeWizzard” wrote:
I know this thread is a bit old, but since triangles are so common I thought I’d relay what I think is an important point…

It’s slow in B.Script though. I wrote a simple one a year or two ago, but it wasn’t fast enough for my needs so I abandoned it. Maybe you’ll do better. Once you have the shape, you can always put it in a texture and blit it quickly…until you need to “reshape” it. Then you re-compute.
Thank you for chiming in. Thread is not too old, i have neither solved, nor given up on the idea i have (just haven’t got developing on it - i have small list of things i work on, on and off).

I did think of scan-line rasterizing (it’s not hard but will have to be careful with degenerate cases, like all 3 vertices on same horizontal line + alpha blending). Initially i was concerned that when i am working in non-native resolution (say if i use roScreen is 854x480 when player is in 720p or 1080p mode), that will lead to triangles turning into horizontal stripes, with gaps forming between the horizontal lines i draw due to zooming. I did not find discussion anywhere how the scaling is done - it could be vector or bitmap-wise, with different outcomes. I still don’t know for sure and since it is not documented, it can potentially change (?!).

But performance is my biggest concern - as an idea of speed i would hope to be able to draw something like this spinning tetrahedron:

[upload|uNLeUPDDehhlU5mJjXZfFA==]

My gut feeling is line-by-line won’t be able to. Was your routine close to such speed, ballpark?

Thank you for chiming in. Thread is not too old, i have neither solved, nor given up on the idea i have (just haven’t got developing on it - i have small list of things i work on, on and off).

I did think of scan-line rasterizing (it’s not hard but will have to be careful with degenerate cases, like all 3 vertices on same horizontal line + alpha blending). Initially i was concerned that when i am working in non-native resolution (say if i use roScreen is 854x480 when player is in 720p or 1080p mode), that will lead to triangles turning into horizontal stripes, with gaps forming between the horizontal lines i draw due to zooming. I did not find discussion anywhere how the scaling is done - it could be vector or bitmap-wise, with different outcomes. I still don’t know for sure and since it is not documented, it can potentially change (?!).

But performance is my biggest concern - as an idea of speed i would hope to be able to draw something like this spinning tetrahedron:

bump bump bump ( better late than never )

why alpha blending? isn’t alpha on roku 2D compositing alpha only? my memory is kinda fuzzy on alpha in 3D, but I vaguely rem it has something to do with raycasting, no?

anyway, I bring it up as it might be a bottleneck. (maybe. maybe not.)

as for performance, try this: http://bloggingwordpress.com/2012/08/ro … ster-demo/

and for those too lazy to click on the link, instead of real-time, why not have your triangle render engine be an offline one, creating sprite sheets for you at load time?

“rokujoel” wrote:
“can we draw to a bitmap directly and then show that bitmap?”

Effectively, drawing to a bitmap is the same operation as drawing to the screen – the screen is sort of a giant bitmap, pretty much anything that works on the screen will work to a bitmap, I believe you will need to call bitmapname.finish() after drawing to bitmaps, just like to the screen,(weird stuff can happen if you don’t) or possibly bitmapname.swapbuffers() under double buffering situations (not sure if bitmaps other than the screen can be double buffered).

but I’ll be bold and say YES! that is possible, with backface culling ( alpha issue? ), I totally believe a Roku 2 can draw 2 (flat shaded) Triangles in realtime using BrightScript*… but probably not much else. :wink:

  • disclaimer, I’m not even going to guess what the FPS would be.

Be aware that drawing first to a bitmap, then to the the screen requires twice as many draws, which will further slow down your render time.

“TheEndless” wrote:
Be aware that drawing first to a bitmap, then to the the screen requires twice as many draws, which will further slow down your render time.
good call.

So, then shouldn’t the pre-rendered sprite-sheet solution work? Assuming sufficient time between 3D objects are used?

“dev42” wrote:

“TheEndless” wrote:
Be aware that drawing first to a bitmap, then to the the screen requires twice as many draws, which will further slow down your render time.
good call.

So, then shouldn’t the pre-rendered sprite-sheet solution work? Assuming sufficient time between 3D objects are used?
In theory.

“dev42” wrote:
why alpha blending? isn’t alpha on roku 2D compositing alpha only? my memory is kinda fuzzy on alpha in 3D, but I vaguely rem it has something to do with raycasting, no?What 3D?! I never said 3D… did the animated GIF above mislead you - those just 2 triangles visible at any one time, showing the speed and size i was looking for. I am a simple, 2D person :sunglasses:

The Alpha is for see-through when two partially transparent figures overlap (fancification).

as for performance, try this: http://bloggingwordpress.com/2012/08/ro … ster-demo/That one is interesting - thanks, I need to look at the code - image is horribly grainy though, like drawn with a chainsaw.

and for those too lazy to click on the link, instead of real-time, why not have your triangle render engine be an offline one, creating sprite sheets for you at load time?Nope, not really - the game should work offline, no justification to make it depend on outside server. Figures be moving and rotating, can’t precompute it all. Theoretically there is ifDraw2D.DrawRotatedObject but that one is limited to 90 degree rotations (i.e. mostly useless). Unofficially, a few of the players (with GLES - 3xxx, 4200) will rotate to non-multiples of 90 but the rest just draw Nada.

and for those too lazy to click on the link, instead of real-time, why not have your triangle render engine be an offline one, creating sprite sheets for you at load time?Nope, not really - the game should work offline, no justification to make it depend on outside server. Figures be moving and rotating, can’t precompute it all. Theoretically there is ifDraw2D.DrawRotatedObject but that one is limited to 90 degree rotations (i.e. mostly useless). Unofficially, a few of the players (with GLES - 3xxx, 4200) will rotate to non-multiples of 90 but the rest just draw Nada.
by “offline” I meant to say precomputed. Like right before they are needed… like during a “loading” screen or something. If enough rotations of the object are precomputed, stored in your sprite sheet, you can pick and choose which frames to display. Movement is the same for “normal” sprites ( those loaded from disk ).

As for triangle drawing code:

http://www.sunshine2k.de/coding/java/Tr … ation.html

My guess is without anti-aliasing it’ll look pretty jagged, but I still believe it’s doable just not sure how much else can be moving on the screen at the same time. :wink:

“dev42” wrote:

as for performance, try this: http://bloggingwordpress.com/2012/08/ro … ster-demo/

:shock:

neat. that is pretty amazing. that’s the coolest thing I’ve seen today.

Update:

I can now draw 2D triangles! With alpha!
http://forums.roku.com/viewtopic.php?f=34&t=75545#p461149

BTW, I forgot that there was a 3D Ray Casting thread that went along with that blog post:
http://forums.roku.com/viewtopic.php?f=34&t=51299&p=348167&hilit=raycaster#p348115

It’s been a while since I played around with it. I’m not even sure if I can find the version with RokuJoel’s updates. Does anybody remember how he’s drawing the rectangles? Is he drawing all the walls? Even those that are occluded? In other words, is there any Hidden Surface Removal going on?

As for performance improvements, I remember this running pretty slowly, but our Roku’s have been updated since then. So, who knows?!

more when I have it.

peace & 42