G2D: Bringing OpenGL to PlayBASIC for Enhanced Rendering

November 15, 2015

 

G2D: Bringing OpenGL to PlayBASIC for Enhanced Rendering

G2D is a promising alternative rendering library for PlayBASIC, offering an OpenGL-based solution for graphics rendering. While PlayBASIC traditionally uses DirectX and software rendering, G2D leverages the power of the OpenGL API to provide a more efficient and flexible rendering option. Although G2D is still in its early stages, the library has already shown significant potential in terms of compatibility and performance.

What is G2D?

At its core, G2D is a minimal rendering library built to work with PlayBASIC, a beginner-friendly programming language for game development. It replaces PlayBASIC’s default rendering system with OpenGL, offering a faster, more modern alternative for developers seeking improved graphical performance.

Currently, G2D supports a basic set of commands, including primitives like lines, shapes, and images. These commands work similarly to their PlayBASIC counterparts, but all rendering happens on the OpenGL canvas, ensuring faster performance in windowed modes.

It’s important to note that G2D is currently only compatible with PlayBASIC’s windowed modes, as it directly attaches the OpenGL viewport to the PlayBASIC window. To hide the default DirectX screen, you can use the `ScreenLayout` command to position it outside the window.

Building Basic Image Support

One of the first features G2D developers focused on was integrating basic image commands. The goal was to maintain compatibility with PlayBASIC’s internal image management system (AFX) while utilizing OpenGL for rendering. When an image is loaded into G2D, it’s first imported into PlayBASIC’s internal image slot and then converted into a texture that OpenGL can use. This dual approach allows developers to continue using PlayBASIC’s native sprite and collision functions while benefiting from the performance gains of OpenGL.

Expanding Core Primitives

In the early stages, G2D developers concentrated on expanding the core primitive commands for more complex scenes. One challenge was making sprites compatible with OpenGL’s efficient rendering pipeline. OpenGL, like Direct3D, performs best when rendering many polygons from a single texture to reduce overhead, but PlayBASIC’s sprites are handled differently.

To solve this, G2D developers experimented with ways to efficiently render sprites while preserving PlayBASIC’s collision and vector-based interactions. One solution was creating a dedicated GL sprite layer that caches texture states, reducing texture swaps between polygons. This approach mitigates performance issues when sprites constantly switch textures.

For maps, G2D introduced the `g2dDrawMap` function, which allows PlayBASIC maps to be rendered using OpenGL textures. This function takes parameters like texture index and map layout, enabling seamless integration with PlayBASIC’s map system while utilizing OpenGL for faster rendering.

Optimizing Sprite Rendering with `g2dDrawAllSprites`

After implementing basic image support, the G2D team moved on to optimizing sprite rendering. The `g2dDrawAllSprites` function was introduced to handle large numbers of sprites efficiently. It takes advantage of OpenGL’s ability to batch multiple sprite draw calls into a single operation, improving performance even with a high volume of sprites.

In early tests, the `g2dDrawAllSprites` function was able to render 1000 anti-aliased sprites at 27 frames per second on a standard test machine without optimization. While impressive, G2D developers acknowledged the need for further optimizations to improve rendering speed.

Dealing with Sprite Issues and Legacy Commands

During development, the G2D team encountered challenges with legacy PlayBASIC sprite commands, particularly functions like `GetSpriteRect()` and `SpriteInRegion()`, which are critical for determining sprite visibility and bounding boxes in the OpenGL viewport. These functions were causing crashes and unexpected behavior, so the G2D team worked to fix them.

The fixes involved rewriting portions of the code to ensure that the OpenGL-based wrapper functions interacted correctly with PlayBASIC’s internal sprite system. While some legacy functions, like sprite clipping, may still not work as expected, these issues are being addressed in ongoing updates.

Introducing `g2dDrawOrderedSprite` for Scene Sorting

To further optimize G2D, the team introduced the `g2dDrawOrderedSprite` function, which allows sprites to be sorted by depth values. This ensures that objects closer to the camera are rendered in front of objects that are farther away—essential for creating 2D scenes with proper layering and depth.

The `g2dDrawOrderedSprite` function works similarly to PlayBASIC’s `DrawOrderedSprite` command, but with the added advantage of OpenGL’s GPU acceleration. This enhancement allows G2D to handle complex scenes more efficiently by offloading rendering to the GPU.

Future Plans and Challenges

Although G2D has made impressive strides, many features and improvements are still in the works. Future updates will focus on adding interfaces for more advanced features like maps, shapes, and fonts. The G2D team is also working to resolve performance issues related to texture sizes, particularly for fonts, which may cause problems if the texture exceeds the size limits of older graphics cards.

For font rendering, the team plans to convert text into meshes and render them onto the OpenGL surface. While feasible, this approach requires attention to texture sizes, especially for large characters. As G2D continues to evolve, the goal is to make font rendering more flexible and optimized for a wide range of hardware configurations.

Conclusion

G2D is an exciting new rendering library for PlayBASIC that harnesses the power of OpenGL for faster and more efficient graphics rendering. Although still in the early stages, G2D already provides a solid foundation for developers looking to enhance the graphical performance of their PlayBASIC projects. With ongoing improvements and optimizations, G2D promises to be a valuable tool for PlayBASIC developers, offering more flexibility and control over rendering while maintaining compatibility with PlayBASIC’s internal systems.

As G2D evolves, it has the potential to become a go-to solution for developers looking to push the limits of PlayBASIC and OpenGL, making it an exciting development to follow for anyone interested in 2D game programming with PlayBASIC.


About the Author:

Kevin Picone is the creator of PlayBASIC, a beginner-friendly programming language for creating 2D games, and the lead developer of the G2D particle library. With years of experience in both game development and programming tools, Kevin is passionate about making powerful game creation tools accessible to everyone, from beginner to advanced developers.


Links:

  • G2D - 2D OpenGL library for PlayBASIC (WIP / BLOG / SCRATCH PAD)
  • PlayBASIC,com

  • Syntax Highlighting PlayBASIC Code Example

    August 03, 2012

     

    Vector Library

    This is simple library of 2d vector functions. Bellow is the example.

    	//  Use a typed array to hold all the vectors we'll be using
    	Dim vectors(100) as vector2d
    	for lp =0 to getArrayElements(vectors())
    		vectors(lp)= new vector2D
    	next
    
    
    	//  declare some pointers of type vector
    	// for use in the examples
    	Dim N as vector2d pointer
    	Dim V1 as vector2d pointer
    	Dim V2 as vector2d pointer
    	Dim OldPoint as vector2D pointer
    
    	//  Get pointers to some pre--alloated
    	//  vectors in our cache array
    	n = Vectors(0).vector2d
    	V1 = Vectors(1).vector2d
    	V2 = Vectors(2).vector2d
    
    
    	Dim CurrentPoint as vector2D pointer
    	CurrentPOint = Vectors(3).vector2d
    
    	Dim OldPoint as vector2D pointer
    	OldPOint = Vectors(4).vector2d
    
    	Dim Lerp1 as vector2D pointer
    	Lerp1 = Vectors(10).vector2d
    
    	Dim Lerp2 as vector2D pointer
    	Lerp2 = Vectors(11).vector2d
    
    
    	SetVector2d lerp1, 500,100
    	SetPolar2d lerp2, Rnd(36),rndrange(10,100)
    	Addvectors2d Lerp2, Lerp2, Lerp1
    
    
    
    	// Set up this vector
    	Setvector2d OldPOint,Mousex(),MouseY()
    	Flushmouse
    
    	// -----------------------------------------
    	Do
    	// -----------------------------------------
    
    		CLS
    
    
    		// Set up this vecor
    		Setvector2d CurrentPoint,Mousex(),MouseY()
    
    
    		circlec OldPoint.X,OldPoint.Y, 50,true, $00ff00
    
    		circle CurrentPoint.X,CurrentPOint.Y, 50,true
    
    
    		// Subtract target from current  N = Old - Current
    		Subvectors2d(N , oldPoint,CurrentPoint)
    
    		ypos= 50
    
    		text 10,Ypos, "Delta:"+StrVector2d$(N)
    
    		//  Get the length of this delta vector
    		Dist#=GetVectorLenght2D(N)
    
    		// normalize N = and store it back in N
    		GetVectorNormal2D(N , N)
    
    		text 10,Ypos+30, "Normalized:"+StrVector2d$(N)
    
    
    		//  Scale Normal by Dist#
    		Multvector2d(N , N, Dist#)
    
    		text 10,Ypos+60, "Scaled Normalized:"+StrVector2d$(N)
    
    		//  Add origin (current point) back on.
    		Addvectors2d(N , N, CurrentPoint)
    
    		text 10,Ypos+90, "Result:"+StrVector2d$(N)
    
    
    		//  Scale it  so we can draw line between them
    		line CurrentPOint.x,CurrentPOint.y,n.x,n.y
    
    		if Mousebutton()=1
    				CopyVector2d OldPoint,CurrentPOint
    		endif
    
    
    		//  test lerp
    		Linec Lerp1.x,Lerp1.y,Lerp2.x,Lerp2.y, $ff00ff
    
    		//
    		LerpFrame		=mod(LerpFrame+1,100)
    		LerpScale#		=LerpFrame/100.0
    
    		LerpVector2d N,Lerp1,Lerp2,LerpScale#
    
    		Circlec n.x , n.y, 5, true ,$ff00ff
    
    
    		//  Curve Lerp vector to the one between
    		LerpVector2d V1,Lerp1,Lerp2,LerpScale#
    		LerpVector2d V2,CurrentPoint,OldPoint,LerpScale#
    		LerpVector2d V1,V2,V1,LerpScale#
    		Circlec v1.x , v1.y, 5, true ,$ff00ff
    
    		LerpVector2d V1,Lerp1,Oldpoint,LerpScale#
    		LerpVector2d V2,lerp2,CurrentPoint,LerpScale#
    		LerpVector2d V1,V2,V1,LerpScale#
    		Circlec v1.x , v1.y, 5, true ,$ff00ff
    
    		Sync
    
    loop  Spacekey()


    Amiga Demos

    October 10, 2011

     

    Metal Combat - Planar 3D Engine Tech Demo For Amiga A1200

    This short video is taken of a tech demo I wrote for the Amiga 1200 way back in 1995/1996. The demo is showing a planar based filled polygon rendering engine designed for A1200/020 systems with fast memory. The idea was to render the spans with the CPU and interleave this with the blitter, which turned out to be fairly good solution at the time.

    While this demo was originally developed to test the viability of the planar rendering concept, the hope was it'd be fast enough to build a Virtual Fighter styled game. With more optimization it probably would have been, but we didn't get that far.

    Code By: Kevin Picone
    Music By: Ardarc






    (Broken) Reality 1994/1995 Amiga Tech Demo

    The original goal of the Reality project was to create a Wolf 3D / Blade Stone styled 2.5D game engine for Amiga A1200 / 020 with Fastmem. It was pretty ambitious at the time, and looking back I wouldn't say that we ever really met our objective, but certainly gave it a good shot. The only down side was that almost nobody got to see it, so here's a warts and all version!

    The version shown here is about the only code that still assembles. There's newer versions of the source code, but they're missing lots of external files. None the less, this supports textured walls / floors with flat shaded polygons.

    For polygons, the original idea was to draw triangles as vertical spans, so they could be clipped against the walls 1D z buffer. But sadly that's not in this version. The walls are connected together line segments, to draw the view, we get a cone of verts and draw the walls attached (to the verts) into the depth buffer. The floors clip to the smallest wall segment in the buffer, so sadly there's a lot of overdraw, not to mention the funky texture slipping....

    The demo in the video, is running through the WinUAE emulator with an image of my A1200 hard drive. Most stuff seems to run ok, except the (AsmOne) assemblers ?, not sure why, but the combination seems rather unstable. So when you factor in the obvious bugs in my code ! :), this is best I can get it running in the short time available :( ... Hence the "Broken" Reality title.... Shame, I was enjoying the nostalgia.

    Code By: https://www.UnderwareDesign.com
    Art By: Raven (Textures are from Heretic)
    Music By: Ardvarc






    Vic Vision - Convert C64 Images To IFF (Amiga Program)

    Vic Vision is a program for Classic Amigas that converts raw Commodore 64 graphic images into Amiga IFF format. It was developed for 64 artists, demo / Game coders, nostalgia freaks, who might be moving onto the Amiga and would like to take their favorite artwork with them.

    Vic Vision supports many popular formats directly, such as FLI, AFLI, CFLI, Blazing Paddles, Koala, Raw Hardware Sprite Data, 8*8,8*16,16*16 fonts and many others, and also incorporates a custom format editor, allowing users to add support for either their own formats or any other that we've overlooked.






    Z Rotate (Amiga)


    This as a (very short) clip of another retro Amiga AGA effect. This is one a slightly different take on the regular Z-Rotate that was common at that time (Min 90's). It was later released as part of the experimental PLLB c2p package. Pllb is a set of C2p routines aimed at A1200 / 68020 with Fastmem.

    The demo is running _not_ running real hardware here sorry, my A1200 died long ago. None the less, you'll be able to find the demo on my site soon enough.

    https://www.UnderwareDesign.com






    Gouraud Cube (Amiga)

    This as a (very short) clip of another retro Amiga AGA effect, the classic gouraud cube.. Original, I know :).. Sadly the video compression kills the shading a bit though. Not too sure when this was first made now, probably been 1995/ 1997. The gouraud code is as you'd imagine it, pretty slow in retrospect. I think, it was only ever released as part of the experimental PLLB c2p package. Pllb is a set of C2p routines aimed at A1200 / 68020 with Fastmem.

    The demo is running _not_ running real hardware here sorry!, my A1200 died long ago. None the less, you'll be able to find the demo on my site soon enough.

    https://www.UnderwareDesign.com








    AGE Example - Loading 256 Colour Picture In AmosPro

    In very short this video we see the AGE library wrapper being used from AmosPRO. The demo frame work sets up the library, create a screen, loads the 8bit (256 colour) IFF, creates a copper list and then displays it.

    Developed By:
    https://www.underwaredesign.com







    Compressed Anim Replayer (Amiga AGA)


    This clip is showing a decompression system written for Amiga AGA 68020 systems back in around 1997/1998. The routine was written as a demo part where the objective was to get the animation data as small as possible, while retaining around a 10/12fps replay on real Amiga A1200/68020 hardware.

    The original animation consists of 120 frames, where each frame is 160x * 128y in 64 colours. The raw planar data for the whole animation weighs in at approximately 1440 odd K, even though the packer uses chucky pixels.

    The packer uses a three pass filter, stage one handlers string style byte repetitions, then there's a type a control byte replacement, with a bit merger pass at the end. The final code (which is big mess :) ), is long away from the original delta block / tile style packer, I'd intending upon using. But it worked out ok in the end.

    The compressed anim comes in 859K, so it's about 40% reduction over the raw planar version. What's surprising today though, is that ratio is still better than just LHA / LHX / RAR / ZIP'ing the original raw anim. But they're generic, and this was crafted to pack this animation and only this animation.

    Developed By:
    https://www.UnderwareDesign.com