Hi all,
A very long time ago, I made a 3D game in AppGameKit for the ill-fated Ouya, a console that seemed promising for indie games. The game wasn't very fluid on the device because it's fill-rate was very slow. One solution for this was to render everything to an image and then display this image as a screen-filling sprite, once all drawing-operations were complete.
Now, I'd like to use that technique again for a 2D game. However, I'm having a hard time getting things to work. Regarding SetRenderToImage and SetRenderToScreen, my assumptions on how to use these commands where these:
- Set the program to draw to an image
- Draw stuff
- Copy the image to a sprite
- Clear the image
- Set the program to draw to the screen
- Position the sprite
I've searched the forum and looked at the examples in the help-files, and I'm... sort of... getting a result. In the code below, I need to hide all the sprites I've positioned or they will show up in both the image and the sprite. This seems wrong and very costly regarding framerates in a game. Can someone help me out and explain what I am doing wrong? I'd appreciate it a lot!
// Project: test_RenderToImage_2
// Created: 19-07-20
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle("test_RenderToImage_2")
SetWindowSize(1280, 720, 0)
SetWindowAllowResize(1) // allow the user to resize the window
// set display properties
SetVirtualResolution(1280, 720) // doesn't have to match the window
SetOrientationAllowed(1, 1, 1, 1) // allow both portrait and landscape on mobile devices
SetSyncRate(30, 0) // 30fps instead of 60 to save battery
SetScissor(0, 0, 0, 0) // use the maximum available screen space, no black borders
SetPrintSize(20)
UseNewDefaultFonts(1)
` ---------------------------------------------------------------------------
// create global variables
dim Sprite[10] as integer
global MaxX# as float
global MaxY# as float
global SprAngle# as float
global Wrap# as float
global WaveHeight# as float
global SpriteSize# as float
global ImgRender as integer ` blank image suitable for rendering
global ImgBuffer as integer ` image used for depth buffer
global SprRender as integer ` sprite that holds render-image
// set values of global variables
MaxX# = GetDeviceWidth()
MaxY# = GetDeviceHeight()
SprAngle# = 0
WaveHeight# = 2.2
SpriteSize# = 100
ImgRender = 1000
ImgBuffer = 1001
SprRender = 1002
ImgRender = CreateRenderImage(MaxX#, MaxY#, 0, 0)
ImgBuffer = CreateRenderImage(MaxX#, MaxY#, 1, 0)
SprRender = CreateSprite(ImgRender)
SetSpriteScale(SprRender, 0.5, 0.5)
SetSpritePositionByOffset(SprRender, GetDeviceWidth()/2.0, GetDeviceHeight()/2.0)
// setup sprites for main loop
for n = 1 to Sprite.Length
Sprite[n] = CreateSprite(0)
r = random(0, 255)
g = random(0, 255)
b = random(0, 255)
a = 255
SetSpriteColor(Sprite[n], r, g, b, a)
SetSpriteSize(Sprite[n], SpriteSize#, SpriteSize#)
SetSpritePosition(Sprite[n], (MaxX# / 4) + (n * 40), (MaxY# / 6.5) + (n * 40))
next n
` ---------------------------------------------------------------------------
// main loop
repeat
// set the scene to render the contents of the screen to the image
SetRenderToImage(ImgRender, ImgBuffer)
// position sprites to test how RenderToImage works
Tilt_Image()
Calculate_Sprite_Positions()
print("RendeToImage test")
// draw the objects we've positioned
SetClearColor(0,0,0) ` set a specific color that is used to fill the back- and depth-buffer once ClearScreen() is called
ClearScreen() ` clear the back- and depth buffer and fill it with the desired color
Update(0) ` update all 2D and 3D objects
Render() ` draw them to the current frame buffer
// set te scene to render the contents of our image to the screen
SetRenderToScreen()
// hide all sprites from the screen so they are only visible on the image
for n = 1 to Sprite.Length
SetSpriteVisible(Sprite[n], 0)
next n
SetClearColor(75,75,75)
Sync()
until GetRawKeyPressed(27) = 1
` ---------------------------------------------------------------------------
function Tilt_Image()
// tilt the sprite that contains the image
inc SprAngle#, 1
if SprAngle# >= 360 then SprAngle# = 0
SetSpriteAngle(SprRender, 30*sin(SprAngle#))
endfunction
` ---------------------------------------------------------------------------
function Calculate_Sprite_Positions()
// calculate new position of the demo-sprites
Wrap# = Wrap# + 0.71
if Wrap# > 360 then Wrap# = 0
// set all sprites to be visible while rendering to the image
for n = 1 to Sprite.Length
SetSpriteVisible(Sprite[n], 1)
x# = GetSpriteX(Sprite[n])
y# = GetSpriteY(Sprite[n])
result# = cos(Wrap#) * WaveHeight#
SetSpritePosition(Sprite[n], x#, y# - (result# * n))
next n
endfunction