SetViewPort

BlitzMax Forums/BlitzMax Programming/SetViewPort

Tricky(Posted 2006) [#1]
Function BattleMessage(Msg$)
Local MS1 = MilliSecs()
Local MS2
Repeat
battleDrawScreen
DrawImage BXTop,0,20-ImageHeight(BXTop)
SetViewport 0,20,800,80
SetOrigin 0,20
TileImage BxBody,0,0
SetScale 2,2
SetColor BXR,BXG,BXB
DrawText MSG,400-(TextWidth(MSG)),40-(TextHeight(MSG))
SetScale 1,1
SetColor 255,255,255
SetOrigin 0,0
SetViewport 0,0,800,600
DrawImage BXBottom,0,100
Flip
MS2=MilliSecs()
Until MS2<MS1 Or MS2-MS1>5000
End Function


This is part of some code I set up for universal use in multiple projects.

In the Mac version this code works precisely as I meant to.
In the Windows version it doesn't.

I hoped that this would work on as well small pictures (which would be tiled), as big pictures which would be cut so that only the part within the viewport was shown.

As I said. The Mac version does it that way, the Windows version acts like I didn't use the SetViewPort command at all. Since the Mac version works, I don't think anything is wrong with my code. There's something in the Windows version that does it. Is it Windows, or BlitzMax that's the problem?

I'm really sorry, I cannot put more of the source code in it. I cannot reveal too much in the project's current state, plus that I have too much initiation routines. So I hope this code is what you need. If not, I'll try to set up a small program that can be built completely.

Anyway, the problem occurs in both "windowed" as "Full-Screen" mode.

I couldn't test this in Linux, since I do not have a fully operational Linux system.


GfK(Posted 2006) [#2]
Maybe you need to write a self-contained program that demonstrates the problem. I've read your post half a dozen times and I'm still not completely sure what the problem is... I'm guessing that you're saying that SetViewport is ignored with either large or small images, but I dunno...


Tricky(Posted 2006) [#3]
The SetViewport seems indeed to be ignored.

Let's say a large picture was to be displayed but only a portion of it. I used SetViewport to make sure only a part of the picture was shown, but still the entire picture is shown in stead of only a portion.

Is that clearer?


===

Below is a screenshot of the actual bug

You see that the meaning was to display only a textbox containing the "Healing Mushroom" text. The green photo had only to be inside the box. That was what the viewport was set on at least. In stead of that, the entire picture was shown.

(Please tell me when you're done with this bug, so I can remove the picture from my server. It's taking up too much space there)


GfK(Posted 2006) [#4]
Just threw this together which seems to work fine?
SetGraphicsDriver GLMax2DDriver()
Graphics 800,600
image:timage = LoadImage("screenbug.png")
SetViewport 0,20,800,80
While Not KeyDown(key_escape)
	Cls
	DrawImage image,0,0
	Flip
Wend



Dreamora(Posted 2006) [#5]
Which would mean that it is (surprise surprise ;) ) a DX problem ...

With all the current DX bugs, writting a DX9 one from scratch should take less time ...


Grisu(Posted 2006) [#6]
Gfk's code works fine. Dx AND GL (win32)!

Tric, I think some of your troubles may be related to a buggy bmx installation?


Tricky(Posted 2006) [#7]
@GFK
I don't have time to try it today, but I'll test that out tomorrow.

@Grisu
A buggy installation you say. I don't know.
This was first tested in V1.14 in which the problem was already there. V1.18 still had that problem, and once again, only in Windows and not on Mac.

I've temporary covered the problem, by making a GrabImage of the original picture (from 0,100) which is the end of the viewport, and using drawimage after the box was rendered. Far from ideal, of course, but it works.


Yan(Posted 2006) [#8]
Try disabling multi-monitor support?...

??


Grey Alien(Posted 2006) [#9]
Try drawing a rectangular area of the source image instead of using viewport as apparently it's not reliable on all systems (so I've heard ...)

Here's is TonyG's code:

Function tg_drawimagerect(image:TImage,x:Int,y:Int,xs:Int,ys:Int,width:Int,height:Int)
    DrawImage LoadImage(PixmapWindow(LockImage(image),xs,ys,width,height)),x,y
End Function



ImaginaryHuman(Posted 2006) [#10]
I've heard that the viewport only tells the system what characteristics a given viewing area has, not whether things will be cropped to only draw inside of it. Under OpenGL I read that you have to use the scissor window or clip planes to stop things being drawn outside the viewport on all systems, ie the viewport doesn't limit the drawing area.


TartanTangerine (was Indiepath)(Posted 2006) [#11]
The blitzmax SetViewport command uses Clip Planes under Direct X and Scissors under OpenGL. If you card does not support Clip planes then you will have this issue with all DirectX software and not just BlitzMax. FYI clip planes do clip the drawing area, a True viewport, which this is not, does not.


Grey Alien(Posted 2006) [#12]
very interesting. So do *most* cards support clip planes or is it better to be safe and use a drawimage rect variant instead? I appreciate that sometimes you *do* need a proper viewport, but I'm just using it to draw rectangular areas of images at the moment.


TartanTangerine (was Indiepath)(Posted 2006) [#13]
I'd suggest you stick with clip planes or use one of the other methods of drawing part of an image that utilise UV co-ordinates. TonyG's code, whilst simple in it's implementation, is just too slow for real-time usage.


Tricky(Posted 2006) [#14]
About GFK's code.
When I tried to run it, but in OpenGL it won't run at all on the Windows machine I'm currently using. And since OpenGL is not exactly a standard in Windows (as I heard MicroSoft announced), I cannot take for granted the users of my project will have it installed. (I don't know where to get a Windows Version of OpenGL either, and since I expect my windows-users to be DX users, I've not too much interest for that either)

Tony's code is a good code to keep in mind.
It's too slow for real-time usage, that I could see without using it, but the idea is not that bad.

I've now solved the problem by altering the code this way:
Function BattleMessage(Msg$)
Local MS1 = MilliSecs()
Local MS2
?Win32
'Make picture of original screen to cover a bug in Windows
Local Ori:TImage = CreateImage(800,500)
GrabImage Ori,0,100
?
Repeat
battleDrawScreen
DrawImage BXTop,0,20-ImageHeight(BXTop)
SetViewport 0,20,800,80
SetOrigin 0,20
TileImage BxBody,0,0
SetScale 2,2
SetColor BXR,BXG,BXB
DrawText MSG,400-(TextWidth(MSG)),40-(TextHeight(MSG))
SetScale 1,1
SetColor 255,255,255
SetOrigin 0,0
SetViewport 0,0,800,600
?Win32
'Project the picture To hide the bug in Windows
SetColor 0,0,0
DrawRect 0,100,800,500
SetColor 255,255,255
DrawImage Ori,0,100
?
DrawImage BXBottom,0,100
Flip
MS2=MilliSecs()
Until MS2<MS1 Or MS2-MS1>5000
End Function


I know you'll bash this solution.
And I would not have used this solution, if this project wasn't part of a multi-project. But it works and the user won't see the difrence.


TartanTangerine (was Indiepath)(Posted 2006) [#15]
*bash*


Grey Alien(Posted 2006) [#16]
lol. Well Indiepath I'd use the other methods you mentioned if I knew what the hell you were on about ;-) not being a DX/OGL god, I "know nuthing"...


Yan(Posted 2006) [#17]
@GA - I've already given you a UV solution...You nutta! ;op


Grey Alien(Posted 2006) [#18]
Yan: I'm confused. What via that multi-monitor link which is an old viewport thread?


Yan(Posted 2006) [#19]
Here... :o)


Grey Alien(Posted 2006) [#20]
groovy, thanks big nose. Also I've learnt that you can include functions within functions from your code which is handy. I can do this in Delphi but never tried in Max, just assumed you couldn't :-o.


BlackSp1der(Posted 2006) [#21]
But, cutting the image with UV don't work with rotated images. So, the only way to get a working viewport with 'images rotated' is the command SetViewport. :S


Grey Alien(Posted 2006) [#22]
hmm, well lucily I don't need it for rotated images ... yet.


TartanTangerine (was Indiepath)(Posted 2006) [#23]
Why do you need to rotate the image at the pixel level? Why don't you just use the normal rotation commands?


Grey Alien(Posted 2006) [#24]
I don't even know what UV stands for? something Vertex?


TartanTangerine (was Indiepath)(Posted 2006) [#25]
U & V are the vertex texture co-ordinates.


Grey Alien(Posted 2006) [#26]
ok, thanks.


Yan(Posted 2006) [#27]
UVW = Texture Space
XYZ = World Space

Make more sense now?


Grey Alien(Posted 2006) [#28]
100% thanks. I already used XYZ years ago with 3D on Spec/BBC/C64 and Amiga before the invention of textures.


BlackSp1der(Posted 2006) [#29]

@Indiepath:
Why do you need to rotate the image at the pixel level? Why don't you just use the normal rotation commands?



I use the normal SetRotation command. Because that I have problems with a virtual viewport created with UV. Maybe if I use render2texture. then put the image rotated in a texture and cut the image with UV.