Rotating a postcard

BlitzMax Modules Forums/MiniB3D/Rotating a postcard

I need some advice here.

I have a 2D user interface (1024x768 fullscreen graphics window). Part of that interface is an area (let's say 400x300px) representing a postcard. If you click on the edge of the postcard it'll turn around to show the back side. This animation must have a 3D look.

I first tried to solve this in pure BlitzMax code (using some 3D math) to visualize a 3D box in a 2D area. But then I found out that BlitzMax can't do any quad transformations with bitmaps.
So I thought I must use MiniB3D to make a cube (size 10, 10, 0.1) with textures. But then I have two questions:
1) how do you make a cube with different textures on each side? (examples are welcome ;)
2) how can I make a 3D viewport within a 2D interface?

Or... is there a much better solution for this?

1) use texture coordinates (vertex UVW), edit them manually in code or use a 3D modeller/editor that can output b3d format.
2) in minib3d there is a GUI canvas example. Or clear the screen , render the 3D scene and then after draw 2D over/around it if you don't use maxgui.

Here is a pure BMax code for a card that looks like it is flipping:
'This creates a horizontally "flipping" card
SetScale(1,Sin(rotation))
'height is the height of the postcard
DrawImage(postcard,x,(y+height/2)-(Sin(rotation)*height/2))

You will need to write a small addition to the code to make the back show instead of the front over and over.

CASO> Your suggestion does not have vanishing points.

LAB[au]> if I don't want to use MaxGUI, how can I combine
Graphics 1024, 768, 32
with a 3D Graphics viewport?
You say (in pseudo code:
Repeat
  Cls
  RotateBox()
  RenderWorld

  Draw2DinterfaceAround3Dviewport()  'how?
  Flip
Unit endOfGame


Your pseudo code is right. (if you have issues with max2d look on this forum for workaround, or use Klepto extended version which has functions enabling mixing minib3d with max2d).

Don't forget to set the viewport of your rendering camera at the desired x,y location.

It's really pretty basic ... or I don't understand your question.

I did not know about an extended version for miniB3D. So thanks for the tip.

I tried to find the answer there but I still don't get it. You say it's pretty basic but I'm completely stuck. I can't also find any BlitzMax example that shows what I need. Which surprices me because I think it's quite commen to combine a 2D interface with a 3D viewport. E.g. a space travel game where you can select/buy a space ship. The interface (with the buy button, the price and other stats) is in 2D and the preview of the selected ship is a 3D viewport with a rotating model of the ship in it.

I tried to combine the Graphics() comand with the Graphics3D() command but obviously that doesn't work. And the CanvasGraphics3D () command requires a gadget object so that seems to be used in combination with a maxGUI window and that is not what I want.

Could you give a very short example presenting a max2D graphics window (so no maxGUI) containing a miniB3D viewport at location 100, 100 with size 400x300?
How should the main repeat loop look like?

FOr combining max2d, Look at his post http://www.blitzbasic.com/Community/posts.php?topic=69542

you will need to recompile minib3d mod (you know how to do that?)
...and here is an example:
Import sidesign.minib3d

Graphics3D 640,480,32,2

Local mycube:TEntity=Createcube()
PositionEntity mycube,0,0,5

Local cam:TCamera=CreateCamera()
CameraViewport cam,100,100,400,300
CameraClsColor cam,0,0,255

Local light=CreateLight()

While Not KeyHit(KEY_ESCAPE)
'everything 3D goes here
	TurnEntity mycube,1,1,0
	RenderWorld()

	TGlobal.BeginMax2D
'put 2D in between BeginMax2D and EndMax2D
	SetColor 255,255,0
	DrawRect 0,0,100,100
	TGlobal.EndMax2D
	Flip

Wend

End


Well, do you believe that...?
It works!
I could never figure out that I must modify a TGlobal file to make this work. Anyway, problem is solved. Now I can concentrate on the project again. Thanks a lot!

It works... almost :-(
In full screen mode (Graphics3D 640, 480, 32, 1) it does not draw the yellow rect. I added a line:
DrawText "Just 2D text", 300, 450
and that text is visible!?
I changes resolutions, flip values, etc. but every turn the same result.

Yes you have to use a modification to the way graphics are initialised in minib3d, so you have to modify the sourcecode of minib3d(in this file sidesign.mod\minib3d.mod\inc\TGlobal.bmx you'll find the graphicsinit function which you have to modify, and you have to add the BeginMax2D and EndMax2D functions) then rebuild the module as sated in the linked post above.

I just add this to be sure you recompiled the module.

I have it working in both windowed and fullscreen mode here. What is your graphic card brand and model? (and OS?)

Cut and paste this code then run it in MaxIde to compile the minib3D mod. (Assuming you have MinGW installed follow the instruction here for installing MinGW http://www.blitzbasic.com/Community/posts.php?topic=53442 ).

SuperStrict

Framework BRL.StandardIO
Import BRL.FileSystem

Global Stream : TStream

Const MODCFG : String = "cfg/modservers.cfg"
Const SYNC   : String = "bin/syncmods.exe"
Const BMK    : String = "bin/bmk.exe"
Const DOC    : String = "bin/docmods.exe"

Try
Print("Compiling...")
system_(BMK + " makemods -a sidesign.minib3d")
Print("~nOK")

Print("Docing...")
'system_(DOC)
Print("~nOK")

Catch Exception:Object
   Print("~nError: ")
   Print(" " + Exception.ToString())

End Try

Print("~n~n- ready -")


I had MinGW installed, indeed.
I tried your code but I saw it was like compiling from a command prompt, which I already did. I also modified TGlobal to include the BeginMax2D and EndMax2D commands. I have sidesign.minib3d (Version: 1.42 from Simon) and also the extended version from Klepto installed (I tried just the sidesign version, the Klepto version and both versions compiled).
With the klepto version I can see the text but no rectangles.
With the sidesign version I can't see the text nor the rectangle. So that's no improvement.

I have a Dell XPS M1710 laptop with NVIDIA GeForce Go 7950 GTX graphics card.
OS: Microsoft Windows XP Professional
Version 5.1.2600 Service Pack 2 Build 2600

PS: I also tried the full screen test with maximum resolution but that has no effect. No rects, just text.

The new 0.42 extended will have a more compatible Max2D behaviour. I hope to release it soon. I have yet to create some additional interface function and some bugs left to fix. So keep patient.

As a possible fix you could try something like this:
TGlobal.BeginMax2D()
 SetBlend AlphaBlend 'Seems to fix sometimes the behaviour
 DrawRect 0,0,-5,-5 'Also seems to fix some things
 'YYour 2D Stuff


Or replace the Functions in TGLobal.bmx with these:
Function GraphicsInit()
	
		TTexture.TextureFilter("",9)
	
		glewInit() ' required for glActiveTextureARB

		'Save the Max2D settings for later
		glPushAttrib GL_ALL_ATTRIB_BITS
		glPushClientAttrib GL_CLIENT_ALL_ATTRIB_BITS
		glMatrixMode GL_MODELVIEW
		glPushMatrix
		glMatrixMode GL_PROJECTION
		glPushMatrix
		glMatrixMode GL_TEXTURE
		glPushMatrix
		glMatrixMode GL_COLOR
		glPushMatrix 
		
		EnableStates()
		
		glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
		glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)

		glClearDepth(1.0)						
		glDepthFunc(GL_LEQUAL)
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

		glAlphaFunc(GL_GEQUAL,0.1)

	End Function
	
	'enter Max2D mode
	Function BeginMax2D()
		
		glPopClientAttrib
		glPopAttrib
		glMatrixMode GL_MODELVIEW
		glPopMatrix
		glMatrixMode GL_PROJECTION
		glPopMatrix
		glMatrixMode GL_TEXTURE
		glPopMatrix
		glMatrixMode GL_COLOR
		glPopMatrix 
		
		'DrawRect 0,0,-5,-5
		
	End Function
	
	'return to MiniB3D mode
	Function EndMax2D()
		
		'Save the Max2D settings for later
		glPushAttrib GL_ALL_ATTRIB_BITS
		glPushClientAttrib GL_CLIENT_ALL_ATTRIB_BITS
		glMatrixMode GL_MODELVIEW
		glPushMatrix
		glMatrixMode GL_PROJECTION
		glPushMatrix
		glMatrixMode GL_TEXTURE
		glPushMatrix
		glMatrixMode GL_COLOR
		glPushMatrix 
		
		EnableStates()
		glDisable GL_TEXTURE_2D
		
		glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
		glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)

		glClearDepth(1.0)						
		glDepthFunc(GL_LEQUAL)
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

		glAlphaFunc(GL_GEQUAL , 0.5)
		
		If isWireframe = True Then
				glPolygonMode(GL_FRONT , GL_LINE)
		EndIf
		
    End Function


And rebuild the module afterwards.

Quickly tried both suggestions, no improvement.
Going to bed now. Tomorrow another day. I hope we find out what the problem is.

After a good night's rest I continued experimenting to figure out what is going on. Based on the example LAB[au] sent, take a look at this:
Import klepto.minib3d

Graphics3D 640,480,32,1

Local mycube:TEntity=CreateCube()
PositionEntity mycube,0,0,5

Local cam:TCamera=CreateCamera()
CameraViewport cam,100,100,400,300
CameraClsColor cam,0,0,255

Local light=CreateLight()

While Not KeyHit(KEY_ESCAPE)
'everything 3D goes here
	TurnEntity mycube,1,1,0
	RenderWorld()

	TGlobal.BeginMax2D
'put 2D in between BeginMax2D and EndMax2D
	SetColor 255,255,0

'	this works
	DrawText "Just 2D text...", 100, 450
	DrawRect 0,0,100,100

'	this doesn't
'	DrawRect 0,0,100,100
'	DrawText "Just 2D text...", 100, 450

	TGlobal.EndMax2D
	Flip

Wend

End

So, when I first draw text and after that draw the rects, it works. But first rects and than text removes the rects. Hmmm?

But it is getting more complicated. I added a DrawImage line after the DrawText
	SetColor(255, 255, 255)
	DrawImage(img, 10, 10)

Now it does draw all the elements, no matter what order I choose.
Klepto, do we have a bug here? Is this something to think about? Will it help you to improve the module? Or is there something wrong with my system and/or BlitzMax+mods installation?

Anyway, I can continue working on my project but I hope this post will not end here.