OpenGL: Render2Texture

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

Fetze

Betreff: OpenGL: Render2Texture

BeitragSo, Sep 23, 2007 10:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich fasse mich entgegen meiner Gewohnheit mal kurz und bündig:
1. Unter reiner Verwendung von OpenGL-Befehlen, wie funktioniert Render2Texture?
2. Wie aktiviere ich eine Textur zum Rendering auf ihr?
3. Wie "schließe ich die Textur wieder ab", wenn ich fertig bin?
4. Müssen Render2Texture-Texturen speziell initialisiert werden?
 

klepto2

BeitragSo, Sep 23, 2007 10:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Echtes Render2 Texture gibt es in OpenGL nicht, jedenfalls nicht für LowEnd Grafikkarten.
Es gibt insgesammt 3 Möglichkeiten dafür:
1. glCopyTexImage, im Prinzip wird der Backbuffer/oder ein anderer Buffer in die Textur kopiert.
Im Prinzip das was BMax bei GrabImage macht

2. Pixelbuffer oder pBuffer, sehr schwierig umzusetzen wird allerdings meistens für r2t verwendet

3. FBO oder Framebufferobjects, erheblich einfacher umzusetzen dafür aber auch nur auf mid und highend karten verbreitet.

Für FBO kann ich dir mein 'noch' nicht voll Funktionsfähiges Texturebuffer Type für miniB3D zeigen.
Wichtig ist das die Buffer zusammen mit der Textur selbst generiert werden und kein Mipmapping verwendet wird.

Code: [AUSKLAPPEN]

Type TTextureBuffer
   Field Texture:TTexture
   Field rb:Int[1]
   Field fb:Int[1]
   Field cubeface:Int = 0
   Field W:Int
   Field H:Int

   Function InitBuffer:TTextureBuffer(Texture:TTexture,frame:Int = 0)
      Local TB:TTextureBuffer = New TTextureBuffer
      TB.Texture = Texture
      TB.W = PixmapWidth(Texture.Pixmap)
      TB.H = PixmapHeight(Texture.PixMap)
      TB.GenBuffer(frame)
      Return TB
   End Function
   
   Method SetBufferCubeFace(cubeface:Int = 0)
      Self.cubeface = cubeface
   End Method
   
   Method GenBuffer(frame:Int = 0)
      Print W + " : " + H + "-->" + fb[0] + " : " + rb[0]
      
      AdjustTexsize(W , H)
      
         
   
      glGenFramebuffersEXT(1, fb )
      glGenRenderbuffersEXT(1 , rb)
      
      glGenTextures(1, texture.gltex)
      glBindTexture(GL_TEXTURE_2D, texture.gltex[0]);
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ;
      
      
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, Null);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
         
      glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,Texture.glTex[frame], 0);
      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]);
      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H);
      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0])
      
       Local status:Int =  glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
      
       Select status
          Case GL_FRAMEBUFFER_COMPLETE_EXT
             Print "all right" + " : " + Status
          Case GL_FRAMEBUFFER_UNSUPPORTED_EXT
             Print "choose different formats"
          Default
             End
      EndSelect
      
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0)
      'If Fullscreen = True Then
      'glViewport(0 , 0 , W , H) ;
      'EndIf

   End Method
   
   Method SetBuffer()
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0])
      'glViewport(0,0,800,600)
   End Method
   
   Method UnSetBuffer()
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0)
      'glViewport(0,0,TGlobal.Width,TGlobal.Height)
   End Method
End Type

Function AdjustTexSize( width:Int Var,height:Int Var )
   'calc texture size
   width=Pow2Size( width )
   height=Pow2Size( height )
   Repeat
      Local t:Int
      glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
      glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t
      If t Return
      If width=1 And height=1 RuntimeError "Unable to calculate tex size"
      If width>1 width:/2
      If height>1 height:/2
   Forever
End Function

Function Pow2Size:Int( n:Int )
   Local t:Int=1
   While t<n
      t:*2
   Wend
   Return t
End Function



Ich hoffe das hilft dir etwas weiter.
Matrix Screensaver
Console Modul für BlitzMax
KLPacker Modul für BlitzMax

HomePage : http://www.brsoftware.de.vu
 

Dreamora

BeitragMo, Sep 24, 2007 9:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Schau im englischen Forum nach Indiepaths Render2Texture Modul.
Der GL Teil davon sollte noch voll funktionsfähig sein, nur der DX Teil ist futsch, was daran liegt, dass DX Max2D sich innerhalb von 1.24 stark verändert hat.
Dieses Modul arbeitet mit pBuffern, da sie auch auf lowerend Karten existieren.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

klepto2

BeitragMo, Sep 24, 2007 9:36
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora, gibt es da eine neure Version ? Die die ich habe benutzt definitiv keine pBuffer sondern ein simples
glCopyTexImage .

Code: [AUSKLAPPEN]

Function TextureRender_End()
   ?Win32
      If dx
         PrimaryDevice.Device.EndScene()
      Else
   ?
         glBindTexture GL_TEXTURE_2D,GLFrame.name
         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, Width, Height, 0)
         glBindTexture GL_TEXTURE_2D,0
   ?Win32
      EndIf
   ?
      ViewportSet(0,0,GraphicsWidth(),GraphicsHeight())
      DrawImageRect Image,-2000,-2000,1,1
   '   Print "tRender : TextureRender_End OK"
      Return True
   End Function
Matrix Screensaver
Console Modul für BlitzMax
KLPacker Modul für BlitzMax

HomePage : http://www.brsoftware.de.vu
 

Dreamora

BeitragMo, Sep 24, 2007 10:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Uba?
Dann war das wohl mal ein Usergebastel, dass es via pBuffer machte. Aber ich weiss das es damals mit den sogenannten Lowend Karten Probleme gab, gibt es aber auch mit dem glCopy ...
Mit Lowend mein ich die Karten die in 50% der Systeme vorhanden sind ... Intel (< GMA 950), SiS und S3 Onboard
Die vertragen sich weder mit der DX noch der GL Seite. Letzteres wird da eh net wirklich unterstützt, da muss der MS OpenGL 1.1 Emulator ran selbst bei der GMA900
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Fetze

BeitragMo, Sep 24, 2007 15:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich also die Indiepath-Variante verwende, hab ich zwar Render2Texture, allerdings zu langsam für Echtzeitverwendung? Das ist allerdings nicht, was ich wirklich will.. echtzeit-tauglich sollte es schon sein!
Ganz allgemein, welche der Varianten wäre denn überhaupt echtzeitfähig? Welche werden denn für Kamera-Screens in modernen 3D-Spielen verwendet?

@klepto2
Inwiefern noch nicht voll funktionstüchtig? Ließe sich Mipmapping implementieren oder ist das aus technischen Gründen ausgeschlossen?

LordArtus

BeitragMo, Sep 24, 2007 15:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,
interresanntes Thema.
Mich würde auch 'sehr' interresieren wie das gemacht ist:
http://spaceinvadersgl.sourceforge.net/

Hab mal gestern erstmal mit GrabImage sowas probiert , die Anwendung ist 50mal langsamer geworden.
Dann mit GrabPixmap , immerhin schneller als GrabImage , aber noch immer viel viel zu langsam (25mal langsamer geworden).Also von Echzeittauglichkeit kann man da überhaupt nicht reden.

MfG

LordArtus
 

klepto2

BeitragMo, Sep 24, 2007 21:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem mit GrabImage ist folgendes, es arbeitet auch mit Pixmaps (genauer mit GrabPixmap). Dadurch muss natürlich einmal die Pixmap in die Textur geladen werden (durch mipmapping sehr oft) und vorher muss noch ein YFlip durchgeführt werden was wiederum sehr an der Performance zieht.

Hier ist mal ein kleines sample mit einem GrabImageFast welches echtzeittauglich ist:

Code: [AUSKLAPPEN]

SuperStrict

SetGraphicsDriver GLMax2DDriver()

Graphics 800 , 600 , 0 , - 1

Local T:Int = MilliSecs()
Local Image:Timage = CreateImage(256 , 256)
Type TPoint
   Field X:Float , Y:Float
   Field R:Int = 0
End Type

Local PLisT:TList = New TList

For Local i:Int = 0 To 200
   Local P:TPoint = New TPoint
   P.X = Rand(800)
   P.Y = Rand(600)
   If Rand(0,10) = 5 Then P.R = 1'SetColor 255,0,0

   PList.Addlast(P)
Next

While Not KeyHit(KEY_ESCAPE)
   Cls
      For Local P:TPoint = EachIn PList
         If P.R = 1 Then SetColor 255,0,0
         DrawOval P.X - 5 , P.Y - 5 , 10 , 10
         SetColor 255 , 255 , 255
      Next
      
      Local MX:Float = MouseX()
      Local MY:Float = MouseY()
      
      If MouseHit(1) Then
         GrabImageFast(Image , MX , MY)
      EndIf
      
      DrawRect 0 , 0 , 266 , 266
      'SetScale 1,-1
      DrawImage Image , 5 , 5
      'SetScale 1 , 1
      
      SetBlend AlphaBlend
      SetAlpha 0.5
      
      DrawRect MX , MY , 256 , 256   
      
      SetAlpha 1.0
         
   Flip
Wend
   
Function GrabImageFast(Image:TImage,X:Int,Y:Int)
   Local Frame:TGlImageFrame = TGLImageframe(Image.frames[0])
   Frame.u0 = 0
   Frame.v0 = 1
   Frame.u1 = 1
   Frame.v1 = 0

   glBindtexture GL_TEXTURE_2D,Frame.name
   glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,x,GraphicsHeight()-y-Image.Height,Image.Width,Image.Height,0)
   glBindTexture GL_TEXTURE_2D , Null
   
   DrawText " ",-10,-10
End Function   


Allerdings sind bei den Fast Images keine Pixeloperationen möglich.

@LordArtus:
Dieser SpaceInvader CLone besteht ganz einfach aus texturierten Quads die auf einer Ebene liegen. Ein Blick in den Source verrät das dort kein R2t angewandt wird.

@Fetze:
Natürlich ist Mipmapping möglich, nur da bereits bei einem 256*256 Image 8 Stufen erstellt werden müssen und natürlich auch wieder hochgeladen werden bringt eben das den entscheidenden Performanceverlust.

Fetze

BeitragMo, Sep 24, 2007 22:20
Antworten mit Zitat
Benutzer-Profile anzeigen
@klepto2
Wie genau kann ich mit OpenGL, nur die Textur-ID kennend, denn die MipMaps generieren? Es gibt da einen glu-Befehl für, allerdigns resultierte seine Anwendung in Kombination mit glGetTex bei meinen Versuchen in einer komplett weißen Textur..

..auch wenn ich diese "GrabImageFast"-Technik mittlerweile selbst anwenden konnte, danke für das Beispiel - hat mich zumindest in der Y-Achsen-ransformation bestätigt, ich war nicht sicher, ob sich das wirklich auf die Fenster / RC-Koordinaten bezieht Smile

Edit: Okay, das mit den Mipmaps hat sich erledigt - konnte das widerspenstige glu-Kommando doch noch dazu bewegen, seinen Dienst zu tun.. ^^
(Aus irgendeinem Grund lief es beim Datenformattyp UNSIGNED_INT_8_8_8_8 nicht, läuft aber bei UNSIGNED_INT? ôo)

LordArtus

BeitragDi, Sep 25, 2007 8:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh man , hab gar nicht gesehen , dass da ein source dabei war.Wie peinlich Embarassed
Stimmt , wird kein R2T verwendet.(si_World.cpp)

MfG

LordArtus

LordArtus

BeitragDi, Sep 25, 2007 17:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi ,
nochmal ich.
klepto2 dein GrabImageFast() ist unglaublich , woooooooooooow.

Code: [AUSKLAPPEN]

'--------------------------'
'-------- DEFENDER --------.'
'---------- 2007 ----------.'
'--------------------------.'
'-- Remake -by LordArtus --.'
'--------------------------.'
'...........................'

'Ver.Alpha 0.5
'-------------

SuperStrict
SeedRnd MilliSecs()
SetGraphicsDriver GLMax2DDriver()

Global GX:Int=400
Global GY:Int=300
      
Graphics GX,GY,0,2

Local yesno:String="No"
Local yesnoflag:Byte=False
Local mx:Int=MouseX()
Local my:Int=MouseY()
Local whileflag:Int=123456

While whileflag=123456

   Cls
   
   mx=MouseX()
   my=MouseY()
   
   CollideRect(GX/2-36,100,72,10,0,1)
   If CollideRect(mx-5,my-4,10,8,1,0)
      SetColor 255,200,0
      DrawText "1280x1024",GX/2-36,100
      If MouseHit(1)
         GX=1280
         GY=1024
         Exit
      EndIf
   Else
      SetColor 255,255,255
      DrawText "1280x1024",GX/2-36,100
   EndIf
   ResetCollisions()

   CollideRect(GX/2-32,120,64,10,0,1)
   If CollideRect(mx-5,my-4,10,8,1,0)
      SetColor 255,200,0
      DrawText "1024x768",GX/2-32,120
      If MouseHit(1)
         GX=1024
         GY=768
         Exit
      EndIf
   Else
      SetColor 255,255,255
      DrawText "1024x768",GX/2-32,120
   EndIf
   ResetCollisions()
   
   CollideRect(GX/2-28,140,56,10,0,1)
   If CollideRect(mx-5,my-4,10,8,1,0)
      SetColor 255,200,0
      DrawText "800x600",GX/2-28,140
      If MouseHit(1)
         GX=800
         GY=600
         Exit
      EndIf
   Else
      SetColor 255,255,255
      DrawText "800x600",GX/2-28,140
   EndIf
   ResetCollisions()
   
   CollideRect(GX/2-60,160,120,10,0,1)
   If CollideRect(mx-5,my-4,10,8,1,0)
      SetColor 255,200,0
      DrawText "Fullscreen: "+yesno,GX/2-60,160
      If MouseHit(1)
         yesnoflag=Not yesnoflag
         If yesnoflag
            yesno="Yes"
         Else
            yesno="No"
         EndIf
      EndIf
   Else
      SetColor 255,255,255
      DrawText "Fullscreen: "+yesno,GX/2-60,160
   EndIf
   ResetCollisions()
   
   If KeyHit(KEY_ESCAPE) End
   
   Flip 1
      
Wend

'ToDo genaue Überprüfung des Spiels bei Auflösungswechsel und wie es auf FPS-Unterschiede reagiert
'-------------------------
If yesno="Yes"
   Graphics GX,GY,32
Else
   Graphics GX,GY,0,2
EndIf

Const MAPSIZEX:Float=5120.0
Global MAPSIZEY:Int=GY-GY/5
Global MAPYNULL:Int=GY/5
Const STARS_LIMIT1:Int=500
Const STARS_LIMIT2:Int=1000
Const STARS_LIMIT3:Int=1500
Const STARS_TILES:Int=6 ' WICHTIG !!! (Minimum 2) 10 bedeutet Background wird auf 10*10 geteilt(100 Tiles)

' Types und Funktionen
'----------------------
Type Player
   Field x:Float
   Field y:Float
   Field speedx:Double
   Field speedy:Float
   Field max_speedx:Float
   Field le_ri_flag:Byte
   Field up_do_flag:Byte
   Field shoot_flag:Byte
   Field stop_flag:Byte
   Field ShootList:TList
   Field wait:Int
   
   Method MoveLeft(upd_speed:Double)
      Self.Accelerate(upd_speed)
      x=x-speedx
      If x<0.0
         x=x+MAPSIZEX
      EndIf
      stop_flag=False
   EndMethod
   
   Method MoveRight(upd_speed:Double)
      Self.Accelerate(upd_speed)
      x=x+speedx
      If x>MAPSIZEX
         x=x-MAPSIZEX
      EndIf
      stop_flag=False
   EndMethod
   
   Method Stop(upd_speed:Double)
      If KeyDown(KEY_RIGHT) Or KeyDown(KEY_LEFT)
         speedx=speedx-(0.15*(upd_speed^2))
      Else
         speedx=speedx-(0.05*(upd_speed^2))
      EndIf
      If speedx<0.0
         speedx=0.0
      EndIf
      If le_ri_flag
         x=x+speedx
         If x>MAPSIZEX
            x=x-MAPSIZEX
         EndIf
      Else
         x=x-speedx
         If x<0.0
            x=x+MAPSIZEX
         EndIf
      EndIf
   EndMethod

   Method Accelerate(upd_speed:Double)
      If speedx<(max_speedx*upd_speed)
         speedx=speedx+(0.1*(upd_speed^2))
      Else
         speedx=(max_speedx*upd_speed)
      EndIf
   EndMethod

   Method MoveUp(upd_speed:Float)
      If y>MAPYNULL+7
         y=y-(speedy*upd_speed)
      EndIf
   EndMethod
   
   Method MoveDown(upd_speed:Float)
      If y<GY-GY/10
         y=y+(speedy*upd_speed)
      EndIf
   EndMethod
      
   Method Shoot()
      If wait+150<MilliSecs()
         ShootList.AddLast(PlayerShoot.Create(x,y,shoot_flag))
         wait=MilliSecs()
      EndIf
   EndMethod
   
   Method Bomb()
   EndMethod
   
   Method Draw(posx:Float)
      SetColor 255,255,255
      If x<GX And posx>MAPSIZEX-GX
         If CollideRect(x+MAPSIZEX-posx,y,PLAYERWIDTH,PLAYERHEIGHT,2,0)
            SetColor 255,0,255
         EndIf
         If shoot_flag
            DrawRect x+MAPSIZEX-posx,y,PLAYERWIDTH,PLAYERHEIGHT
            DrawLine x+MAPSIZEX-posx,y,x+MAPSIZEX-posx,y-5
            DrawLine x+MAPSIZEX-posx,y-5,x+MAPSIZEX-posx+PLAYERWIDTH/2,y
            SetColor 0,0,0
            DrawRect (x+MAPSIZEX-posx)+1,y+1,PLAYERWIDTH/2,PLAYERHEIGHT-2
         Else
            DrawRect x+MAPSIZEX-posx,y,PLAYERWIDTH,PLAYERHEIGHT
            DrawLine x+MAPSIZEX-posx+PLAYERWIDTH-1,y,x+MAPSIZEX-posx+PLAYERWIDTH-1,y-5
            DrawLine x+MAPSIZEX-posx+PLAYERWIDTH-1,y-5,x+MAPSIZEX-posx+PLAYERWIDTH/2,y
            SetColor 0,0,0
            DrawRect (x+MAPSIZEX-posx)+PLAYERWIDTH/2-1,y+1,PLAYERWIDTH/2,PLAYERHEIGHT-2
         EndIf
         CollideRect(x+MAPSIZEX-posx,y,PLAYERWIDTH,PLAYERHEIGHT,0,1)
         SetColor 0,255,255
         DrawRect (x+MAPSIZEX-posx)/10+(GX/2-GX/20)-1,GY/12+y/10-1,3,3 ' Anzeige des Raumschiffs im HUD
      Else
         If CollideRect(x-posx,y,PLAYERWIDTH,PLAYERHEIGHT,2,0)
            SetColor 255,0,255
         EndIf
         If shoot_flag
            DrawRect x-posx,y,PLAYERWIDTH,PLAYERHEIGHT
            DrawLine x-posx,y,x-posx,y-5
            DrawLine x-posx,y-5,x-posx+PLAYERWIDTH/2,y
            SetColor 0,0,0
            DrawRect (x-posx)+1,y+1,PLAYERWIDTH/2,PLAYERHEIGHT-2
         Else
            DrawRect x-posx,y,PLAYERWIDTH,PLAYERHEIGHT
            DrawLine x-posx+PLAYERWIDTH-1,y,x-posx+PLAYERWIDTH-1,y-5
            DrawLine x-posx+PLAYERWIDTH-1,y-5,x-posx+PLAYERWIDTH/2,y
            SetColor 0,0,0
            DrawRect (x-posx)+PLAYERWIDTH/2-1,y+1,PLAYERWIDTH/2,PLAYERHEIGHT-2
         EndIf
         CollideRect(x-posx,y,PLAYERWIDTH,PLAYERHEIGHT,0,1)
         SetColor 0,255,255
         DrawRect (x-posx)/10+(GX/2-GX/20)-1,GY/12+y/10-1,3,3 ' Anzeige des Raumschiffs im HUD
      EndIf
   EndMethod
   
   Function Create:Player(startx:Float)
      Local cp:Player=New Player
      cp.ShootList=New TList
      cp.x=startx
      cp.y=GY/2
      cp.speedx=0.0
      cp.speedy=6.0
      cp.max_speedx=15.0
      cp.shoot_flag=True
      cp.stop_flag=True
      cp.le_ri_flag=cp.shoot_flag
      cp.up_do_flag=0             ' ToDo am Überlegen wegen Vertikal-Beschleunigung
      cp.wait=0
      Return cp
   EndFunction
EndType

Type PlayerShoot
   Field x:Float
   Field y:Float
   Field speed:Float
   Field shoot_flag:Byte
   
   Method Move:Byte(posx:Float,upd_speed:Float)
      speed=20.0*upd_speed
      If x<0.0
         x=x+MAPSIZEX
      EndIf
      If x>MAPSIZEX
         x=x-MAPSIZEX
      EndIf
      If x<GX And posx>MAPSIZEX-GX
         If shoot_flag
            If x+PLAYERWIDTH+MAPSIZEX<posx+GX
               x=x+speed
               Return True
            Else
               Return False
            EndIf
         Else
            If x+MAPSIZEX>posx
               x=x-speed
               Return True
            Else
               Return False
            EndIf
         EndIf
      Else
         If shoot_flag
            If x+PLAYERWIDTH<posx+GX
               x=x+speed
               Return True
            Else
               Return False
            EndIf
         Else
            If x-speed>posx
               x=x-speed
               Return True
            Else
               Return False
            EndIf
         EndIf
      EndIf
   EndMethod
   
   Method Draw(posx:Float)
      SetColor 255,255,0
      If x<GX And posx>MAPSIZEX-GX
         If shoot_flag
            DrawLine x+PLAYERWIDTH+MAPSIZEX-posx,y,x+PLAYERWIDTH+20+MAPSIZEX-posx,y
            CollideRect(x+PLAYERWIDTH+MAPSIZEX-posx,y-1,20,3,0,1)
         Else
            DrawLine x+MAPSIZEX-posx,y,(x-20)+MAPSIZEX-posx,y
            CollideRect(x+MAPSIZEX-posx,y-1,-20,3,0,1)
         EndIf
      Else
         If shoot_flag
            DrawLine x+PLAYERWIDTH-posx,y,x+PLAYERWIDTH+20-posx,y
            CollideRect(x+PLAYERWIDTH-posx,y-1,20,3,0,1)
         Else
            DrawLine x-posx,y,(x-20)-posx,y
            CollideRect(x-posx,y-1,-20,3,0,1)
         EndIf
      EndIf
   EndMethod
   
   Function Create:PlayerShoot(x:Int,y:Int,shoot_flag:Byte)
   Local ps:PlayerShoot=New PlayerShoot
   ps.x=x
   ps.y=y
   ps.speed=20.0
   ps.shoot_flag=shoot_flag
   Return ps
   EndFunction
EndType

Type Enemy
   Field x:Float
   Field y:Float
   Field speedx:Float
   Field speedy:Float
   Field changespeedwait:Int
   Field rtime:Int
   
   Method Move(upd_speed:Float)
      'Nur zu Testzwecken
      '------------------------------------
      If changespeedwait+rtime<MilliSecs()
         speedx=Rnd(-1.0,1.0)
         speedy=Rnd(-1.0,1.0)
         rtime=Rand(5000,15000)
         changespeedwait=MilliSecs()
      EndIf
      '------------------------------------
      
      x=x+(speedx*upd_speed)
      y=y+(speedy*upd_speed)
      If x>MAPSIZEX
         x=x-MAPSIZEX
      EndIf
      If x<0.0
         x=x+MAPSIZEX
      EndIf
      If y<MAPYNULL-speedy Or y>GY-ENEMYHEIGHT-speedy
         speedy=-speedy
      EndIf
   EndMethod
   
   Method Shoot:Byte()
      Return True
   EndMethod
   
   Method Draw:Byte(posx:Float)
      SetColor 0,255,0
      Local _coll:Byte=False
      Local xdraw:Float=x-posx
      If (xdraw<GX And xdraw+ENEMYWIDTH>0) Or (xdraw>-MAPSIZEX And xdraw<-(MAPSIZEX-GX))
         If x<GX And posx>MAPSIZEX-GX
            If CollideRect(xdraw+MAPSIZEX,y,ENEMYWIDTH,ENEMYHEIGHT,1,0)
               SetColor 255,0,0
               _coll=True
            EndIf
            DrawRect xdraw+MAPSIZEX,y,ENEMYWIDTH,ENEMYHEIGHT
            CollideRect(xdraw+MAPSIZEX,y,ENEMYWIDTH,ENEMYHEIGHT,0,2)
         Else
            If CollideRect(xdraw,y,ENEMYWIDTH,ENEMYHEIGHT,1,0)
               SetColor 255,0,0
               _coll=True
            EndIf
            DrawRect xdraw,y,ENEMYWIDTH,ENEMYHEIGHT
            CollideRect(xdraw,y,ENEMYWIDTH,ENEMYHEIGHT,0,2)
         EndIf
      EndIf
      DrawEnemyOnHUD(x,y,posx)
      Return _coll
   EndMethod
   
   Function Create:Enemy()
      Local ce:Enemy=New Enemy
      ce.speedx=Rnd(-1.0,1.0)
      ce.speedy=Rnd(-1.0,1.0)
      ce.x=Rand(0,MAPSIZEX)
      ce.y=Rand(MAPYNULL,MAPYNULL+MAPSIZEY-10)
      ce.changespeedwait=MilliSecs()
      ce.rtime=5000
      Return ce
   EndFunction
EndType

Function DrawEnemyOnHUD(x:Float,y:Float,posx:Float)
   Local xhud:Float=(x+MAPSIZEX/2-GX/2)/10
   Local camposxhud:Float=posx/10
   If xhud>MAPSIZEX/10
      xhud=xhud-MAPSIZEX/10
   EndIf
   If xhud-camposxhud<0
      xhud=xhud+MAPSIZEX/10
   EndIf
   SetColor 200,200,200
   Plot (xhud-camposxhud)+(GX/2-MAPSIZEX/20),GY/12+y/10 ' Anzeige im HUD
EndFunction

'-------------------------
'--------- ToDo ----------
'-------------------------


Type EnemyShoot
EndType

Type EnemyKI ' Vielleicht reicht da Function()
EndType

Type PlayerExplosion ' Vielleicht reicht da Function()
EndType

Type EnemyExplosion
EndType

'-------------------------
'-------------------------

Type H_U_D
   Field x:Int
   Field y:Int
   Field wait:Int
   Field mem:Int
   
   Method Draw(Score:Int,Lives:Int,Bombs:Int,posx:Int,px:Int,cs:Float,shootlist:TList,us:Float)
      SetColor 255,255,255
      DrawLine x,y+MAPYNULL,x+GX,y+MAPYNULL
      DrawLine GX/2-MAPSIZEX/20,y,GX/2-MAPSIZEX/20,MAPYNULL
      DrawLine GX/2+MAPSIZEX/20,y,GX/2+MAPSIZEX/20,MAPYNULL
      '---------------------------
      DrawLine GX/2-GX/20,GY/12+MAPYNULL/10,GX/2+GX/20,GY/12+MAPYNULL/10
      DrawLine GX/2+GX/20,GY/12+MAPYNULL/10,GX/2+GX/20,GY/12+MAPYNULL/10+MAPSIZEY/10
      DrawLine GX/2+GX/20,GY/12+MAPYNULL/10+MAPSIZEY/10,GX/2-GX/20,GY/12+MAPYNULL/10+MAPSIZEY/10
      DrawLine GX/2-GX/20,GY/12+MAPYNULL/10+MAPSIZEY/10,GX/2-GX/20,GY/12+MAPYNULL/10
      '----------------------------
      glEnable GL_TEXTURE_2D
      DrawText "Score: "+Score,130,120
      DrawText "Lives: "+Lives,130,132
      DrawText "Bombs: "+Bombs,130,144
      ' Zum Testzwecken
      '-----------------
      DrawText "camposx: "+posx,0,12
      DrawText "playerposx: "+px,0,24
      DrawText "camspeed: "+cs,0,36
      If shootlist=Null
         DrawText "shoots: "+0,0,48
      Else
         DrawText "shoots: "+CountList(shootlist),0,48
      EndIf
      DrawText "upd_speed: "+us,0,60
      glDisable GL_TEXTURE_2D
      DrawLine 0,90,GX/2-MAPSIZEX/20,90
      '-----------------
   EndMethod
   
   Function Create:H_U_D()
      Local hud:H_U_D=New H_U_D
      hud.x=0
      hud.y=0
      hud.wait=MilliSecs()
      hud.mem=GCMemAlloced()
      Return hud
   EndFunction
EndType

Type Background
   Field r1:Float
   Field r2:Float
   Field r3:Float
   Field img1:TImage[,]
   Field img2:TImage[,]
   Field img3:TImage[,]
   Field x1:Float[]
   Field y1:Float[]
   Field x2:Float[]
   Field y2:Float[]
   Field x3:Float[]
   Field y3:Float[]
   Field pos_last:Float
   
   Method Draw(flag:Byte,pos_now:Float)
      Local r:Float=Abs(pos_now-pos_last)
      If r>100
         r=MAPSIZEX-r
      EndIf
      If flag
         r1=-(r)/10
         r2=-(r)/20
         r3=-(r)/30
      Else
         r1=r/10
         r2=r/20
         r3=r/30
      EndIf
      pos_last=pos_now
      '----------------------------
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            x3[x]=x3[x]+r3
            If x3[x]>GX
               x3[x]=x3[x]-GX-(GX/STARS_TILES)
            EndIf
            If x3[x]<-(GX/STARS_TILES)
               x3[x]=x3[x]+GX+(GX/STARS_TILES)
            EndIf
            DrawImage img3[x,y],x3[x],y3[y]
         Next
      Next

      '----------------------------
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            x2[x]=x2[x]+r2
            If x2[x]>GX
               x2[x]=x2[x]-GX-(GX/STARS_TILES)
            EndIf
            If x2[x]<-(GX/STARS_TILES)
               x2[x]=x2[x]+GX+(GX/STARS_TILES)
            EndIf
            DrawImage img2[x,y],x2[x],y2[y]
         Next
      Next

      '----------------------------
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            x1[x]=x1[x]+r1
            If x1[x]>GX
               x1[x]=x1[x]-GX-(GX/STARS_TILES)
            EndIf
            If x1[x]<-(GX/STARS_TILES)
               x1[x]=x1[x]+GX+(GX/STARS_TILES)
            EndIf
            DrawImage img1[x,y],x1[x],y1[y]
         Next
      Next
   EndMethod
   
   Function Create:Background(startx:Float)
      Local bgr:Background=New Background
      Local x1:Int
      Local y1:Int
      Cls
      '-------------------------------
      bgr.x1=New Float[STARS_TILES+1]
      bgr.y1=New Float[STARS_TILES]
      bgr.img1=New TImage[STARS_TILES+1,STARS_TILES]
      SetColor 255,255,255
      For Local i:Int=0 To STARS_LIMIT1
         x1=Rand(0,GX)
         y1=Rand(MAPYNULL,GY-GY/10)
         Plot x1,y1
      Next
      Local pluslast:Int=0
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            Local cimg:TImage=CreateImage(GX/STARS_TILES,MAPSIZEY/STARS_TILES,1,DYNAMICIMAGE|MASKEDIMAGE)
            If x=STARS_TILES Then pluslast=-GX/2
            GrabImage cimg,x*(GX/STARS_TILES)+pluslast,MAPYNULL+y*(MAPSIZEY/STARS_TILES)
            bgr.img1[x,y]=cimg
            bgr.x1[x]=x*(GX/STARS_TILES)
            bgr.y1[y]=MAPYNULL+y*(MAPSIZEY/STARS_TILES)            
         Next
      Next
      Cls
      pluslast=0
      '-------------------------------
      bgr.x2=New Float[STARS_TILES+1]
      bgr.y2=New Float[STARS_TILES]
      bgr.img2=New TImage[STARS_TILES+1,STARS_TILES]
      SetColor 180,180,180
      For Local i:Int=0 To STARS_LIMIT2
         x1=Rand(0,GX)
         y1=Rand(MAPYNULL,GY-GY/10)
         Plot x1,y1
      Next
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            Local cimg:TImage=CreateImage(GX/STARS_TILES,MAPSIZEY/STARS_TILES,1,DYNAMICIMAGE|MASKEDIMAGE)
            If x=STARS_TILES Then pluslast=-GX/2
            GrabImage cimg,x*(GX/STARS_TILES)+pluslast,MAPYNULL+y*(MAPSIZEY/STARS_TILES)
            bgr.img2[x,y]=cimg
            bgr.x2[x]=x*(GX/STARS_TILES)
            bgr.y2[y]=MAPYNULL+y*(MAPSIZEY/STARS_TILES)
         Next
      Next
      Cls
      pluslast=0
      '---------------------------------
      bgr.x3=New Float[STARS_TILES+1]
      bgr.y3=New Float[STARS_TILES]
      bgr.img3=New TImage[STARS_TILES+1,STARS_TILES]
      SetColor 100,100,100
      For Local i:Int=0 To STARS_LIMIT3
         x1=Rand(0,GX)
         y1=Rand(MAPYNULL,GY-GY/10)
         Plot x1,y1
      Next
      For Local x:Int=0 To STARS_TILES
         For Local y:Int=0 To STARS_TILES-1
            Local cimg:TImage=CreateImage(GX/STARS_TILES,MAPSIZEY/STARS_TILES,1,DYNAMICIMAGE|MASKEDIMAGE)
            If x=STARS_TILES Then pluslast=-GX/2
            GrabImage cimg,x*(GX/STARS_TILES)+pluslast,MAPYNULL+y*(MAPSIZEY/STARS_TILES)
            bgr.img3[x,y]=cimg
            bgr.x3[x]=x*(GX/STARS_TILES)
            bgr.y3[y]=MAPYNULL+y*(MAPSIZEY/STARS_TILES)
         Next
      Next
      Cls
      '----------------------------------
      bgr.pos_last=startx
      Return bgr
   EndFunction
EndType

Type Camera
   Field posx:Float
   Field speed:Double
   Field flag:Byte
   Field max_speed:Float
   Field counter:Float
   
   Method MoveLeft(upd_speed:Double)
      Self.Accelerate(upd_speed)
      posx=posx-speed
      If posx<0.0
         posx=posx+MAPSIZEX
      EndIf
   EndMethod
   
   Method MoveRight(upd_speed:Double)
      Self.Accelerate(upd_speed)
      posx=posx+speed
      If posx>MAPSIZEX
         posx=posx-MAPSIZEX
      EndIf
   EndMethod
   
   Method Stop(upd_speed:Double,le_ri_flag:Byte)
      If KeyDown(KEY_RIGHT) Or KeyDown(KEY_LEFT)
         speed=speed-(0.15*(upd_speed^2))
      Else
         speed=speed-(0.05*(upd_speed^2))
      EndIf
      If speed<0.0
         speed=0.0
      EndIf
      If le_ri_flag
         posx=posx+speed
         If posx>MAPSIZEX
            posx=posx-MAPSIZEX
         EndIf
      Else
         posx=posx-speed
         If posx<0.0
            posx=posx+MAPSIZEX
         EndIf
      EndIf
   EndMethod
   
   Method Accelerate(upd_speed:Double)
      If speed<(max_speed*upd_speed)
         speed=speed+(0.1*(upd_speed^2))
      Else
         speed=(max_speed*upd_speed)
      EndIf
   EndMethod
   
   Method MoveToPos(upd_speed:Double,shoot_flag:Byte) ' ToDooooooooooooo (Buggggggggggggggggggggg)
      If flag And shoot_flag=False
         If counter<GX/4      
            posx=posx-(8*upd_speed)
            If posx<0.0
               posx=posx+MAPSIZEX
            EndIf
            counter=counter+(4*upd_speed)
         Else
            counter=0.0
            flag=False
         EndIf
      ElseIf flag=False And shoot_flag
         If counter<GX/4
            posx=posx+(8*upd_speed)
            If posx>MAPSIZEX
               posx=posx-MAPSIZEX
            EndIf
            counter=counter+(4*upd_speed)
         Else
            counter=0.0
            flag=True
         EndIf
      Else
         If counter>0.0
            flag=Not flag
            counter=GX/4-counter
         EndIf
      EndIf
   EndMethod
   
   Function Create:Camera(startx:Float)
   Local cam:Camera=New Camera
   cam.posx=startx   
    cam.speed=0.0
   cam.flag=True
   cam.max_speed=15.0
   cam.counter=0.0
   Return cam
   End Function
EndType

Type World
   Field _camera:Camera
   Field _player:Player
   Field _EnemyList:TList ' ToDo EnemyListe in Enemy-Type reinpacken
   Field _EnemyShootList:TList
   Field _background:Background
   Field _HUD:H_U_D
   Field PlayerScore:Int
   Field PlayerLives:Int
   Field PlayerBombs:Int
   Field upd_speed:Double
   
   Method UpdateWorld(upd_speed:Double) ' ToDo die Steuerung noch richtig anpassen
                        ' ToDo inteligente Kameraverfolgung (Grundgerüst vorhanden) einbauen
      ResetCollisions(1)
      
      _player.stop_flag=True
      
      If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT)
         _player.shoot_flag=False
         If _player.le_ri_flag=True And _player.speedx>0.0
         Else
            _player.le_ri_flag=False
            _player.MoveLeft(upd_speed)
            _camera.MoveLeft(upd_speed)
         EndIf
      EndIf
      
      If KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
         _player.shoot_flag=True
         If _player.le_ri_flag=False And _player.speedx>0.0
         Else
            _player.le_ri_flag=True
            _player.MoveRight(upd_speed)
            _camera.MoveRight(upd_speed)
         EndIf
      EndIf
            
      If _player.stop_flag            ' True = Anhalten
         If _camera.speed=0.0
         Else
            _camera.Stop(upd_speed,_player.le_ri_flag)
            _player.Stop(upd_speed)
         EndIf
      EndIf
      
      _camera.MoveToPos(upd_speed,_player.shoot_flag)
      
      If MouseDown(1) _player.Shoot()
      If MouseHit(2) _player.Bomb()   ' ToDo Noch am Überlegen wegen der _player.Bomb Lösung      
      If KeyDown(KEY_UP) _player.MoveUp(upd_speed)
      If KeyDown(KEY_DOWN) _player.MoveDown(upd_speed)
      If KeyHit(KEY_SPACE) _camera.MoveToPos(upd_speed,_player.x)
      
      _background.Draw(_player.le_ri_flag,_camera.posx)
      
      _player.Draw(_camera.posx)
      
      ResetCollisions(2)
      
      For Local ps:PlayerShoot=EachIn _player.ShootList
         If ps.Move(_camera.posx,upd_speed)
            ps.Draw(_camera.posx)
         Else
            ListRemove(_player.ShootList,ps) ' ToDo RemoveLink()
         EndIf
      Next
      
      For Local en:Enemy=EachIn _EnemyList
         en.Move(upd_speed) 
         If en.Draw(_camera.posx)
            ' Set Explosion
            ListRemove(_EnemyList,en)
         EndIf
      Next
      
      Rem
      For ens:EnemyShoot=EachIn _EnemyShootList
         If ens.Move()
            ens.Draw()
         EndIf
      Next
      EndRem
      
      _HUD.Draw(PlayerScore,PlayerLives,PlayerBombs,_camera.posx,_player.x,_camera.speed,_player.ShootList,upd_speed)
      
   EndMethod
      
   Function Create:World()
      Local cw:World=New World
      cw._camera=Camera.Create(1000.0)   ' Startposition der Kamera
      cw._player=Player.Create(1000.0+GX/4)  ' Startposition des Spielers
      cw._EnemyList:TList=New TList
      For Local i:Int=0 To 250               ' Anzahl Enemys
         cw._EnemyList.AddLast(Enemy.Create())
      Next
      cw._EnemyShootList:TList=New TList
      cw._background=Background.Create(1000.0)
      cw._HUD=H_U_D.Create()
      cw.PlayerScore=0
      cw.PlayerLives=5
      cw.PlayerBombs=3
      Return cw
   EndFunction
EndType

'Globale Variablen
'------------------------------------------

Global PLAYERWIDTH:Int=40
Global PLAYERHEIGHT:Int=10
Global ENEMYWIDTH:Int=10
Global ENEMYHEIGHT:Int=10
Local Game1:World=World.Create()

' HauptSchleife
'------------------------------
Local a:Int=MilliSecs()
Local fps:Short=0
Local upd_speed:Double=1.0
Local z:Short=0
Local Image:Timage = CreateImage(GX , GY)

While Not KeyHit(KEY_ESCAPE)
   
   If a+999<MilliSecs()
      a=MilliSecs()
      fps=z
      upd_speed=85.0/fps
      z=0
   EndIf
   
   If KeyHit(KEY_P)
      Repeat
         DrawText "PAUSE",GX/2,GY/2
         Flip 1
      Until KeyHit(KEY_P)
      a=MilliSecs()
      z=0
   EndIf

   Cls
   
   SetScale 1.0,1.0
   SetRotation 0
      
   Game1.UpdateWorld(upd_speed)

   DrawText "FPS: "+fps,0,0
   
   GrabImageFast(Image ,0,0)
   
   Cls
   
   SetScale 0.7,0.7
   SetRotation 10
   
   DrawImage Image,150,50
         
   Flip 0
   
   z=z+1

Wend

Function GrabImageFast(Image:TImage,X:Int,Y:Int)
   Local Frame:TGlImageFrame = TGLImageframe(Image.frames[0])
   Frame.u0 = 0
   Frame.v0 = 1
   Frame.u1 = 1
   Frame.v1 = 0

   glBindtexture GL_TEXTURE_2D,Frame.name
   glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,x,GraphicsHeight()-y-Image.Height,Image.Width,Image.Height,0)
   glBindTexture GL_TEXTURE_2D , Null

   DrawText " ",-10,-10
   
End Function
 
End


Danke nochmal für deinen Code klepto2.

MfG

LordArtus

maximilian

BeitragDi, Sep 25, 2007 17:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine Frage: Ich verstehe knapp 10% von dem was ihr hier redet. Trotzdem habe ich das Gefühl mit dem Wissen ein unglaublich schnelles DrawPixmap/schnelleren Pixelzugriff hinzubekommen in dem ich in Echtzeit auf ne Textur male. Lieg ich da richtig, oder ist das wider nur mein Wunschdenken?
Variety is the spice of life. One day ignore people, next day annoy them.

Fetze

BeitragDi, Sep 25, 2007 19:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist im Prinzip nichts anderes als ein nett-schnelles GrabImage, zumindest soweit ich Render2Texture in der derzeit besprochenen Variante verstanden hab ^^
 

Matthias

BeitragFr, Okt 05, 2007 15:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Hay.
@klepto2



Dein FastGrabImage ist echt der Hammer. Es ist genau das was ich immer gesucht habe. Very Happy Laughing Very Happy

FastGrabImage=75FPS GrabImage=14FPS bei 1.875GHz und 1024x768x32



Ich war schon richtig sauer über BMax weil ich immer ein riesiges Land machen wolte. Leider war es bis jetzt nur Echtzeittauglich wenn mann es als ein Images im GFX-Speicher speicherte. Doch dann war die grenze schon bei 4096x4096px erreicht weil 67MB GFX Speicher. +Objekte,Efekte
schnell mal 128MB weg. (Mehr hab ich nicht)

Aber durch deine geile FastGrabImage function kann mann nun alles was sich auf dem Bildschirm befindet zb um 10px nach links verschieben und braucht nur noch am rechten rand die 10px mit Plot ansetzen. Und das beste daran diese werte kommen direckt aus dem RamSpeicher und davon hab ich mehr als genug.

Warum ist MarkSibily nur so blöde und setzt uns sone langsamme GrabImage Function vor die Nase, wenns doch viel viel schneller geht.
 

Dreamora

BeitragFr, Okt 05, 2007 16:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Weil du mit deiner coolen FastGrabImage Umsetzung etwa 60% aller User ganz übel eins vorn Kopf schlägst, denn die meisten Onboard Karten sind nicht OpenGL tauglich, auch die Intel GMA900 die bis vor 1.5 Jahren standard war ist es nicht (fallback auf Microsoft Software Emulation)

Hinzu kommt: OpenGL ist da definitiv die miese und lahme Krücke. Wenn du dir das selbst in DX7 implementierst durch nutzung der DirectSurfaces wirds einige Welten schneller. Siehe SetBuffer() etc von Blitz3D und BlitzPlus, was nichts anderes macht.


Will heissen: Würde man die Fähigkeiten von OGL und DX wirklich ausreizen, wäre 100-500% Performancegewinn relativ schnell Mal drin.
Aber 50%+ aller Computeruser würden nix mehr sehen.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

Matthias

BeitragFr, Okt 05, 2007 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Crying or Very sad

Mh das ist ja keine schöne Neuigkeit. Ich habe eine Uhralte GeForce 5200 (128MB) selbst die Packt es.

Jaaa!!! Das wäre natürlich genial. SetBuffer wie in Blitz3D.
Aber ich habe keine Ahnung wie mann das "implementieren" soll.

DirectSurfaces habe ich auch noch nie gehört.

Gibt es denn eine einfache Alternative zu FastGrabImage bei der mann nicht auf 60% der User rücksicht nehmen muß????


Zitat:

Wenn du dir das selbst in DX7 implementierst durch nutzung der DirectSurfaces wirds einige Welten schneller
 

Dreamora

BeitragFr, Okt 05, 2007 16:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Du hast eine 3D Beschleunigerkarte, dass ist das elementare Problem.
Selbst aktuelle Intel Onboard (X3100) sind noch nicht wirklich auf dem Niveau der GeForce 5200 vor allem geschwindigkeitsmässig.

Das einzige was du machen kannst ist das was alle machen: Einen Fallback mit Fake für Klasse 4 Grafikkarten (Intel, SiS onboard) der mies aussieht aber immerhin noch läuft. (der sieht zb bei Geometry Wars so aus das es keine Grids etc etc mehr gibt, nur noch Spieler, Gegner, Schüsse) oder die explizit ausschliessen.


Die Surfaces sind eine DX7 Klasse und repräsentieren das was du als Image / Texture kennst von BM und Blitz3D.
Jedoch können sie noch mehr. In Blitz3D zb sind sie so initialisiert dass man sie locken kann um direkt in sie zu zeichnen. Das geht leider in BM nicht, da sie falsch initialisiert werden.

Indiepaths Render2Texture Modul hat das insofern umgangen dass er eine eigene CreateImage funktion geschrieben hat die das bild korrekt erzeugte so das man es entsprechen nutzen konnte für Render2Texture.

Und das ist auch das was du brauchen würdest übrigens in deinem Fall ... Render2Texture.

Alternativ kannst du das machen was auch Clonk macht übrigens, was auch 3D beschleunigte dynamische Pixelterrains hat:
TileMap System wo nur das grad als Texturen im VRAM ist was man braucht, der Rest ist im RAM. (sprich TImage was gezeichnet wird, TPixmap was nur für später da ist)

Mit dem kommst du auch auf ausreichend geschwindigkeit. Und zwar um einiges mehr als du es mit Grab jemals erreichen wirst. Denn selbst meine 8800GTS ist nicht dafür ausgelegt.
Grafikkarten sind für 2 Dinge optimiert: Daten durchjagen und Daten zeichnen.
ABER: Sie sind jedoch grottig wenns darum geht Daten zu nehmen und zurück zu geben (was du mit deinem Grab erzwingst). Dafür wurden sie einfach nicht gemacht.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Fetze

BeitragFr, Okt 05, 2007 16:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Womit wir wieder beim Thema wären - wie realisiere ich denn nun Render2Texture mit OpenGL? Die Vorschläge wurden genannt, aber ich habe leider keine AHnung, worum es sich bei den genannten Konzepten handelt. Das GrabImage-Konzept ausgenommen, welches ich getestet und angewandt habe.. aber bei den anderen wäre es schön, wenn mir jemand ein (funktionierendes) Beispiel zur Verfügung stellen könnte ôo
 

klepto2

BeitragFr, Okt 05, 2007 18:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier ist mal eine sehr frühe funktionale Form eines FBO Imagebuffers in OpenGL.

Code: [AUSKLAPPEN]

SuperStrict


Type TKLGUI
   Global Container:TList = New TList
   
   Function RegisterITEM(Item:TKLITEM)
      TKLGUI.Container.Addlast(Item)
   End Function
   
   Function Sort()
   End Function
   
   Function Update()
   End Function
End Type

Type TKLITEM Abstract
End Type

Type TKLEVENT
End Type

Type TImageBuffer
   Field Image:TImage
   Field rb:Int[1]
   Field fb:Int[1]
   Field Imageframe:TGLImageframe
   Field Frame:Int = 0
   Field OrigX:Int
   Field OrigY:Int
   Field OrigW:Int
   Field OrigH:Int

   Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 )
      Local IB:TImageBuffer = New TImageBuffer
      IB.Image = Image
      IB.Frame = Frame
      IB.GenerateFBO()
      IB.BindBuffer()
      Return IB
   End Function
   
   Method GenerateFBO()
      ImageFrame = TGLImageFrame(Image.frame(Frame) )
         
      imageframe.v0 = imageframe.v1
      imageframe.v1 = 0.0
   
      Local W:Int = Image.width
      Local H:Int = Image.Height
      
      AdjustTexSize(W , H)

      
      glGenFramebuffersEXT(1, fb )
       glGenRenderbuffersEXT(1 , rb)
      
       glBindTexture(GL_TEXTURE_2D, Imageframe.name);
       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ;
      
      
       'glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, W, H, 0, GL_RGBA8, GL_UNSIGNED_BYTE, Null);
       'glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
       'glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
      
       glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,  Imageframe.name, 0);
       glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]);
       glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H);
       glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0])
      
       Local status:Int =  glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
      
       Select status
          Case GL_FRAMEBUFFER_COMPLETE_EXT
             Print "all right" + " : " + Status
          Case GL_FRAMEBUFFER_UNSUPPORTED_EXT
             Print "choose different formats"
          Default
             End
       EndSelect
   
   End Method
   
   Method BindBuffer(Fullscreen:Byte = False)
      GetViewport(OrigX,OrigY,OrigW,OrigH)   
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0])
      'If Fullscreen = True Then
         'glViewport(0 , 0 , -Image.Width , -Image.Height) ;
      'EndIf
      glViewport(0 , 0 , Image.Width , Image.Height)
      'SetScale 1,-1
      'SetOrigin 0 , Float(Image.Height) * (GraphicsHeight() / 600.0)
      'Print (Image.Height * (GraphicsHeight()/600.0))

   End Method
   
   Method UnBindBuffer()
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0)
      glViewport(OrigX , OrigY , OrigW , OrigH)
      SetOrigin 0 , 0
      SetScale 1,1
   End Method
   
   Method Cls()
      glClearColor 0.0,0.0,0.0,0.0
      glClear GL_COLOR_BUFFER_BIT
   End Method

End Type


Function AdjustTexSize( width:Int Var,height:Int Var )
   'calc texture size
   width=Pow2Size( width )
   height=Pow2Size( height )
   Repeat
      Local t:Int
      glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
      glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t
      If t Return
      If width=1 And height=1 RuntimeError "Unable to calculate tex size"
      If width>1 width:/2
      If height>1 height:/2
   Forever
End Function

Function Pow2Size:Int( n:Int )
   Local t:Int=1
   While t<n
      t:*2
   Wend
   Return t
End Function




SetGraphicsDriver GLMax2DDriver()

Graphics 800 , 600 , 0, - 1
glewinit()


SetMaskColor 255,0,255
Global Img:TImage = CreateImage(400, 300)

Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img)

Local x:Float = 0
Local Speed:Float = 0.1

Local OX:Float = 200
Local OY:Float = 150

UpdateImage(IB,OX,OY)


While Not KeyHit(Key_Escape)
   SetClsColor 0 , 0 , 255

   Cls
      SetColor 0,255,0
      DrawRect 256,256,256,256
      SetBlend ALPHABLEND
      SetAlpha 1.0
      SetColor 255,255,255
      SetRotation 360 * Sin(X/10.0)
      DrawImage Img , 200 + X ,150
      SetRotation 0
      SetAlpha 1.0
      
      x:+ Speed
      If x > 800 -400 Then Speed = - 0.1
      If x < 0 Then Speed = 0.1
      
      If KeyDown(KEY_RIGHT)
         OX:+0.1
         UpdateImage(IB , OX , OY)
      EndIf
      
      If KeyDown(KEY_LEFT)
         OX:-0.1
         UpdateImage(IB , OX , OY)
      EndIf
      
      If KeyDown(KEY_UP)
         OY:-0.1
         UpdateImage(IB , OX , OY)
      EndIf
      
      If KeyDown(KEY_DOWN)
         OY:+0.1
         UpdateImage(IB , OX , OY)
      EndIf
      
      

      DrawText OX + " : " + OY ,20,20
   Flip   
Wend

Function UpdateImage(IB:TImageBuffer , X:Float , Y:Float)
         IB.BindBuffer()
          IB.Cls()
         SetLineWidth 4
         DrawLine 0 , 0 , 800 , 0
         DrawLine 798 , 0 , 798 , 600
         DrawLine 800 , 598 , 0 , 598
         DrawLine 0 , 600 , 0 , 0
         
         SetColor 255, 0 , 0
         SetScale 5,5
         DrawText "Hello World" , GraphicsWidth()/2-(TextWidth("Hello World")*5)/2 , GraphicsHeight()/2
         SetScale 1,1
         DrawOval X , Y , 20 , 20
         SetColor 255 , 255 , 255
         SetAlpha 1.0
         IB.UnBindBuffer()    
End Function


Ich hoffe das hilft dir etwas weiter Wink
Matrix Screensaver
Console Modul für BlitzMax
KLPacker Modul für BlitzMax

HomePage : http://www.brsoftware.de.vu

Fetze

BeitragFr, Okt 05, 2007 18:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Jup, das könnte durchaus helfen, danke Smile

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group