Documentation
This is an opengl Es 3.0 graphics library for android devices. You can use it for prototyping, 2D games and simulations. The texture atlas and the UI system are not yet fully stable still have some improvements to make. Would be cool if i add feature like lighting, custom shaders and postprocessing effects.
Setup and Intergration
You can import the library by downloading the release extract the zip file then import it to android studio or intellij as a module project. Click on File->New-> importModule
Alternative
- Download the release extract the zip file then copy it directly to the project directory.
- Open setting.gradle and add the following line
include ':GLCanvas'
- Open app:build.gradle and in the dependancies tree add the following line.
implementation project(':GLCanvas')
How to Use
1.0 Setting up a renderer
Create a renderer class and extend GLRendererView. GLRendererView is a wrapper that overrides GLSurfaceView.Renderer methods and accepts two arguments the surfaceWidth and surfaceHeight. It keeps all the bloat away.
class GLCanvasRenderer(private val context: Context,width: Float, height: Float) : GLRendererView(width, height) {
//init resources eg textures, fonts, camera and batches
override fun prepare() {
}
// draw objects every frame here
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
GLES32.glClearColor(0f,0f,0f,1f)
}
// update your logic here
override fun update(delta: Long) {
}
//delete all textures and clean opengl memory here when the app exits
override fun onRelease() {
}
1.1 Setting up a SurfaceView
In your mainActivity create a GLCanvasSurfaceView object and set the renderer.
class MainActivity : AppCompatActivity() {
private var surface: GLCanvasSurfaceView?=null
private var renderer:GLCanvasRenderer?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//create a renderer
renderer=GLCanvasRenderer(this ,1280.0f,720.0f)
// pass in the application context and renderer
surface= GLCanvasSurfaceView(this, renderer!!)
// set this surface to view
setContentView(surface)
}
override fun onPause() {
super.onPause()
}
override fun onResume() {
super.onResume()
}
override fun onDestroy() {
super.onDestroy()
renderer?.onRelease()
}
}
1.2 Create a Camera and a Batch
The camera helps us project stuff on the screen. The batch helps us draw various objects on the screen using OpenGL functions.
class GLCanvasRenderer(private val context: Context,width: Float, height: Float) : GLRendererView(width, height) {
private val batch = Batch()
// creates a camera with a height value
private val camera= Camera2D(10.0f)
//init resources eg textures, fonts, camera and batches
override fun prepare() {
// initializes the shaders being used by the batch
batch.initShader(context)
// creates an orthogonal projection
camera.setOrtho( getCanvasWidth(), getCanvasHeight())
}
// draw objects every frame here
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
GLES32.glClearColor(0f,0f,0f,1f)
}
// update your logic here
override fun update(delta: Long) {
}
//delete all textures and clean opengl memory here when the app exits
override fun onRelease() {
}
2.0 Rendering Objects
A. Quads
// creates a square of coordinates x,y, width and height
private var rect=RectF(300f,300f,100f,100f)
// draw quad in the draw loop
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
GLES32.glClearColor(0f,0f,0f,1f)
// prepare the batch for drawing
batch.begin(camera)
// pass in the rect object for drawing
batch.draw(rect)
//close the batch, render everything on the screen and flush
batch.end()
}
functions
- setConnerRadius- creates a rounded rect object
- setThickness- creates a hollow quad.
B. Circles
// creates circle at coordinates x,y radius
private var circle=Circle(100f,600f,50f)
// draw quad in the draw loop
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
//clear the surface to color black
GLES32.glClearColor(0f,0f,0f,1f)
// prepare the batch for drawing
batch.begin(camera)
// pass in the circle object for drawing
batch.draw(circle)
//close the batch, render everything on the screen and flush
batch.end()
}
C. Triangle
// creates a polygon object
private var triangle=Polygon()
//move to origin
triangle.moveTo(300f,790f)
//first triangle
triangle.lineTo(300f,850f)
triangle.lineTo(350f,850f)
//second triangle
triangle.lineTo(250f,850f)
triangle.lineTo(300f,850f)
// draw quad in the draw loop
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
GLES32.glClearColor(0f,0f,0f,1f)
// prepare the batch for drawing
batch.begin(camera)
// pass in the polygon object for drawing
batch.draw(polygon)
//close the batch, render everything on the screen and flush
batch.end()
}
The polygon object is not limited to just two triangles you can create complex shapes too. If the polygon coordinates keep changing every frame call the reset function to clear previous vertex data.
//clear previous vertex data
triangle.reset()
D. PolyLine
private var polyline=PolyLine()
//creates an an array of lines based on an origin point
// moveTo creates an origin
// lineTo creates a line connected to the defined origin
polyline.moveTo(100f,100f)
polyline.lineTo(200f,100f)
polyline.moveTo(200f,100f)
polyline.lineTo(200f,300f)
polyline.moveTo(50f,300f)
polyline.lineTo(200f,300f)
polyline.moveTo(50f,300f)
polyline.lineTo(50f,400f)
polyline.moveTo(50f,400f)
polyline.lineTo(100f,400f)
// draw quad in the draw loop
override fun draw() {
GLES32.glClear(GLES32.GL_DEPTH_BUFFER_BIT or GLES32.GL_COLOR_BUFFER_BIT)
GLES32.glClearColor(0f,0f,0f,1f)
// prepare the batch for drawing
batch.begin(camera)
// pass in the polyline object for drawing
batch.draw(polyline)
//close the batch, render everything on the screen and flush
batch.end()
}
Just like the polygon object you can clear the data from the polyline if it changes every frame. Using the reset function ofcourse.
//clear previous vertex data
polyline.reset()
3.0 Colors and Gradients
In GLCanvas there is a ColorRGBA object that is used to define colors data.
constructors
- ColorRGBA(value)- Initializes all the values in the object with a single scalar value.
- ColorRGBA()- Creates a color object with default values of 1.0. (White)
- ColorRGBA(color)- Copies data from another color object.
- ColorRGBA(r,g,b,a)- Initializes the color object with different RGBA values.
functions
- darken- accepts two arguments as inputs. a. A factor of float ranging from (0.0f-1.0f). Lower values will make the color darker. b. A target ColorRGBA object.
- set- modifies the RGBA valuesa of the color object .
- setAlpha- modifies the alpha value.
- get- returns a single RGBA value using an index position.
- getData- returns an array of RGBA values.
constants a *R- * red value. b *G- * green value. c *B- * blue value. d *A- * alpha value. e default colors- transparent, red, white ,blue, green, gray, lightGray, yellow, pink, cyan.
Each of the rendereable objects contains properties like colors and gradients that can be tweaked according to your needs.
functions
- setColor- accepts a ColorRGBA object as an input to change the model’s color.
- gradient- accepts an array of colors per vertex arrays to create a smooth gradient.
3.1 Texures
Textures can be loaded from the asset folder using the Texture class. Only load the textures in the onPrepare method.
private var texture:Texture?=null
override fun prepare(){
texture=Texture(context,"texture.png")
}
Texures are binded to objects using the setTexure function.
3.2 Transformations
functions
-
rotations:-
- setRotationX(angleInDegrees)- rotates the object across the x axis.
- setRotationY(angleInDegrees)- rotates the object across the y axis.
- setRotationZ(angleInDegrees)- rotates the object across the center.
-
scale:-
- setScale(scaleX,ScaleY)- scales an entity.
4.0 SpriteSheet and Animation
GLCanvas supports spriteSheet 2D animations. You can also define the spritesheet coordinates manually or populate the data from an external parser.
Spritesheets animations can be created for shapes such as circles and quads. The animations are defines by an animationFrame object passed in the animator class. Every object is automatically initialized with a default (1,1) spriteSheet.
//define a quad object
private var rect=RectF(300f,300f,200f,200f)
init{
//loads a 4x4 spriteSheet
rect.setTexture(Texture(context,"flyingDragon.png")
//specify the width and height of the spritesheet
rect.setSpriteSheet(SpriteSheet(4,4))
/*create an animator object and pass in animation frames using the AnimationFrame class. Sprite animator accepts an animation id as a string , animationFrame object and the spritesheet object*/
// first let's create the frames
val flyFrame=AnimationFrame(
//the animation time fro each frame
arrayOf(100L,100L,100L,100L),
//frames to show in the texture
arrayOf(0,1,2,3))
/*then create the animator object this will update the animation every frame in the update method*/
val animator=SpriteAnimator("fly",flyFrame,rect.getSpriteSheet())
rect.setAnimator(animator)
//other constraints
//activates the animation as active
animator.setActivated(true)
//loops throught the animation forever
animator.setLooping(true)
// sets the current animation
animator.setCurrent("fly")
}
....
// the animation will be automatically be updated in the update method
override fun update(delta: Long) {
rect.update(delta)
}
SpriteSheet Functions
- *resize(width,height)- resizes the spritesheet with new values.
- clone-creates an identical copy of the sheet.
- getCurrentFrame– returns the current active array of frames.
- getFrameAt-returns an array of floats for a given frame.
AnimationFrame Functions
- setFrameLength(arrayofLong)-sets the timer for each frame.
- setFrames(arrayOfInts)– sets the frames for this animation.
- getFrames()-returns the array of frames.
- getFrameLength()-returns the array of frameLength.
- getCurrent()-returns the current active frame index.
- reset()– resets the animationFrame.
SpriteAnimator functions
- put(name, animationFrame,sheet)– adds an animationFrame to the animator.
- setCurrent(key)-sets the current animationFrame.
- getCurrentFrame()-returns the current active animationFrame.
- isActivated()– returns a boolean flag indicating whether the animation is active.
- isLooping()– returns a boolean flag. Test is looping is enabled.
- setLooping(boolean)-set the loop flag.
- reset()-reset the animation counter.
- update(delta)-updates the animation everyFrame.