7 Years Bad Luck?

Blitz3D Forums/Blitz3D Beginners Area/7 Years Bad Luck?

_PJ_(Posted 2011) [#1]
I was toying with the idea of a reflective "mirror" based on a quad with a 2ndary camera render as its texture.

I managed to get it working too, but then I tried modifying it and somehow, now it doesn't seem to work at all :/

Unfortunately, I've overwtritten any backups of the working version too, and I can't see what's causing the problem.

It's clear thpough, that something is preventing the 2ndary camera ("Reflection") from rendering a visible scene.

The code is in two parts, the first is just initialising and a main loop, the second is a dependancy keeping the "mirror-specific" functions and constants separate.

If anyone can offer any suggestions as to what might be the problem, I'd be really grateful, thank you!






Ross C(Posted 2011) [#2]
Whoa, that's alot of code just for creating a mirror :) I don't see a buffer set to the backbuffer or frontbuffer. So, unless your using fastextension, then I can't see how you can copy anything to a mirror?

Your copying from an imagebuffer to a texturebuffer, but that's about it...


_PJ_(Posted 2011) [#3]
I'm using the CopyRect function, is that one from FastExtension? I lose track of which are native and not these days. That command takes parameters for source and destination buffers.

The only important functions are those in the second code block, and they are dealing with creating the mirror, calculating the angles and position for the reflection according to the viewer, and then the actual capturing the render.

Also, there's a couple of extra useful funcs thrown in, such as AddQuad() etc.

------------------------

If the copying from image buffer into a texture buffer IS (part of?) the problem, is there a recommended way to do this efficiently? All I can think of to be as "safe" as possible is a Read/WritePixelFast which might be too slow for realtime?


Ross C(Posted 2011) [#4]
I would copyrect from the buffer, rather than grab image. Copy straight from the buffer, directly to a texture. And always copy from the backbuffer(). I'll knock together a sample for ya.


Midimaster(Posted 2011) [#5]
did you read this:

http://www.blitzbasic.com/Community/posts.php?topic=87371#990125

perhaps it may help....


Ross C(Posted 2011) [#6]
Hi Malice. Here is my mirror code. I've coded it using types, so you can have as many mirrors as you want. You can set size and position, and texture size too. The only thing you need to watch out for though, is because each mirror has a camera attached, it has it's own cameraclscolor. So any areas of blank will be rendered using that particular camerasclscolor. So just watch if you change the main camera's clscolor. You will need to change all the mirrors.

Z and X keys to move the cube. Arrow keys to move and turn the camera. Enjoy!

OH! And i've coded it so mirrors can't reflect other mirrors. If you want to disable that, delete the hide_all_mirrors() and show_all_mirrors() function calls. Rendering other mirrors in a mirror doesn't work very well... Oh AND don't set the texture resolution of the mirror to a dimension larger than the set graphics resolution. Doesn't work right!

Const graphics_width = 800
Const graphics_height = 600

Graphics3D graphics_width,graphics_height
SetBuffer BackBuffer()


Global light = CreateLight()

Global camera = CreateCamera()
PositionEntity camera,0,0,-10

CameraClsColor camera,100,100,100

Global cube = CreateCube()
PositionEntity cube,0,0,5

ScaleEntity cube,0.2,0.2,0.2


Type mirror

	Field entity
	Field mesh
	Field surface
	Field texture
	Field texture_width
	Field texture_height
	
	Field camera
	
	Field v0,v1,v2,v3
	Field x,y,z
	
End Type

Global mirror1 = create_mirror(0,1,10,4,4,256,256,0,0,0)
Global mirror2 = create_mirror(4,1,10,4,4,256,256,0,-50,0)
Global mirror3 = create_mirror(-4,1,10,4,4,256,256,0,50,0)

While Not KeyHit(1)


	If KeyDown(200) Then MoveEntity camera,0,0,0.1
	If KeyDown(208) Then MoveEntity camera,0,0,-0.1
	If KeyDown(203) Then TurnEntity camera,0,1,0
	If KeyDown(205) Then TurnEntity camera,0,-1,0

	If KeyDown(44) Then MoveEntity cube,-0.4,0,0
	If KeyDown(45) Then MoveEntity cube,0.4,0,0

	update_mirrors()

	UpdateWorld
	RenderWorld
	Flip
Wend
End

Function update_mirrors()


	hide_all_mirrors()

	For m.mirror = Each mirror

		ShowEntity m\mesh
		ShowEntity m\camera
		HideEntity camera
		trx = DeltaPitch#(m\mesh,camera)*-1
		try = DeltaYaw#(m\mesh,camera)*-1
		

		RotateEntity m\camera, EntityPitch(m\mesh,True) + trx, EntityYaw(m\mesh,True) + try + 0 , 0,True

		RenderWorld
		CopyRect 0,0,m\texture_width,m\texture_height,0,0,BackBuffer(),TextureBuffer(m\texture)

		HideEntity m\camera
		HideEntity m\mesh
		
	Next

	show_all_mirrors()
	
	ShowEntity camera

		
End Function

Function hide_all_mirrors()

	For m.mirror = Each mirror
	
		HideEntity m\mesh
		
	Next
	
End Function

Function show_all_mirrors()

	For m.mirror = Each mirror
	
		ShowEntity m\mesh
		
	Next
	
End Function


; x - the centre x position of the mirror
; y - the centre y position of the mirror
; z - the centre z position of the mirror
;
; width - the width of the mirror
; height - the height of the mirror
;
; tex_x_res - the resolution width of the texture for the mirror
; tex_y_res - the resolution height of the texture for the mirror
;
; rot_x - the pitch of the new mirror
; rot_y - the yaw of the new mirror
; rot_z - the roll of the new mirror
;
; This function will return the actual entity, so you can modify it as you see fit.
; Remember the mirror mesh has a camera attached, which I don't think hides with the mesh.

Function create_mirror(x#,y#,z#,width#,height#,tex_x_res,tex_y_res,rotx#=0,roty#=0,rotz#=0)

	m.mirror = New mirror
	
	m\mesh = CreateMesh()
	m\surface = CreateSurface(m\mesh)

	m\v0 = AddVertex( m\surface,  - (width*0.5) ,  + (height*0.5) , 0 ,1,0)
	m\v1 = AddVertex( m\surface,  + (width*0.5) ,  + (height*0.5) , 0 ,0,0)
	m\v2 = AddVertex( m\surface,  - (width*0.5) ,  - (height*0.5) , 0 ,1,1)
	m\v3 = AddVertex( m\surface,  + (width*0.5) ,  - (height*0.5) , 0 ,0,1)
	
	AddTriangle (m\surface,m\v0,m\v1,m\v2)
	AddTriangle (m\surface,m\v2,m\v1,m\v3)
	
	UpdateNormals m\mesh
	
	PositionEntity m\mesh,x,y,z

	m\texture = CreateTexture(tex_x_res,tex_y_res)
	m\texture_width = tex_x_res
	m\texture_height = tex_y_res
	
	SetBuffer TextureBuffer(m\texture)
	Color 255,255,255
	Oval 0,0,200,200
	
	SetBuffer BackBuffer()
	
	EntityTexture m\mesh,m\texture
	
	RotateEntity m\mesh,rotx,roty,rotz
	
	m\camera = CreateCamera()
	EntityParent m\camera,m\mesh
	PositionEntity m\camera,x,y,z,True
	HideEntity m\camera
	CameraRange m\camera,0.1,100
	CameraViewport m\camera,0,0, m\texture_width, m\texture_height
	CameraClsColor m\camera,0,0,0
	
	Return m\mesh
	
End Function


I was tinkering with the idea of a disable mirror commmand, so the mirror can be truely disabled, rather than hidden. Shouldn't be too hard to do though!

Last edited 2011

Last edited 2011


_PJ_(Posted 2011) [#7]
I would copyrect from the buffer, rather than grab image

Of course! I'd been so used to working with locking buffers that I completely ignored the possiblity of just working directly with Buffers via SetBuffer.


As foir your code,
That's excellent, Ross... thank you so much! It's really made a lot of my ideas above obsolete, I still want to play around with it some. I'll post back when I have finished :)

It's much more versatile and capable than I really thought possible too!