SetBuffer BackBuffer()

Blitz3D Forums/Blitz3D Beginners Area/SetBuffer BackBuffer()

ColeE(Posted 2016) [#1]
In every 3D program I've written in Blitz3D, I've begun:

Graphics3D 640, 480
SetBuffer Backbuffer()


Well, with different screen sizes at times... and sometimes assorted calculations beforehand...

But anyways, I just read that SetBuffer BackBuffer() is supposed to go before Graphic3D, is this correct? Why is it wrong to put it after it?

Sorry I've been posting so many questions lately...


RemiD(Posted 2016) [#2]
It is not because many people repeat the same thing that this is true :P

From what i understand, setbuffer(backbuffer()) should be put before renderworld() (or before drawimage or text if you only want to render 2d) (once in the mainloop is enough) so that you draw on the backbuffer and then flip() puts what is on the backbuffer on the frontbuffer (and display it on the screen).

2 recent discussions about that :
http://www.blitzbasic.com/Community/posts.php?topic=105925
http://www.blitzbasic.com/Community/posts.php?topic=105524


Kryzon(Posted 2016) [#3]
According to the documentation RenderWorld draws the active camera viewports always onto the back-buffer. It makes no difference what other buffer was manually set.

It does make a difference for the 2D drawing command though, so people write SetBuffer at the beginning so you can use RenderWorld and then use 2D commands that will composite over on the back-buffer, overlaying the 3D render.


ColeE(Posted 2016) [#4]
Are you saying that I should SetBuffer Backbuffer() every frame? Or am I misunderstanding?


Guy Fawkes(Posted 2016) [#5]
no... He's saying:



~GF


Kryzon(Posted 2016) [#6]
Are you saying that I should SetBuffer Backbuffer() every frame?

It's a persistent state, which means that if you set it once at the beginning of your program every subsequent 2D drawing command will happen on the back-buffer.

EDIT: To answer your original question, SetBuffer is supposed to be used any time after you entered the graphics mode with a call to Graphics or Graphics3D.


Omnicode(Posted 2016) [#7]
Sets the current drawing buffer.

;Here's some variations of setting the current buffer for elements to be drawn on.
SetBuffer Backbuffer()
SetBuffer Frontbuffer()
SetBuffer Imagebuffer(image)
SetBuffer TextureBuffer(texture)



Floyd(Posted 2016) [#8]
Just to drive another nail in the coffin, these two programs
Graphics3D 640, 480
SetBuffer Backbuffer()
and
Graphics3D 640, 480
do exactly the same thing.The back buffer is already set by default after Graphics3D. All 2D drawing goes to the back buffer.

I have often begun programs in the first style, using SetBuffer(). This is just to make the graphics buffer obvious to everyone. There have been three different "flavors" of Blitz ( original, Plus and 3D ) and many versions of each. The default graphics buffer has changed over the years. Even now, within Blitz3D, it is different for Graphics and Graphics3D.

Here is a trivial example. It writes the numbers 0,1,2... to the back buffer then flips to the front. If you change Graphics3D to Graphics you will see nothing. Text will now write to the front buffer. Flip then puts this to the back buffer where it is invisible.

If SetBuffer BackBuffer() is used then there is no change in behavior.
Graphics3D 500, 500, 0, 2
;SetBuffer BackBuffer()

While Not KeyDown(1)
	Delay 300
	Cls
	Text 250,250, n
	n = n + 1
	Flip
Wend



RemiD(Posted 2016) [#9]
Ok, now try to display an image on the screen without setbuffer(backbuffer()) before renderworld if you have used others buffers (imagebuffer or texturebuffer) in the mainloop or before the mainloop but after your setbuffer(backbuffer())...

Also it seems to work as expected if you use setbuffer(backbuffer()) after graphics3d() and you create your camera just after, but try to use setbuffer(imagebuffer()) or setbuffer(texturebuffer()) before creating the camera and see what happens. (apparently the camera viewport is resized to the width height of the last used buffer...)

So it may work well ( to only put setbuffer(backbuffer()) after graphics3d() ) for some simple codes, but once you play with different buffers it is better to put setbuffer(backbuffer()) before renderworld imo (or before drawimage if you only want to draw images)


RemiD(Posted 2016) [#10]
An example of what i mean :


To make it work correctly :
either put setbuffer(backbuffer()) before creating the camera + put setbuffer(backbuffer()) before renderworld() (or before drawimage() if you only want to draw images)
or put CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight()) after having created the camera + put setbuffer(backbuffer()) before renderworld() (or before drawimage() if you only want to draw images)


Floyd(Posted 2016) [#11]
What is the problem, that the image and text are not drawn to the screen?

You did SetBuffer ImageBuffer(etc.) but never put it back with SetBuffer BackBuffer().
That means DrawImage and Text not drawn to the screen. Text and the image itself are being drawn to the image.

The image creation would normally go like this
TestImage = CreateImage(100,100)

SetBuffer ImageBuffer(TestImage) 

ClsColor(128,128,128)
Cls()
Color(255,255,255)
Oval(0,0,100,100,True)

SetBuffer BackBuffer() ; done drawing to image



RemiD(Posted 2016) [#12]
My code example demonstrates the problem :
if you create a camera just after having used a buffer different than the backbuffer (an imagebuffer or a texturebuffer), the cameraviewport adopts its width height (i consider this is a bug...)

What you explain about puting setbuffer(backbuffer()) after having finished to draw on an imagebuffer or texturebuffer is one way to do it, but putting it before renderworld (or before drawimage if you only want to draw images) is the same thing, except you don't have to write it 100 times (one each time after having finished to draw on an imagebuffer or texturebuffer)


Floyd(Posted 2016) [#13]
Aha! So CreateCamera() sets the viewport to match whatever graphics buffer is currently active.

I routinely set up things like Graphics3D, CreateCamera etc., which are common to all 3D programs, at the beginning. Things like CreateImage, which are specific to a particular program, come later. So I never noticed how CreateCamera set the viewport.

Using my typical program structure I would write things this way.
Graphics3D(500,500,32,2)
camera = CreateCamera()   ; viewport matches the current graphics buffer

TestImage = CreateImage(100,100)
SetBuffer(ImageBuffer(TestImage))
	ClsColor(128,128,128)
	Cls()
	Color(255,255,255)
	Oval(0,0,100,100,True)
SetBuffer(BackBuffer())

For i% = 1 To 1000 Step 1
 Cube = CreateCube()
 ScaleMesh(Cube,1.0/2,1.0/2,1.0/2)
 EntityColor(Cube,Rand(025,255),Rand(025,255),Rand(025,255))
 PositionEntity(Cube,Rand(-10,10)+0.5,Rand(-10,10)+0.5,Rand(-10,10)+0.5,True)
Next

PositionEntity(Camera,0,0,-20,True)

OLight = CreateLight(2)
LightRange(OLight,3.0)
LightColor(OLight,224,224,224)
PositionEntity(OLight,0,0,0,True)

AmbientLight(032,032,032)

While Not KeyDown(1)

	Delay(100)
  RenderWorld()    

  DrawImage(TestImage,GraphicsWidth()/2-ImageWidth(TestImage)/2,0)

	Text(0,0,n)
	n = n + 1
	
	Flip(1)
	
Wend



RemiD(Posted 2016) [#14]

So CreateCamera() sets the viewport to match whatever graphics buffer is currently active.


Yes that's the bug that i have seen.

Imagine how impossible it was to find this bug (when the code seemed to be correct) and when the last set buffer before creating the camera was an imagebuffer of a 2x2pixels image (used as a reticle). In this case it was impossible to see the small size of the camera viewport (2x2pixels !) I gave up the debugging and started a new code from scratch !


Your code structure will not produce the bug indeed. But this code structure will :
Graphics3d(640,480,32,2)

include "premades.bb" ;(premade meshes, textures, skeletons, animations, images, fonts, sounds)

Global Camera = createcamera()
CameraRange(Camera,0.1,100)
CameraClsColor(Camera,000,000,000)

PositionEntity(Camera,0,1.65,-3,true)

Main()

End()

function Main()
 Repeat

  setbuffer(backbuffer())
  renderworld()

  flip(1)

 Until( keydown(1)=1 )
end function




Guy Fawkes(Posted 2016) [#15]
And yet, you forgot the "premades.bb" -.-

UNbelievable!


RemiD(Posted 2016) [#16]
@GF>>What is believable however, is your unintelligent comment... The code that i have posted in my previous post was just to demonstrate the structure of the code (and why the bug may cause a problem in this case)...