[GELÖST] Blitzmax - Bild auf Polygon rendern?

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] Blitzmax - Bild auf Polygon rendern?

BeitragMo, Jul 10, 2017 21:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich hätte da mal wieder eine Frage: Ist es möglich mit den Mitteln aus Max2D ein Bild auf ein Polygon zu rendern? Wenn ja, wie?

Grüße,

Marius
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Mi, Jul 19, 2017 19:02, insgesamt einmal bearbeitet

BladeRunner

Moderator

BeitragMo, Jul 10, 2017 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, irgendwo in den Tiefen meiner alten Platte liegen passende Funktionen dafür. Find ich natürlich wieder nicht.
Was ich gefunden habe ist das hier:
BlitzMax: [AUSKLAPPEN]
    Strict
'Rem
SetGraphicsDriver GLMax2DDriver()
Graphics 800,600

Local Image:TImage = LoadImage("clock.png") ' 32x32 256x256 e.t.c
Local TestImage:TImage = LoadImage("sun.png")

Local xyuv:Float[] = [ ..
100.0,100.0, 0.5, 0.5,..
100.0, 36.0, .5, 0.0, ..
145.2, 54.0, .85, 0.14 ..
]

SetBlend AlphaBlend
SetScale 2,2
SetAlpha .5
'DrawImage Image, 0, 0
DrawTexturedPoly Image, xyuv
'DrawImage TestImage, 200, 200

Flip
WaitKey
' End Rem


Function DrawTexturedPoly( image:TImage,xyuv#[],frame=0, vertex = -1)
Local handle_x#, handle_y#
GetHandle handle_x#, handle_y#
Local origin_x#, origin_y#
GetOrigin origin_x#, origin_y#

Local D3DDriver:TD3D7Max2DDriver = TD3D7Max2DDriver(_max2dDriver)

Assert Image, "Image not found"

If D3DDriver Then
DrawTexturedPolyD3D ..
D3DDriver,..
TD3D7ImageFrame(image.Frame(frame)), ..
xyuv, handle_x, handle_y, origin_x,origin_y, vertex*4
Return
End If
Local OGLDriver:TGLMax2DDriver = TGLMax2DDriver(_max2dDriver)
If OGLDriver Then
DrawTexturedPolyOGL ..
OGLDriver,..
TGLImageFrame(image.Frame(frame)), ..
xyuv, handle_x, handle_y, origin_x,origin_y, vertex*4
Return
End If
End Function


Function DrawTexturedPolyD3D( Driver:TD3D7Max2DDriver, Frame:TD3D7ImageFrame,xyuv#[],handlex#,handley#,tx#,ty# , vertex)
'If Driver.islost() Return
If xyuv.length<6 Return
Local segs=xyuv.length/4
Local len_ = Len(xyuv)

If vertex > - 1 Then
segs = vertex / 4
len_ = vertex
End If
Local uv#[] = New Float[segs*6] ' 6


Local c:Int Ptr=Int Ptr(Float Ptr(uv))

Local ii:Int = 0
For Local i=0 Until len_ Step 4
Local x# = xyuv[i+0]+handlex
Local y# = xyuv[i+1]+handley
uv[ii+0] = x*Driver.ix+y*Driver.iy+tx
uv[ii+1] = x*Driver.jx+y*Driver.jy+ty
uv[ii+2] = 0 ' *********** THIS IS THE Z-COORDINATE
c[ii+3] = Driver.DrawColor
uv[ii+4] = xyuv[i+2]
uv[ii+5] = xyuv[i+3]
ii:+6
Next
Driver.SetActiveFrame Frame
Driver.device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ| D3DFVF_DIFFUSE | D3DFVF_TEX1,uv,segs,0)
End Function

Function DrawTexturedPolyOGL (Driver:TGLMax2DDriver, Frame:TGLImageFrame, xy#[],handle_x#,handle_y#,origin_x#,origin_y#, vertex)
Private
Global TmpImage:TImage
Public

If xy.length<6 Return

Local rot# = GetRotation()
Local tform_scale_x#, tform_scale_y#
GetScale tform_scale_x, tform_scale_y

Local s#=Sin(rot)
Local c#=Cos(rot)
Local ix= c*tform_scale_x
Local iy=-s*tform_scale_y
Local jx= s*tform_scale_x
Local jy= c*tform_scale_y

glBindTexture GL_TEXTURE_2D, Frame.name
glEnable GL_TEXTURE_2D

glBegin GL_POLYGON
For Local i=0 Until Len xy Step 4
If vertex > -1 And i >= vertex Then Exit
Local x#=xy[i+0]+handle_x
Local y#=xy[i+1]+handle_y
Local u#=xy[i+2]
Local v#=xy[i+3]
glTexCoord2f u,v
glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y
Next
glEnd
If Not tmpImage Then tmpImage = CreateImage(1,1)
DrawImage tmpImage, -100, - 100 ' Chtob zbit' flag texturi
End Function


Leider ist da ein wenig der Wurm drin - es funktioniert nur die OGl-Version, die DX7-Variante läuft zwar durch, rendert aber nichts. Ich glaube mich zu erinnern dass ich das damals auf diesem Code basiert gefixt hatte, aber frag mich nicht mehr nach dem wie. Zudem war das weit vor Win10, wahrscheinlich noch zu XP-Zeiten.

Aber als Ausgangspunkt tut es das, es müsste halt auf DX9 /11 gepatcht werden.

Hoffe es hilft dir.
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
 

CO2

ehemals "SirMO"

BeitragDi, Jul 11, 2017 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich bedanke mich! Das geht allerdings nur für quadratische Bilder, richtig? Gibt es etwas ähnliches für nicht-quadratische Bilder?

EDIT: DAS GEHT JA AUCH FÜR NICHT-QUADRATISCHE BILDER!!! Ich freue mich derbe. Vielen Dank. Wenn ich fertig gebastelt habe, poste ich hier den Code.

EDIT II: Leider nur halber Code, aber eine Frage: Ich versuche aktuell folgendes: Ich habe ein 2D-Modell von einem Fahrzeug (Top-Down). Nun möchte ich per Polygon den Rahmen des Fahrzeugs malen und dort drin das Fahrzeugmodell rendern. Das funktion dank BladeRunners Code auch tadellos. Was ich jetzt jedoch vor habe ist, dass ich die "Auflösung" des Rahmens anpasse. Also während normalerweise nur 4 Eckpunkte bei einem Rechteck nötig wären, male ich einfach 8, sodass jede Seite 3 Punkte hat (Beide Eckpunkte inklusive). Wenn ich nun einen Punkt verschiebe, kann ich ein dynamisches Schadensmodell simulieren (naja, mehr oder weniger). Jedoch passiert bei der Manipulation des obigen Punktes beispielsweise nichts. Als ich mir das ganze mit DrawPoly nochmal anschaute, fiel mir auf, dass der verschobene Punkt einfach übermalt wird. Meine Frage ist jetzt, wie ich dieses Verhalten umgehen kann. Hier mein bisheriger Code:
BlitzMax: [AUSKLAPPEN]
' Import "../../../../../functions/functions.bmx"

Function DrawTexturedPoly(image:TImage, xyuv:Float[], frame:Int = 0, vertex:Int = -1)
Local handle_x:Float
Local handle_y:Float
GetHandle(handle_x, handle_y)

Local origin_x:Float
Local origin_y:Float

GetOrigin(origin_x, origin_y)

Local OGLDriver:TGLMax2DDriver = TGLMax2DDriver(_max2dDriver)
If (OGLDriver)
DrawTexturedPolyOGL(OGLDriver, TGLImageFrame(image.Frame(frame)), xyuv, handle_x, handle_y, origin_x, origin_y, vertex * 4)
End If
End Function

Function DrawTexturedPolyOGL(Driver:TGLMax2DDriver, Frame:TGLImageFrame, xy:Float[], handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float, vertex:Int)
Private
Global TmpImage:TImage

Public
If (xy.length < 6) Then Return

Local rot:Float = GetRotation()
Local tform_scale_x:Float
Local tform_scale_y:Float
GetScale(tform_scale_x, tform_scale_y)

Local s:Float = Sin(rot)
Local c:Float = Cos(rot)
Local ix:Float = c * tform_scale_x
Local iy:Float = -s * tform_scale_y
Local jx:Float = s * tform_scale_x
Local jy:Float = c * tform_scale_y

glBindTexture(GL_TEXTURE_2D, Frame.name)
glEnable(GL_TEXTURE_2D)

glBegin(GL_POLYGON)
For Local i:Int = 0 Until Len(xy) Step 4
If (vertex > -1 And i >= vertex) Then Exit

Local x:Float = xy[i + 0] + handle_x
Local y:Float = xy[i + 1] + handle_y
Local u:Float = xy[i + 2]
Local v:Float = xy[i + 3]

glTexCoord2f(u, v)

glVertex2f(x * ix + y * iy + origin_x, x * jx + y * jy + origin_y)
Next
glEnd

If (Not tmpImage) Then tmpImage = CreateImage(1,1)
DrawImage(tmpImage, -100, -100) ' Chtob zbit' flag texturi
End Function

SetGraphicsDriver(GLMax2DDriver())

Graphics(800, 600)

Local fpstimer:TTimer = CreateTimer(60)

Type T2DModel
Field xyuv:Float[]
Field model:TImage
Field resolution:Double

Function Create:T2DModel(modelsrc:Object, resolution:Int = 1)
Local RetVal:T2DModel = New T2DModel
RetVal.model = LoadImage(modelsrc, MASKEDIMAGE)
RetVal.resolution = resolution
RetVal.CalculateXYUVCoords()
Return RetVal
End Function

Method CalculateXYUVCoords()
Local imgwidth:Double = ImageWidth(Self.model)
Local imgheight:Double = ImageHeight(Self.model)

Local arraydim:Int = 4 * 4 * Self.resolution ' 4 values per coord
If (arraydim <= 0) Then Return

xyuv = New Float[arraydim]

For Local pnt:Int = 0 To (Self.resolution - 1)
' oben
Local base:Int = pnt * 4
xyuv[base + 0] = pnt * (imgwidth / Self.resolution)
xyuv[base + 1] = 0.0
xyuv[base + 2] = pnt * (1.0 / Self.resolution)
xyuv[base + 3] = 0.0

' rechts
base = 4 * Self.resolution * 1 + pnt * 4
xyuv[base + 0] = imgwidth
xyuv[base + 1] = pnt * (imgheight / Self.resolution)
xyuv[base + 2] = 1.0
xyuv[base + 3] = pnt * (1.0 / Self.resolution)

' unten
base = 4 * Self.resolution * 2 + pnt * 4
xyuv[base + 0] = imgwidth - (pnt * (imgwidth / Self.resolution))
xyuv[base + 1] = imgheight
xyuv[base + 2] = 1.0 - (pnt * (1.0 / Self.resolution))
xyuv[base + 3] = 1.0

' links
base = 4 * Self.resolution * 3 + pnt * 4
xyuv[base + 0] = 0.0
xyuv[base + 1] = imgheight - (pnt * (imgheight / Self.resolution))
xyuv[base + 2] = 0.0
xyuv[base + 3] = 1.0 - (pnt * (1.0 / Self.resolution))
Next
End Method

Method Draw(posx:Double, posy:Double, rot:Double)
DrawTexturedPoly(Self.model, Self.xyuv)
End Method
End Type

SetMaskColor(255, 0, 255)
SetClsColor(64, 64, 64)

Local model:T2DModel = T2DModel.Create("vehicle009.bmp", 2)

' "Delle erzeugen"
model.xyuv[5] = 50

Local momrot:Double = 0.0

Repeat
WaitTimer(fpstimer)
Cls()

model.Draw(100, 100, momrot)

momrot = (momrot + 0.5) Mod 360

Flip()
Until KeyHit(KEY_ESCAPE)
End


Als Bild kann irgendein Bild genommen werden, spielt keine Rolle.

Das Bild wird jedoch weiterhin Rechteckig gezeichnet.

EDIT III: Oder anders gefragt: Warum ergibt folgender BlitzMax: [AUSKLAPPEN]
Local asdf:Float[10]
asdf[0] = 0.0
asdf[1] = 0.0
asdf[2] = 50.0
asdf[3] = 50.0
asdf[4] = 100.0
asdf[5] = 0.0
asdf[6] = 100.0
asdf[7] = 100.0
asdf[8] = 0.0
asdf[9] = 100.0

Graphics(800, 600)

Local fps:TTimer = CreateTimer(60)

Repeat
WaitTimer(fps)
Cls()

DrawPoly(asdf)

Flip(0)
Until KeyHit(KEY_ESCAPE)
End
folgendes Bild:
user posted image
Wo ich doch eigentlich ein solches erwarten würde:
user posted image
?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
 

CO2

ehemals "SirMO"

BeitragDi, Jul 18, 2017 20:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich mache mal einen neuen Post, statt dem editieren des vorherigen. Ich habe es nun hinbekommen, es so wie im zweiten Bild zu malen. Dafür habe ich das große Polygon in mehrere kleine unterteilt.
Jetzt fällt auf, dass offensichtlich irgendein Scalefaktor oder sonstiges greift. Die Positionen auf dem Bildschirm und die u und v-Koordinaten sehen zwar gut aus (so wie erwartet), jedoch wird das Bild skaliert gemalt. Die Skalierung ist so krass, dass das Bild in der Höhe auf etwa 75% kleiner ist. Und das obwohl - wie geschrieben - die Koordinaten, die per glVertex2f und glTexCoord2f übergeben werden korrekt aussehen. Woran kann das liegen?
Ich selbst nutze kein SetScale, hantiere aber mit SetOrigin und SetHandle herum um das Bild an die gewünschte Position zu malen. Diese Manipulationen setze ich jedoch jedes Mal zurück.
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Holzchopf

Meisterpacker

BeitragDi, Jul 18, 2017 22:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Klingt als wäre dein Bild nicht quadratisch und nicht mit Seitenlänge 2^n. Wenn du z.B. ein 100x80 px grosses Bild lädst, wird es zwangsweise eine 128x128 px Textur belegen. Die Texturkoordinaten von dem Bildteil, der dich interessiert, gehen dann bis 100.0/128.0 resp. 80.0/128.0, also (0.78125, 0.625) - nicht (1, 1)

mfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

CO2

ehemals "SirMO"

BeitragMi, Jul 19, 2017 19:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank für die Antwort! Exakt das war's. Allerdings ist bei mir aufgefallen, dass für Höhe und Breite des Bildes verschiedene Texturauflösungen genommen werden. Mein Bild ist 60 x 200 px groß und als Texturauflösung wird 64 x 256 px genommen (Beweis durch malen Very Happy )

Grüße,

Marius
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

BladeRunner

Moderator

BeitragMi, Jul 19, 2017 19:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Was auch so passt, es wird immer die nächste zweier Potenz genommen.
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 Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group