SetViewPort Problem

BlitzMax Forums/BlitzMax Programming/SetViewPort Problem

maverick69(Posted 2006) [#1]
Hi!

Today I've tested my upcoming game with various systems, and on some old Geforce 2-GraphicCards the SetViewPort-Command from BlitzMax will be totaly ignored.

I've found some info on this board, that some gfx-card doesn't support the BlitzMax SetViewPort command.

Can you think of a workaround so I can clip images (in realtime) so that it works on all graphic cards? The BlitzMax DrawImageRect command doesn't work here, because it changes the uv-coords / scales the image.


AlexO(Posted 2006) [#2]
not sure how you're using the viewport command. if its just to clip images that are off screen then just use black images drawing on the borders? if its some sort of inset (like an animated hud or something) the only thing I can think of at the moment is doing a grab pixels:
- draw your hud off screen somewhere on the backbuffer.
- then do a grabImage of the size you want.
- then just draw that image where you want to on the screen.


Grey Alien(Posted 2006) [#3]
hmm, this is what I was testing in this thread:

http://www.blitzbasic.com/Community/posts.php?topic=62781

but noone found a PC where it didn't work. Any chance you can test my exe in that thread on the Geforce PCs and list the exact model numbers of the cards?

One of my problems was fixed with a Ian Duff's code (drawing part of rect) but for the other problem I could only use viewport because it involved drawing text onto an image but having the text clipped to a viewport. The only way I could see around this was to predraw the text on the image, and then use Ian Duff's code to draw part of the image only...

Meanwhile, are these two bits of code any good to you:

' -----------------------------------------------------------------------------
' cctg_drawimagerect by TonyG (slow?)
' -----------------------------------------------------------------------------
Function cctg_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

' -----------------------------------------------------------------------------
' ccDrawImageArea by Ian Duff (faster?)
' -----------------------------------------------------------------------------
' Note that this code works fine in DirectX or OpenGL on PCs - it autodetects (JB).
Function ccDrawImageArea(image:TImage, x#, y#, rx#, ry#, rw#, rh#, frame=0)
  Local origin_x#, origin_y# ; GetOrigin (origin_x, origin_y)
  Local tw = Pow2Size(image.width)
  Local th = Pow2Size(image.height)
  Local rw1#  = rx + rw
  Local rh1#  = ry + rh
  Local x0# = -image.handle_x, x1# = x0 + rw
  Local y0# = -image.handle_y, y1# = y0 + rh
  
  If rw1 > image.width
    x1 = x0 + rw + image.width - rw1
    rw1 = image.width
  EndIf
   
  If rh1 > image.height
    y1 = y0 + rh + image.height - rh1
    rh1 = image.height
  EndIf
?Win32
  If TD3D7ImageFrame(image.frame(frame))
    Local frame:TD3D7ImageFrame = TD3D7ImageFrame(image.frame(frame))
    
    frame.setUV(rx / tw, ry / th, rw1 / tw, rh1 / th)
    frame.Draw x0, y0, x1, y1, x + origin_x, y + origin_y
    frame.setUV(0, 0, image.width / Float(tw), image.height / Float(th))
  Else
?
    Local frame:TGLImageFrame = TGLImageFrame (image.frame(frame))
                
    frame.u0 = rx / tw
    frame.v0 = ry / th
    frame.u1 = rw1 / tw
    frame.v1 = rh1 / th
    
    frame.Draw x0, y0, x1, y1, x + origin_x, y + origin_y
    
    frame.u0 = 0
    frame.v0 = 0
    frame.u1 = image.width / Float(tw)
    frame.v1 = image.height / Float(th)
?Win32
  EndIf
?
  
  Function Pow2Size(n)
    Local ry = 1
    
    While ry < n
      ry :* 2
    Wend
    
    Return ry
  End Function
End Function



maverick69(Posted 2006) [#4]
The GraphicCard is: nVidia GeForce2MX400

Isn't it a little bit slow to grab the image each frame?


Grey Alien(Posted 2006) [#5]
I don't even understand what those two bits of code are doing, I just use them. So they are grabbing an image each frame and putting out a smaller rectangle yes? Well if that's all that can be done...


tonyg(Posted 2006) [#6]
The pixmap.window is slow and was supposed to be for a one-off. The SetUV code should be fast enough though.


Grey Alien(Posted 2006) [#7]
thanks for clearing that up, that's what I thought which is why my comments say Slow? and Faster?


maverick69(Posted 2006) [#8]
The code doesn't compile: "Duplicate identifier 'frame'" ??


tonyg(Posted 2006) [#9]
Blimey, then put on Superstrict and make sure each variable is defined.
For your ease...

Let me know when your tea needs stirring.


maverick69(Posted 2006) [#10]
Thanks, seems to work fine.


maverick69(Posted 2006) [#11]
Because I have A LOT OF SetViewport / DrawImage Commands in my game source I tought of a possibilty To overwrite those two Blitzfunctions, but I have some problems with the math how To calculate the news coords.

The source should look something like this


I know that other commands (like DrawRect etc...) won't use the viewport, but that doesn't matter for my case...


Tom Darby(Posted 2006) [#12]
I can attest to the viewport problem--one of my testing boxes has it. It only seems to happen with DirectX. I'm using a GeForce3 something or other; the real kicker is that before I reinstalled Win2K on this machine, I wasn't having a problem, so it's almost certainly a driver or DirectX issue.


Grey Alien(Posted 2006) [#13]
maverick69: oops sorry, yeah it just needs Strict before it and nothing else.

Tom Darby. Hmm that's a bummer that it's just a driver issue...or actually maybe that's good cos it means it can be fixed...


tonyg(Posted 2006) [#14]
@Maverick, Make your viewport and object and add 'myviewport.x' and 'myviewport.y' to your image x/y?


maverick69(Posted 2006) [#15]
I have written a little test app, and it seems to work fine. Only one small mistake. If the Viewport starts at (100,100) and I draw the image at (120,120) the lase pixel row and colum (above and left from the image) will be repeated.

Here's the code. You can hold down "Q" to swap between BlitzMax SetViewport and the overwritten SetViewport-Command




tonyg(Posted 2006) [#16]
Hmmm, not sure I see a problem.
P.S. You might want to use codebox rather than code for long code posts.


ImaginaryHuman(Posted 2006) [#17]
You could look at using the stencil buffer.


maverick69(Posted 2006) [#18]
Do you know where I can find some docu or examples using the stencil buffer and BlitzMax?


maverick69(Posted 2006) [#19]
Just for other users with the same problem. If you use the following code you can use SetViewPort/DrawImage as you are used to use them, but it will work on all graphic cards:




Grey Alien(Posted 2006) [#20]
thanks. ANy idea if the code works with drawtext and rectangles/lines etc?


maverick69(Posted 2006) [#21]
No, it doesn't. It also doesn't work if you use SetRotation() before the drawing command or if the ImageHandle isn't (0,0).

But the problem with the image handle could be corrected easily, with something like this I think (warning, not tested)

rw:+image.handle_x
rh:+image.handle_y



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