Blitzmax:Opengl-Anim. Textur funzt jetzt :-) [Solved]

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

SiriusMonk

Betreff: Blitzmax:Opengl-Anim. Textur funzt jetzt :-) [Solved]

BeitragMi, Feb 13, 2013 12:34
Antworten mit Zitat
Benutzer-Profile anzeigen
So der'le . Danke an Boulder Smile - neben den üblich - wie dämlich muss man sein Fehlern. Fehler:
( Variablen / Felder und Global ) und in der SetTextureUV war noch ein Logikfehler, aber jetzt funzt es Smile
Fehlt nur noch Codecleaning ...

Folgendener Code :

BlitzMax: [AUSKLAPPEN]



Strict

Import "framework.bmx"

Global Sizex:Int=640
Global SizeY:Int=400





New TNeHe6.Run(0, "Texture mapping")

Type TNeHe6 Extends TNeHe
Field texname


' Animation

Field indices:Int[] = [0, 1, 2, 3,4,5,6,7] '6,... der reihe nach die Frames auf dem Bild.
Field currentIndex:Int = 0

Field pngWidth:Int = 640 'Hier achtung! OpenGl mag es garnicht, wenn man keine 2^x kantenlängen hat! 128,256,512,1024, alles voll okay. Gilt auch für höhe
Field pngHeight:Int = 400

'Bezieht sich auf die Framegröße, ausgehend davon, das alle frames gleichgroß sind. Float nur, um rundungsfehler zu vermeiden. Siehe: SetTextureCoords
Field frameWidth:Float = 64
Field frameHeight:Float = 128

'Bezieht sich auf die frameanordnung. du hast 4x2 frames.
Field framesPerRow:Int = 4
Field framesPerLine:Int = 2

Field time:Int = MilliSecs() + 250 'zum umschalten der frames

' Animation



Method Init()

Global tex01:TPixmap = LoadPixmap("IsoHex.png")
Texname:Int= GLTexFromPixmap(tex01) ' texname , weil texname doppel: texname
pngwidth=tex01.Width
pngheight=tex01.Height

glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT

glEnable GL_DEPTH_TEST
glEnable GL_TEXTURE_2D

glDepthFunc GL_LESS
glMatrixMode GL_PROJECTION
glLoadIdentity
glViewport 0,0,ScreenWidth,ScreenHeight
glOrtho 0, SizeX, SizeY,0, 0, 128 ' achse gespiegelt oben links, ansonsten hal position mittelpunkt -halbbreite, halbehöhe
glMatrixMode GL_MODELVIEW
glLoadIdentity
glTranslatef 120, 120, 0 ' -> hier rotate etc
End Method

Method Loop()

glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
glEnable(GL_TEXTURE_2D)
glEnable GL_ALPHA_TEST
'glEnable GL_CULL_FACE




glBindTexture GL_TEXTURE_2D, Texname
glPixelStorei GL_UNPACK_ALIGNMENT, 1
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
glTexEnvf GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE
' glTexImage2D GL_TEXTURE_2D, 0, GL_RGB, 640, 400, 0, GL_RGB, GL_UNSIGNED_BYTE,

glAlphaFunc GL_GREATER, 0.1


glBegin GL_QUADS
''Oben links, oben rechts, unten rechts, unten links.
SetTextureCoords(0) ; glVertex3f 0.0,0.0,0.0
SetTextureCoords(1) ; glVertex3f 64.0,0.0,0.0
SetTextureCoords(2) ; glVertex3f 64.0,64.0,0.0
SetTextureCoords(3) ; glVertex3f 0.0,64.0, 0.0

glEnd
Update()

End Method



Method update()
If time < MilliSecs()
time = MilliSecs() + 250

currentIndex = (currentIndex + 1) Mod Len(indices)
'mod sorgt dafür, das die animation von vorne beginnt, wenn durchgelaufen.
EndIf
End Method

'Nur innerhalb von glBegin/glEnd aufrufen und BEVOR der vertex platziert wird. Der Parameter index diehnt als vertex-index. ausgehend von der reihenfolge: Oben links, oben rechts, unten rechts, unten links.
Method SetTextureCoords(index:Int)
Local u:Float = 0
Local v:Float = 0

Local frameIndex:Int = indices[currentIndex] 'aktuelles frame holen

Local frameY:Int = frameIndex / framesPerRow
Local frameX:Int = frameIndex Mod framesPerRow ' framesPerLine Indizes falsch

u = (frameX * frameWidth) / pngWidth 'wäre frameWidth ein integer, gäbe es bei der division mit pngWidth rundungsfehler.
v = (frameY * frameHeight) / pngHeight



'weiter im text. Uv bezieht sich nun auf die obere linke ecke.
Select index
Case 0
Case 1
u:+frameWidth / pngWidth
Case 2
u:+frameWidth / pngWidth
v:+frameHeight / pngHeight
Case 3
v:+frameHeight / pngHeight
End Select

glTexCoord2d(u,v) 'hier das eigentliche setzen :>

End Method
End Type





dazugehöriges png: ( grau sollte eigentlich schwarz/transparent sein Confused )

user posted image


dazugehöriges Framework

BlitzMax: [AUSKLAPPEN]


Strict

Const SCREENWIDTH = 800
Const SCREENHEIGHT = 600
Const SCREENDEPTH = 0
Const SCREENHERTZ = 60

Type TNeHe
Method Init() Abstract
Method Loop() Abstract

Method Run(lesson_number, lesson_name$,flags:Int=GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER)
AppTitle = "NeHe Tutorial "+lesson_number+": "+lesson_name
GLGraphics SCREENWIDTH,SCREENHEIGHT,SCREENDEPTH,SCREENHERTZ,flags

Init

While Not KeyDown(KEY_ESCAPE) And Not AppTerminate()
Loop
glDisable GL_LIGHTING
glColor3f 1.0,1.0,1.0
GLDrawText "FPS : "+GetFPS(),0,0
Flip
Wend
End Method

Function GetFPS()
Global _fps,_ticks,_lastupdate
If _lastupdate+1000<MilliSecs()
_fps=_ticks
_ticks=0
_lastupdate=MilliSecs()
Else
_ticks:+1
EndIf
Return _fps
End Function
End Type

  • Zuletzt bearbeitet von SiriusMonk am Mi, Feb 13, 2013 17:39, insgesamt 5-mal bearbeitet
 

PhillipK

BeitragMi, Feb 13, 2013 12:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein paar dinge:
1) Unheimlich schwer zu lesen. Bitte den Blitzmax Codetag verwenden und ein paar mehr leerzeilen spendieren
2) Grade opengl wartet mit ziemlich fiesen, ähnlich aussehenden funktionen auf. Hier sorge ich dafür, das immer brav zu bündeln: Glbegin, vertexdaten, glend. Vorne und hinterher nen absatz oder kommentar. Aktivieren von states etc auch schön gebündelt.

3) Was genau macht deine Animations-anzeige?
BlitzMax: [AUSKLAPPEN]

glTexCoord2f AnimX, 1-AnimY-1/AnimRows ; glVertex3f -192, -192, 0
glTexCoord2f AnimX+1/AnimCols, 1-AnimY-1/AnimRows ; glVertex3f 192, -192, 0
glTexCoord2f AnimX+1/AnimCols, 1-AnimY ; glVertex3f 192, 192, 0
glTexCoord2f AnimX, 1-AnimY ; glVertex3f -192, 192, 0

Schaut weird aus.

Im prinzip brauchst du eine umrechnungsfunktion:
BlitzMax: [AUSKLAPPEN]

Type TAnimationSet
Field indices:Int[] = [0, 1, 2, 3, 4, 5] '6,... der reihe nach die Frames auf dem Bild.
Field currentIndex:Int = 0

Field pngWidth:Int = 640 'Hier achtung! OpenGl mag es garnicht, wenn man keine 2^x kantenlängen hat! 128,256,512,1024, alles voll okay. Gilt auch für höhe
Field pngHeight:Int = 400

'Bezieht sich auf die Framegröße, ausgehend davon, das alle frames gleichgroß sind. Float nur, um rundungsfehler zu vermeiden. Siehe: SetTextureCoords
Field frameWidth:Float = 308
Field frameHeight:Float = 256

'Bezieht sich auf die frameanordnung. du hast 4x2 frames.
Field framesPerRow:Int = 4
Field framesPerLine:Int = 2

Field time:Int = MilliSecs() + 250 'zum umschalten der frames
Method update()
If time < MilliSecs()
time = MilliSecs() + 250

currentIndex = (currentIndex + 1) Mod Len(indices)
'mod sorgt dafür, das die animation von vorne beginnt, wenn durchgelaufen.
EndIf
End Method

'Nur innerhalb von glBegin/glEnd aufrufen und BEVOR der vertex platziert wird. Der Parameter index diehnt als vertex-index. ausgehend von der reihenfolge: Oben links, oben rechts, unten rechts, unten links.
Method setTextureCoords(index:Int)
Local u:Float = 0
Local v:Float = 0

Local frameIndex:Int = indices[currentIndex] 'aktuelles frame holen

Local frameY:Int = frameIndex / framesPerRow
Local frameX:Int = frameIndex Mod framesPerLine

u = (frameX * frameWidth) / pngWidth 'wäre frameWidth ein integer, gäbe es bei der division mit pngWidth rundungsfehler.
v = (frameY * frameHeight) / pngHeight



'weiter im text. Uv bezieht sich nun auf die obere linke ecke.
Select index
Case 0
Case 1
u:+frameWidth / pngWidth
Case 2
u:+frameWidth / pngWidth
v:+frameHeight / pngHeight
Case 3
v:+frameHeight / pngHeight
End Select

glTexCoord2d(u,v) 'hier das eigentliche setzen :>

End Method
End Type


Das habe ich auf die schnelle als pseudocode geschrieben.

Ein paar punkte:
1) UV koordinaten liegen im bereich 0...1. Das heißt floatzahlen.
die berechnung geht relativ einfach: TotalePixelPositionX / BildBreite und TotalePixelPositionY / BildHöhe

Ich verrechne allerdings eine verschiebung. so errechne ich die pixelposition im bild und teile sie durch die bildbreite bzw höhe. Es geht anders, man kann viel mehr vorberechnen, aber zur anschauung reicht es.

2) Ich hab die funktion rel. dreckig aufgebaut. Im prinzip bist du mit einem UV Array besser bediehnt, den du beim Bildladen erstellst. Im idealfall ist es ein float[,] wo der erste Index den Animationsindex darstellt und der 2te Index mit 0 für U und 1 für V steht.

3) Der code ist nicht getestet.


Falls noch rückfragen bestehen, versuche ich das ganze mehr zu erklären Very Happy Mir gings nur um die rechnung ^^

Tennisball

BeitragMi, Feb 13, 2013 13:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein paar weitere Dinge:

1) Wie PhillipK sagte, rücke deinen Code ein (bitte mit Tabs). Benutze außerdem für Funktionsaufrufe Klammernpaare!

2) glEnable, egal welche Parameter, musst du pro Sache die du "enablen" willst nur einmal aufrufen, nicht in deiner "Loop"-Funktion.

3) Das glDisable( GL_TEXTURE_2D ) hat in deinem Code keinen Sinn, kann das sein?

Gruß,
Tennisball
 

SiriusMonk

BeitragMi, Feb 13, 2013 13:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Wow !

Ich wollte grade meine Rechner runterfahren, vielen Dank euch beiden.... ich werde es soweit berücksichtigen und mir jetzt mal den "Pseudocode" zu Gemüte führen.... Die Animation ist entnommen aus
Isometric Game Programming with DirectX 7.0 - daher auch der Animationsheet (nur von tga->png) wegen Pixmap .... eigentlich soll die Figur sich nur bewegen und die Keule schwingen - die TexCords-Angaben sind aus dem Orignalquellcode übernommen...

Schönen Gruß und Danke

SiriusMonk

BladeRunner

Moderator

BeitragMi, Feb 13, 2013 13:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine Winzigkeit, aber das Grau ist doch transparent Wink
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group