BasicCoder2 wrote:If you mean the Frame rate independent game loop example I did assume the metaballs code was buried in there somewhere I was however thinking in terms of a short simple single file code challenge solution although included files with functions for general use would be acceptable.
Yep. This is the actual metaball rendering code (it's in 'gameLoop.bi'):
Code: Select all
sub GameLoop.render( byval lerp as single = 0.0 )
Renders the screen
The rendering process happens in two passes, and is rather simple: first, all metaballs are
blitted to a render context (here, it is stored in the 'm_context' member variable) using
additive blending. Then, this context is in turn rendered to the screen, pixel by pixel.
If the pixel value (I use the red component in this example) is greater than a certain threshold
(represented by the 'm_threshold' member var), we draw it using the red tint of the pixel read.
If not, we draw it using the full value of the pixel we read before. This creates that 'halo'
effect you see around the metaballs because each metaball is rendered in its own context in
greyscale (check the drawMetaballImage() function in the FBRenderDevice definition).
'' set a background color
dim as uint32 clearColor = rgba( 0, 0, 0, 0 )
dim as integer count = m_state->entityList->count
dim as IEntity ptr e
'' clears the rendering context used for the metaballs
m_context->clearContext( clearColor )
'' first pass: render the metaballs to a separate context
for i as uinteger = 1 to count - 1
e = m_state->entityList->get( i )
e->render( m_renderDevice, m_context, m_state, lerp )
Second pass: render the context to the screen
We don't have to clear the screen, because we are going to overwrite it anyway.
'' Gets the 'handle' of the render device, which is in fact a fb.image ptr
dim as uint32 ptr scrp = m_renderDevice->handle
Skip the header of the context, as FB needs the header to be intact to be
able to put() the buffer later
dim as uint32 ptr bckp = m_context->handle + sizeOf( fb.image ) \ sizeOf( uint32 )
Computes the padding of each scanline
This is done because, when doing low-level rendering code, you have to take into account
that FBGFX aligns the buffer returned by imageCreate() to a multiple of 16 bytes to keep
the buffer aligned (this allows for faster memory access). So, the amount of padding is
simply the pitch minus the buffer width (scaled here to get the value in INTEGERS, not bytes)
dim as integer padding = ( m_context->pitch \ m_context->bitsPerPixel ) - m_context->width
'' the RGBAColor is an union, and is defined in 'math.bi'
dim as RGBAColor c
for y as integer = 0 to m_context->height - 1
for x as integer = 0 to ( m_renderDevice->pitch \ m_renderDevice->bytesPerPixel ) - 1
'' read a pixel from the render context
c = *bckp
'' check if the red component is above 'm_threshold' (try changing this to use the
'' alpha component and see what happens)
if( c.r > m_threshold ) then
*scrp = rgb( c.r, 0, 0 )
*scrp = c
scrp += 1
bckp += 1
'' skip the remaining padding pixels of the scanline
bckp += padding
Renders 'player' entity to screen
Note how we don't pass m_context (the rendering context where the metaballs were rendered) but
the rendering context OF THE SCREEN. We get this context via m_renderDevice->screenContext. Look
at the implementation of FBRenderContext for an explanation on this.
e = m_state->entityList->get( 0 )
e->render( m_renderDevice, m_renderDevice->screenContext, m_state, lerp )
So, you see, the actual metaball rendering thing its merely secondary to the demo.
Yes, they are. That's what the interfaces are for, to treat the two objects polymorphically
, as if they were the same thing. Which, code wise, they actually are =D
I can give further insight in that thread if you wish, to avoid polluting this one.
BasicCoder2 wrote:Still need to digest your 3d stuff and the utube example is rendered in its final version. The utube examples are built up piece by piece. As I wrote this particular example is probably too complex for a simple FreeBASIC version as you would have to duplicate whatever is innate in the processing environment.
Of course it is fully rendered, you're comparing a framework
with plain FB (no libraries). And it's not that the example is complex, but do you want to learn how to define
a Menger Sponge in 3D, or how to render
it? They are two very
different topics, as you can imagine. 3D rendering, unfortunately, isn't as simple as you may think. The paper plane demo shows the basic
math and concepts that you'll need to learn to be able to implement a viewing system
for a 3D engine (camera, objects and the like) without the rendering code.
If we were to start with the rendering, we have to talk about normals, UV coordinates, lighting and shading, among other many topics. All this assuming, of course, that you already grasped the basics (at the very
least, vectors, matrices and projections).
So, to get back on topic:
BasicCoder2 wrote:Coding challenges was only a suggestion and this thread will probably die or diverge into something else like all my other thoughts about how to show case FreeBASIC.
The idea is interesting, but remember that FB is rather 'bare bones', it isn't a framework. There are things that are bound to be more complicated (read: implemented by yourself) to be able to port the coding challenges provided =D