Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Jul 13, 2025 20:18

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Billboarding
BeitragVerfasst: Mi Mai 06, 2009 11:34 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Dez 03, 2008 12:01
Beiträge: 167
Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
So, ich hab mal wieder ein Problem. Diesmal geht es um ein Partikelsystem. Ich hab mir verschiedene Tutorials durchgelesen und dann versucht, mein eigenes zu schreiben. Das hat auch eigentlich ganz gut geklappt (auch wenn ich es noch erweitern muss), allerdings konnte man die Partikel von der Seite sehen, was wirklich nicht schön aussieht.

Also hab ich wieder ein bisschen rumgesucht und bin auf einige Infos über Billboarding gestoßen. Gleich eingebaut und fertig. Dachte ich.

Wenn ich mich jetzt aber in meiner 3d-Welt bewege, bekomme ich seltsame Dinge zu sehen. Die Partikel sind zwar zu Kamera ausgerichtet, bewegen sich dabei sehr seltsam, wenn man zum Beispiel nahe an die Partikel geht und die Kamera dreht. (Könnt ihr selbst ausprobieren: http://www.gamerzone.info/startseite/download.php?id=76)



Hier auch mal die wichtigsten Teile des Codes:



Code:
  1. type Xenon_particle                        '// the type for each particle    
  2.  
  3.     position as Xenon_point3d              '// position of the particle
  4.  
  5.     velocity as Xenon_point3d              '// velocity vector (speed) of the particle
  6.  
  7.     xcolor(3) as GLfloat                   '// color of the particle
  8.  
  9.     size as GLfloat                        '// size of the particle
  10.  
  11.     TimeToLive as integer                  '// how long the particle lives (from now)
  12.  
  13.     status as BYTE                         '// status of the particle (living or not)
  14.  
  15.     mass as single                         '// mass of the particle
  16.  
  17.     nextEntry as Xenon_particle PTR        '// next entry in the particle-list
  18.  
  19. end type
  20.  
  21.  
  22.  
  23. type Xenon_ParticleEffect                  '// the type for the particle-system
  24.  
  25.     position as Xenon_point3d              '// where the particles come from
  26.  
  27.     texture as Xenon_texture2d             '// the texture for the particles
  28.  
  29.     particles as Xenon_particle PTR        '// the pointer to the first particle
  30.  
  31.     declare sub render ()                  '// the render-procedure for this system
  32.  
  33.     declare sub update ()                  '// the update-procedure for this system
  34.  
  35.     declare sub add ()                     '// add a new particle
  36.  
  37. end type
  38.  
  39.  
  40.  
  41. '// Xenon_ParticleEffect.update addiert den Geschwindigkeits-vektor zur position
  42.  
  43.  
  44.  
  45. sub Xenon_ParticleEffect.render                          '// the render-procedure for this system
  46.  
  47.     dim currentParticle as Xenon_particle PTR            '// pointer for the particles
  48.  
  49.     currentParticle = This.particles                     '// point to first particle
  50.  
  51.    
  52.  
  53.     glBindTexture (GL_TEXTURE_2D, This.texture.handle)
  54.  
  55.    
  56.  
  57.     glDepthMask (GL_FALSE)
  58.  
  59.     glDisable (GL_DEPTH_TEST)
  60.  
  61.     glEnable (GL_BLEND)
  62.  
  63.     glBlendFunc (GL_SRC_ALPHA, GL_ONE)
  64.  
  65.    
  66.  
  67.     do until currentParticle = 0
  68.  
  69.         glColor4fv @(currentParticle->xcolor(0))
  70.  
  71.         glBegin (GL_QUADS)
  72.  
  73.             glTexCoord2i (1, 1)
  74.  
  75.             glVertex3f currentParticle->position.x+currentParticle->size, currentParticle->position.y+currentParticle->size, currentParticle->position.z
  76.  
  77.            
  78.  
  79.             glTexCoord2i (0, 1)
  80.  
  81.             glVertex3f currentParticle->position.x-currentParticle->size, currentParticle->position.y+currentParticle->size, currentParticle->position.z
  82.  
  83.            
  84.  
  85.             glTexCoord2i (0, 0)
  86.  
  87.             glVertex3f currentParticle->position.x-currentParticle->size, currentParticle->position.y-currentParticle->size, currentParticle->position.z
  88.  
  89.            
  90.  
  91.             glTexCoord2i (1, 0)
  92.  
  93.             glVertex3f currentParticle->position.x+currentParticle->size, currentParticle->position.y-currentParticle->size, currentParticle->position.z
  94.  
  95.         glEnd
  96.  
  97.         currentParticle = currentParticle->nextEntry
  98.  
  99.     loop
  100.  
  101.    
  102.  
  103.     glColor3f 1, 1, 1
  104.  
  105.     glDisable (GL_BLEND)
  106.  
  107.     glEnable (GL_DEPTH_TEST)
  108.  
  109.     glDepthMask (GL_TRUE)
  110.  
  111. end sub




Mit Xenon_ParticleEffect.render werden alle vorhanden Partikel in der Liste mit Blending gezeichnet.

Mein Kamerasystem funktioniert mit glTranslate und glRotate Befehlen. Die Billboarding-routine sollte praktisch die Rotation der Kamera wieder rückgängig machen. Die auskommentierten Zeilen hab ich schon ausprobiert, die liefern auch seltsame Ergebnisse.

Hier also der Billboarding-Code:

Code:
  1. sub Xenon_Billboard (camera as Xenon_camera)
  2.  
  3. '    dim NewModelView (0 to 11) as GLfloat = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0}
  4.  
  5. '    dim Modelview (0 to 15) as GLfloat
  6.  
  7. '    
  8.  
  9. '    glGetFloatv (GL_MODELVIEW_MATRIX, @Modelview(0))
  10.  
  11. '    memcpy (@Modelview(0), @NewModelView(0), sizeof(NewModelView))
  12.  
  13. '    glLoadMatrixf (@Modelview(0))
  14.  
  15.    
  16.  
  17. ''    glRotatef(PI, 1.0, 0.0, 0.0)
  18.  
  19. ''    glRotatef(PI, 0.0, 1.0, 0.0)
  20.  
  21.    
  22.  
  23.     glRotatef(-camera.yrot, 0.0, 1.0, 0.0)
  24.  
  25.     glRotatef(-camera.xrot, 1.0, 0.0, 0.0)
  26.  
  27.    
  28.  
  29. end sub




Im Hauptprogramm wird dann ein Partikelsystem erstellt, ein paar Partikel hinzugefügt und der Spaß gerendert:

Code:
  1. dim ParticleSystem as Xenon_particleEffect
  2.  
  3.  
  4.  
  5. '...
  6.  
  7.  
  8.  
  9.     if effectenabled = true then
  10.  
  11.         glPushMatrix
  12.  
  13.         ParticleSystem.update
  14.  
  15.         Xenon_Billboard camera
  16.  
  17.         ParticleSystem.render
  18.  
  19.         glPopMatrix
  20.  
  21.     end if




Ich hab mal wieder überhaupt keine Ahnung woran das liegt.


Zuletzt geändert von darkinsanity am Do Mai 07, 2009 13:06, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Mai 06, 2009 11:42 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
(Könnt ihr selbst ausprobieren: LINK HIER EINFÜGEN!)

Zitat:
Ich hab mal wieder überhaupt keine Ahnung woran das liegt.

So wird dir niemand helfen können. Poste doch mal einen Screenshot oder so. Ich vermute du hattest sowas auch vor, aber dann irgendwie vergessen? ;)

Es wäre vielleicht auch sinnvoll zu erfahren um welche Programmiersprache es sich da handelt. Sieht jedenfalls weder nach Delphi noch nach C++ aus. Sollte das Perl sein?
Edit: Nein, Perl ist es nicht...nächster Versuch: Python?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Mai 06, 2009 12:09 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Das Sub sieht verdächtig nach VB aus...

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Mai 06, 2009 12:34 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Python ist hübscher ;).

Ich hab zwar deinen Code nicht ganz genau kapiert, aber wenn mich nicht alles täuscht, beschreibst du da das ganz normale Billboard-Verhalten. Denn das Rückgängigmachen der Matrixänderungen (das, was du tun willst und was man beim allgemeinen Billboarding auch macht) richtet nicht die Billboards zur Kamera aus. Sondern es richtet sie so aus, dass ihre Normale entgegengesetzt zu der Normale der Kamera ist. Nun kann man sich die Kamera in OpenGL als Ebene vorstellen, als NearClippingPlane.
Wenn du jetzt die Kamera drehst, drehst du die Ebene. Das heißt, die Normale der Ebene verändert sich, dreht sich mit. Die Partikel reagieren darauf und drehen sich ebenfalls. Das sieht erstmal komisch aus, ist aber logisch. Wenn du das Verhalten anders haben willst, musst du dafür sorgen, dass die Normale der Partikel (und damit auch die Fläche) immer in richtung des Punktes zeigt, von dem die Kamera ausgeht. Dann hast du den Effekt, den du vermutlich erwartet hast. Normalerweise benutzt man aber das Vorgehen, welches dieses "Artefakt" hervorruft (findest du sicherlich auch in einigen kommerziellen Spielen).

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 07, 2009 13:04 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Dez 03, 2008 12:01
Beiträge: 167
Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
Die Sprache ist FreeBASIC :)
Eigentlich wollte ich die demo hochladen, scheitert aber daran dass freehoster.ch ständig nicht funktioniert.
So, download gibts hier: http://www.gamerzone.info/startseite/download.php?id=76

@Lord Horazont: Gibt es da ein Tut oder so was?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 07, 2009 18:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hier im Wiki gibts den Artikel zum Thema Sphärisches Billboard. Der könnte helfen.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 08, 2009 11:54 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Dez 03, 2008 12:01
Beiträge: 167
Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
danke :)
achja, hab total vergessen: in der Demo muss man "N" drücken, damit das Partikelsystem gestartet wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:47 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Also ich habe in meiner Partikelengine für die Billboards eine einfache Methode geschrieben. Die Methode richtet jedes Quad genau zur Kamera aus:

Code:
  1.     protected Vector3f[] getBillboardedPosition(GL gl, GLU glu)
  2.     {
  3.         final int[][] QUAD = {{1, 1},{-1, 1},{-1, -1},{1, -1}};//new int[4][2];
  4.  
  5.         Vector3f[] result = new Vector3f[4];
  6.         Vector3f right = null;
  7.         Vector3f up = null;
  8.        
  9.         FloatBuffer modelViewMatrix = FloatBuffer.allocate(16);
  10.        
  11.         gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelViewMatrix);
  12.        
  13.         right   = new Vector3f(modelViewMatrix.get(0),
  14.                                modelViewMatrix.get(4),
  15.                                modelViewMatrix.get(8));
  16.        
  17.         up      = new Vector3f(modelViewMatrix.get(1),
  18.                                modelViewMatrix.get(5),
  19.                                modelViewMatrix.get(9));
  20.        
  21.         for (int i = 0; i <=3; i++)
  22.         {
  23.             result[i] = new Vector3f((QUAD[i][0]*right.x + QUAD[i][1]*up.x) * textureSize[0]/2,
  24.                                      (QUAD[i][0]*right.y + QUAD[i][1]*up.y) * textureSize[1]/2,
  25.                                      (QUAD[i][0]*right.z + QUAD[i][1]*up.z) * textureSize[1]/2);
  26.                    
  27.         }
  28.         return result;
  29.     }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 16:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Uff, und das machst du für jeden Partikel? Halte ich für übertrieben. Ich würde Right und Up-Vektoren zwischenspeichern. Vorallem nicht dauernd die Matrix auslesen.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 17:42 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Was spricht eigentlich gegen GL_POINTS? Die Dinger werden automatisch zur Kamera ausgerichtet, selbst um Texturkoordinaten muss man sich nicht kümmern. Ist natürlich WESENTLICH schneller, da die ganzen Berechnungen auf der Grafikkarte durchgeführt werden.

Code:
  1. glEnable(GL_POINT_SPRITE);
  2. glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);


Die Punktgröße wird als Vertexattribut angegeben. Ich nehme die Transformation der PointSize selbst im Vertexshader vor, aber das geht auch mit der festen Funktionspipeline. Siehe glPointParameter.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 17:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wenn ich mich recht erinnere, gibt es eine Maximalbeschränkung für PointSize. Je nach Distanz und Partikelart könnte es da zu unschönheiten kommen, oder?

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 18:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ich bin mir nicht 100%ig sicher, aber ich glaube diese Größe kannst du mit glPointParameter selbst festlegen. Zudem sind Partikel normalerweise nicht so groß, dafür sind es halt sehr viele. Wenn du GL_POINTS verwendest kannst du auch wesentlich mehr Partikel rendern. In jedem Fall sind ziemlich große Partikel möglich, also 128x128 Pixel (Screenspace) müssten eigentlich gehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 18:00 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Es gibt eine Erweiterung, mit der man tatsächlich GL_POINTS wunderbar für Partikelsystem einsetzen kann, da man damit die Größe afaik beliebig groß setzen kann. Weiß aber grad nicht den Namen... gibt aber genug Demos im Netz dazu. Hab irgendwas von wegen GL_POINT_SPRITE in Erinnerung aber ist schon ne Weile her ;)
Ohne die Erweiterung ist man iirc bei ner Maximalgröße von (blind geraten) 5 oder 20 (?) limitiert. Jedenfalls ist sie klein genug, um GL_POINTS nicht einzusetzen ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 18:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also ich vermute stark das diese Extension schon lange in OpenGL integriert ist. Vielleicht GL_ARB_point_parameters oder GL_ARB_point_sprite ?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 18:06 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
jup die letzte meinte ich... hm 2003... merkwürdig, ich kann mich noch erinnern als das neu war :)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 15 Queries | GZIP : On ]