Ok so had some fun making a mirror object here, but cannot get the image in the mirror to flip. I have a simple memblock image flipper function that works fine in other programs, but as soon as you touch the image created from CreateRenderImage the Vulkan engine throws an error when it goes to SetRenderToImage.
My initial idea was that if I could flip the image from CreateRenderImage() before it was populated and it would stick, and I wouldn't need to call the memblock image flip every frame which is a deal breaker on performance. I know this is a silly thought as the pixels are empty, but worth a try for performance. OpenGL does allow me to call the image flip function after CreateRenderImage, but my dream of it being already flipped when SetRenderToImage gets called did not pan out.
Not sure if anyone is able to make sense of this craziness? Has anyone been able to make a mirror object with a properly flipped image in real time?
// Project: Mirror_test
// Created: 21-05-21
// show all errors
`#renderer "Basic" //OpenGL
SetErrorMode(2)
// set window properties
SetWindowTitle( "Mirror_test" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // 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
UseNewDefaultFonts( 1 )
SetPrintSize(18)
create3DPhysicsWorld(1)
Set3DPhysicsGravity(0, -40, 0)
SetAmbientColor(150, 150, 150)
MoveCameraLocalZ(1, 5)
`SetSkyBoxVisible(1) //SKYBOX DOES NOT WORK WITH THIS?!?!
global camcon_camSpeed as float = 1.5 //Camera movement
global camcon_rotateStartX as float //Camera movement
global camcon_rotateStartY as float //Camera movement
type miller //Reggie Miller for the 3 Point buzzer beater
x as float
y as float
z as float
endtype
type mirrorObj //Mirror object data type
object as integer //3D Plane object
pos as miller //Position of plane object
ang as miller //Angle of plane object
size as miller //Size of the plane object
img as integer //Image grabbed from render used to create mirror
endtype
global mirrorList as mirrorObj[] //Mirror objects get placed in this array
mirrorList.length = -1
global diag_numReflects as integer = 0 //Diagnostics - number of active mirrors reflecting
loadRoom()
myMover = CreateObjectBox(2, 2, 2)
SetObjectColor(myMover, 150, 89, 255, 255)
SetObjectPosition(myMover, 0, 3, 0)
Create3DPhysicsDynamicBody(myMover)
SetObject3DPhysicsFriction(myMover, 0.25)
SetObject3DPhysicsCanSleep(myMover, 0)
mirrorSize as miller
mirrorPos as miller
mirrorAng as miller
mirrorSize = reggie(4, 4, 0)
mirrorPos = reggie(-4, 2.25, 5)
mirrorAng = reggie(0, 315, 0)
addMirrorPlane(mirrorSize, mirrorPos, mirrorAng, 1.0) //Mirror middle left
mirrorPos = reggie(4, 2.25, 5)
mirrorAng = reggie(0, 45, 0)
addMirrorPlane(mirrorSize, mirrorPos, mirrorAng, 1.0) //Mirror middle right
mirrorSize = reggie(8, 8, 0)
mirrorPos = reggie(-10, 4.25, 0)
mirrorAng = reggie(0, 270, 270)
addMirrorPlane(mirrorSize, mirrorPos, mirrorAng, 0.1) //Big mirror left (LOW RESOLUTION)
mirrorPos = reggie(10, 4.25, 0)
mirrorAng = reggie(0, 90, 0)
addMirrorPlane(mirrorSize, mirrorPos, mirrorAng, 1.0) //Big mirror right
mirrorSize = reggie(15, 10, 0)
mirrorPos = reggie(0, 5, 15)
mirrorAng = reggie(0, 0, 0)
addMirrorPlane(mirrorSize, mirrorPos, mirrorAng, 1.0) //Big middle mirror
do
print("FPS: " + str(ScreenFPS()))
print("Move box with arrow keys")
print("Move camera with WASD, Middle Mouse button & wheel")
print("~~~~~~~")
print("Number of Mirrors Total: " + str((mirrorList.length) + 1))
print("Number of Mirrors Active: " + str(diag_numReflects))
cameraControls() //Watch for any camera movement
mirrorReflect()
if (GetRawKeyState(38)) then SetObject3DPhysicsLinearVelocity(myMover, 0, 0, 1, 5)
if (GetRawKeyState(40)) then SetObject3DPhysicsLinearVelocity(myMover, 0, 0, -1, 5)
if (GetRawKeyState(37)) then SetObject3DPhysicsLinearVelocity(myMover, -1, 0, 0, 5)
if (GetRawKeyState(39)) then SetObject3DPhysicsLinearVelocity(myMover, 1, 0, 0, 5)
Step3DPhysicsWorld()
Sync()
loop
function addMirrorPlane(getSize as miller, getPos as miller, getAng as miller, getResolution as float)
myMirror as mirrorObj
myMirror.size = reggie(getSize.x, getSize.y, getSize.z) //Mirror size
myMirror.pos = reggie(getPos.x, getPos.y, getPos.z) //Position
myMirror.ang = reggie(getAng.x, getAng.y, getAng.z) //Angle
myMirror.object = CreateObjectPlane(myMirror.size.x, myMirror.size.y)
SetObjectPosition(myMirror.object, myMirror.pos.x, myMirror.pos.y, myMirror.pos.z)
SetObjectRotation(myMirror.object, myMirror.ang.x, myMirror.ang.y, myMirror.ang.z)
myMirrorImgScale = getResolution * 100 //Not sure if this improves performance or not
myMirror.img = CreateRenderImage(myMirrorImgScale * myMirror.size.x, myMirrorImgScale * myMirror.size.y, 0, 0) //Create blank image to render to
`myMirror.img = imageFlipH(myMirror.img)
mirrorList.insert(myMirror)
endfunction
function mirrorReflect()
cameraPos as miller //Record position of camera
cameraAng as miller //Record angle of camera
cameraPos = reggie(GetCameraX(1), GetCameraY(1), GetCameraZ(1))
cameraAng = reggie(GetCameraAngleX(1), GetCameraAngleY(1), GetCameraAngleZ(1))
diag_numReflects = 0 //Diagnostics - number of active mirrors
for i=0 to mirrorList.length
if (GetObjectInScreen(mirrorList[i].object))
SetCameraPosition(1, mirrorList[i].pos.x, mirrorList[i].pos.y, mirrorList[i].pos.z) //Move camera position to the
SetCameraRotation(1, mirrorList[i].ang.x, mirrorList[i].ang.y - 180, mirrorList[i].ang.z)
`SetCameraAspect(1, mirrorList[i].size.x / mirrorList[i].size.y)
`DeleteImage(mirrorList[i].img)
`myMirrorImgScale = 1.0 * 100
`mirrorList[i].img = CreateRenderImage(myMirrorImgScale * mirrorList[i].size.x, myMirrorImgScale * mirrorList[i].size.y, 0, 0) //Create blank image to render to
Update3D(0)
SetRenderToImage(mirrorList[i].img, 0) //Render the view to an image in memory
ClearScreen()
ClearDepthBuffer()
Render3D()
SetRenderToScreen()
SetCameraPosition(1, cameraPos.x, cameraPos.y, cameraPos.z)
SetCameraRotation(1, cameraAng.x, cameraAng.y, cameraAng.z)
`SetCameraAspect(1, GetVirtualWidth() / GetVirtualHeight())
SetObjectImage(mirrorList[i].object, mirrorList[i].img, 0) //Set the mirror image
diag_numReflects = diag_numReflects + 1
endif
next i
endfunction
function imageFlipH(getImg as integer)
returnImage as integer //Flipped image to return
iflip_mb_a as integer //Memblock passed image
iflip_mb_b as integer //Memblock flipped image
iflip_mb_width as integer //Width of image
iflip_mb_height as integer //Height of image
iflip_mb_depth as integer //Depth of image
iflip_mb_a = CreateMemblockFromImage(getImg)
iflip_mb_width = GetMemblockInt(iflip_mb_a, 0) //Memblock Image: Bytes 0-4 = Width
iflip_mb_height = GetMemblockInt(iflip_mb_a, 4) //Memblock Image: Bytes 4-7 = Height
iflip_mb_depth = GetMemblockInt(iflip_mb_a, 4) //Memblock Image: Bytes 8-11 = Depth
iflip_mb_b = CreateMemblock(GetMemblockSize(iflip_mb_a))
SetMemblockInt(iflip_mb_b, 0, iflip_mb_width)
SetMemblockInt(iflip_mb_b, 4, iflip_mb_height)
SetMemblockInt(iflip_mb_b, 8, iflip_mb_depth)
for i=0 to iflip_mb_height - 1 step 1
for j=0 to iflip_mb_width - 1 step 1
iflip_mb_a_offset = 12 + (i * iflip_mb_width * 4) + (j * 4) //Image A: Go left to right for each row
iflip_mb_b_offset = 12 + (i * iflip_mb_width * 4) + (((iflip_mb_width - 1) - j) * 4) //Image B: Go in reverse (right to left) for each row
SetMemblockInt(iflip_mb_b, iflip_mb_b_offset, GetMemblockInt(iflip_mb_a, iflip_mb_a_offset))
next j
next i
returnImage = CreateImageFromMemBlock(iflip_mb_b)
DeleteMemblock(iflip_mb_a)
DeleteMemblock(iflip_mb_b)
endfunction returnImage
function cameraControls()
if GetRawKeyState(65) Then MoveCameraLocalX(1, -1)
if GetRawKeyState(68) Then MoveCameraLocalX(1, 1)
if GetRawKeyState(87) Then RotateCameraLocalX(1, -1)
if GetRawKeyState(83) Then RotateCameraLocalX(1, 1)
if (GetRawMouseWheelDelta() > 0) //Mouse Wheel Scroll Up (Zoom In)
MoveCameraLocalZ(1, camcon_camSpeed)
endif
if (GetRawMouseWheelDelta() < 0) //Mouse Wheel Scroll Down (Zoom Out)
MoveCameraLocalZ(1, camcon_camSpeed * -1)
endif
if GetRawMouseMiddlePressed() //This is only on when the middle mouse button is first pressed (off while GetRawMouseMiddlePressed() is true)
camcon_rotateStartX = GetPointerX() //Get the current mouse position, the rotation is based on this
camcon_rotateStartY = GetPointerY()
endif
camcon_camSpeed = 0.75 //Speed that the camera will rotate
if GetRawMouseMiddleState() //Rotate camera while holding down mouse wheel
if (GetPointerX() < camcon_rotateStartX)
RotateCameraLocalY(1, camcon_camSpeed * -1) //Mouse moving left, rotate camera left
elseif (GetPointerX() > camcon_rotateStartX)
RotateCameraLocalY(1, camcon_camSpeed) //Mouse moving right
endif
if (GetPointerY() < camcon_rotateStartY)
RotateCameraLocalX(1, camcon_camSpeed * -1) //Mouse moving up, rotate camera up
elseif (GetPointerY() > camcon_rotateStartY)
RotateCameraLocalX(1, camcon_camSpeed) //Mouse moving down
endif
SetCameraRotation(1, GetCameraAngleX(1), GetCameraAngleY(1), 0) //Zero the Z axis rotation (keep camera level with horizon)
endif
endfunction
function loadRoom()
myfloor = CreateObjectPlane(48, 48)
SetObjectColor(myFloor, 0, 51, 0, 255)
RotateObjectLocalX(myFloor, 90)
Create3DPhysicsStaticBody(myFloor)
SetObject3DPhysicsFriction(myFloor, 0.5)
SetObject3DPhysicsRollingFriction(myFloor, 0.25)
myWallN = CreateObjectPlane(48, 48)
SetObjectColor(myWallN, 8, 57, 127, 255)
SetObjectPosition(myWallN, 0, abs(GetObjectMeshSizeMinY(myWallN, 1)), abs(GetObjectMeshSizeMinY(myfloor, 1)))
Create3DPhysicsStaticBody(myWallN)
myWallS = CreateObjectPlane(48, 48)
SetObjectColor(myWallS, 50, 220, 255, 255)
SetObjectPosition(myWallS, 0, abs(GetObjectMeshSizeMinY(myWallS, 1)), abs(GetObjectMeshSizeMinY(myfloor, 1)) * -1)
Create3DPhysicsStaticBody(myWallS)
myWallW = CreateObjectPlane(48, 48)
RotateObjectLocalY(myWallW, 90)
SetObjectColor(myWallW, 74, 204, 10, 255)
SetObjectPosition(myWallW, abs(GetObjectMeshSizeMinX(myfloor, 1)) * -1, abs(GetObjectMeshSizeMinY(myWallW, 1)), 0)
Create3DPhysicsStaticBody(myWallW)
myWallE = CreateObjectPlane(48, 48)
RotateObjectLocalY(myWallE, 90)
SetObjectColor(myWallE, 229, 255, 50, 255)
SetObjectPosition(myWallE, abs(GetObjectMeshSizeMinX(myfloor, 1)), abs(GetObjectMeshSizeMinY(myWallE, 1)), 0)
Create3DPhysicsStaticBody(myWallE)
ball1 = CreateObjectSphere(2, 16, 16)
SetObjectColor(ball1, 178, 62, 62, 255)
SetObjectPosition(ball1, -4, 4, -2)
Create3DPhysicsDynamicBody(ball1)
SetObject3DPhysicsRollingFriction(ball1, 0.25)
ball2 = CreateObjectSphere(2, 16, 16)
SetObjectColor(ball2, 178, 178, 62, 255)
SetObjectPosition(ball2, 4, 4, -2)
Create3DPhysicsDynamicBody(ball2)
SetObject3DPhysicsRollingFriction(ball2, 0.25)
endfunction
function reggie(getMillerX as float, getMillerY as float, getMillerZ as float) //3 Point Play specialist #31 Reggie Miller
millerID as miller
millerID.x = getMillerX
millerID.y = getMillerY
millerID.z = getMillerZ
endfunction millerID