# Rechenzeit zum Rendern



## ArtjomZab (24. Apr 2008)

Ich hab eine 3DBiblithek zum Darstellen und Bewegen von 3D-Gittermodellen entwickelt.
Nur habe ich das Problem, dass bei Gns
Bodenlose sinkt.

Ist für das Transformieren von Vertices generell die CPU verantwortlich oder
lässt sich hier mit java die Resource Grafikkarte nutzen?


----------



## Soulfly (24. Apr 2008)

Da wirst du nichts machen können! Die Darstellung wird wohl beschleunigt werden, falls du Swing benutzt und Beschleunigung grundsätzlich aktiviert ist. Aber das berechnen und alles andere wird nicht beschleunigt.

Warum benutzt du nicht einfach JOGL oder LWJogl packst da dein Polygonmodel rein und EIN EINZGIER Befehl,

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

eh voilá Wireframe.


----------



## EgonOlsen (24. Apr 2008)

ArtjomZab hat gesagt.:
			
		

> Nur habe ich das Problem, dass bei Gns
> Bodenlose sinkt.


Gns? Da fehlt doch irgendwas. Wann sinkt was?


----------



## Evil-Devil (25. Apr 2008)

Was sind denn bitte Gns?

@Transformation: Wenn der PC über eine Grafikkarte mit Shadermodel 2 und höher verfügt, kann man die Transformation über Shader laufen lassen, aber das lässt sich nur mit DirectX oder OpenGL ansteuern. Kenne jedenfalls keine andere unter Java verfügbare hardwarenahe API die Shader direkt ansteuern kann.


----------



## ArtjomZab (25. Apr 2008)

Gns bedeutet Frames


----------



## EgonOlsen (25. Apr 2008)

OK, dann heißt es also:



> Nur habe ich das Problem, dass bei Frames Bodenlose sinkt.



...verstehe ich immer noch nicht...???


----------



## ArtjomZab (25. Apr 2008)

Wie kann ich die Shader nutzen. Über DX oder OpenGL? Und wie binde ich die in Java ein?


----------



## ArtjomZab (25. Apr 2008)

Sorry, ich meine natürlich, dass bei mehr als 10000 Vertices die FPS ins Bodenlose sinken!


----------



## Evil-Devil (25. Apr 2008)

Hmm, >10.000 Vertices sind nun wirklich nicht viel. Selbst in 2D sollten da >30 fps drin sein. Benutzt du irgendwelche Culling Algos um nur die wirklich sichtbaren Vertices anzeigen zu lassen oder plain Bruteforce Rendering?

@DX/OGL: DX gibt es in Java3D, Open GL in Java3D, JOGL, LWJGL. Letzteres hat in naher Zukunft auch ein DX9/10 Binding =)


----------



## ArtjomZab (25. Apr 2008)

Ne, culling nutz ich nicht.

Wie greift den java auf die Graka zu. Baut java sich irgendwie eine Schnittstelle im Grafiktreiber?
Muss ich mir dafür das java3D packet integrieren oder ist das schon bei java dabei?

Aus Erfahrung, wie is die performance unter java bei dx?


----------



## Evil-Devil (25. Apr 2008)

In wie weit Swing Hardware beschleunigt ist weiß ich nicht.

Java3D, JOGL, LWJGL sind jeweils eigene APIs die man zusätzlich einbinden muss.

Perfo unter DX? Keine Ahnung. Ich arbeite derzeit nur mit OpenGL unter Java und da reicht mir die perfo bisher.

@Culling: Dann einbauen


----------



## EgonOlsen (25. Apr 2008)

ArtjomZab hat gesagt.:
			
		

> Sorry, ich meine natürlich, dass bei mehr als 10000 Vertices die FPS ins Bodenlose sinken!


Wo genau ist bodenlos? Also in jPCT kann ich im Software-Modus ein Objekt mit 12600 Vertices bei 800*600er Auflösung bildschirmfüllend und alle Vertices sichtbar auf diesem völlig vergurkten uralt P4 @ 2.4Ghz bei etwa 40fps darstellen. Wobei ich die Linien allerdings selber zeichne und dies nicht von Swing/AWT erledigen lasse.
Wenn du weit darunter liegst, solltest mal deine Berechnungen checken. Z.B. ist es nicht sinnvoll, jeden Vertex durch 3 Methoden zu schleusen, um ihn zu transformieren oder ähnliches.


----------



## ArtjomZab (26. Apr 2008)

Für jede Bewegung berechne ich eine Transformationsmatrix. Diese
wende ich dann auf jeden zu transformierenden Vektor an. Die Vektoren verbinde ich dann über 
drawLine(x,y), fertig. Auf meinem AMD 3200+ (2.2ghz) habe ich bei 30000 vertices nicht mal 15 frames..!?!?
Wahrscheinlich sind meine Algorithmen nicht effizient genug. Ich werde später hier mal den Quelltext reinstellen, hab ihn
gerade nicht zur hand.

WIe ist eigentlich die Performance wenn man in java mit opengl 3d szenen rendert?


----------



## Evil-Devil (27. Apr 2008)

Dürfte wesentlich besser sein.

Dies hier hat 12.238 Vertices bestehend aus 4010 Polys. Einfaches Bruteforce Rendern über eine DisplayListe. In Bewegung immer noch ~250fps auf meiner Oldi Kiste ^^


----------



## lohr (28. Apr 2008)

Sieht mal richtig schick ist 
Ist das von dir?


----------



## Lulumann6 (28. Apr 2008)

ich glaube nicht das der das selber gemacht hat, dass kommt warscheinlich ursprünglich von ati, oder meinst du nicht^^


----------



## Evil-Devil (28. Apr 2008)

Doch, habs selbst gebastelt. Ist eine der Lektionen aus dem Maya Tutorial, in dem man lernt mit den Werkzeugen umzugehen. Und irgendeine Textur muss ich dem Teil doch geben


----------



## ArtjomZab (29. Apr 2008)

Also, ich möchte noch einmal zu meinem Performance-Problem zurückkehren,
welches bei meiner 3D-Bibliothek auftritt.Also hier einmal die Klasse, die das 
3D-Model repräsentiert:


```
package Bib3D;

/*
 * Autor: Artjom Zabelin  
 *  Facharbeit Informatik LK 12.2 T. Selms 
 * 
 * Model3D reprÃ¤sentiert die mathematische bzw. geometrische
 * Beschreibung eines Drahtgittermodells.
 * 
 * Es stellt die Methode transform zum ÃœberfÃ¼hren der
 * 3D-Vektoren in 2D-Vektoren zur VerfÃ¼gung und reduziert
 * die Anzahl der zu zeichnenden Linien auf das Wesentliche.
 */ 

import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Model3D
{
    public String Name;
    
    public ModelHandler ModelHandler;
    
    public Matrix3D matrix;
    
    public boolean transformed;
        
    public Model3D()
    {
        this.matrix = new Matrix3D();
        this.matrix.rotierenX(0);
        this.matrix.rotierenZ(0);  
        this.matrix.skalieren(1);        
    }
       
    public Model3D(File file) throws FileNotFoundException, IOException
    {
        this.matrix = new Matrix3D();
        this.matrix.rotierenX(0);
        this.matrix.rotierenZ(0);  
        this.matrix.skalieren(1);
        
        this.m_setName(file.getName());
        this.createModelHandler(this);
        this.loadModel(file);
    }
    
    public void m_setName(String pName)
    {
        this.Name = pName;
    }
    
    public void createModelHandler(Model3D Model)
    {
        this.ModelHandler = new ModelHandler(Model);
    }
    
    public void loadModel(File file) throws FileNotFoundException, IOException
    {
        this.ModelHandler.loadModelData(file);
    }
        
    public void transform()
    {
        if (this.transformed || this.ModelHandler.Buffer.nVertices <= 0)
        {
	    return;
        }
	if (this.ModelHandler.Buffer.TBuffer == null ||
            this.ModelHandler.Buffer.TBuffer.length < 
            this.ModelHandler.Buffer.nVertices * 3)
        {
	    this.ModelHandler.Buffer.TBuffer = new int[this.ModelHandler.Buffer.nVertices*3];
        }
        
	this.matrix.transform(this.ModelHandler.Buffer.VBuffer, this.ModelHandler.Buffer.TBuffer, this.ModelHandler.Buffer.nVertices);
	this.transformed = true;
    }

   public void sortSurface(int s[], int l, int r)
   {
      int li = l;
      int ri = r;
      int pE;
      
      if(r > l)
      {
         pE = s[ (l + r)/2];
         
         while(li <= ri)
         {
            while((li < r) && (s[li] < pE))
               ++li;
            
            while((ri > li) && (s[ri] > pE))
               --ri;

            if(li <= ri)
            {
              this.changeElements(s, li, ri);
               ++li;
               --ri;
            }
         }

         if(l < ri)
         {
           this.sortSurface(s, l, ri);
         }


        if(li < r)
        {
            this.sortSurface(s, li, r);
        }
      }
   }

   public void changeElements(int s[], int x, int y)
   {
      int f;
      f = s[x];
      s[x] = s[y];
      s[y] = f;
   }
  
   public void reduce() 
   {
	int frontier = this.ModelHandler.Buffer.nLines;
	int nL[] = this.ModelHandler.Buffer.LBuffer;
        
	this.sortSurface(this.ModelHandler.Buffer.LBuffer, 0,
                         this.ModelHandler.Buffer.nLines - 1);        
	int f = 0;
	int vV1 = -1;
        
	for (int x = 0; x < frontier; x++) 
        {
	    int v1 = nL[x];
            
	    if (vV1 != v1) 
            {
		nL[f] = v1;
		f++;
	    }     
            
	    vV1 = v1;
	}       
	this.ModelHandler.Buffer.nLines = f;
    }       
}
```


----------



## ArtjomZab (29. Apr 2008)

Hier einmal die Klasse die das ganze zeichnet:


```
package Bib3D;

/*
 * Autor: Artjom Zabelin, Februar 2008
 *  Facharbeit Informatik LK 12.2 T. Selms
 * 
 * GraphicSurface stellt einen minimalen Grafikkontext her. 
 * Sie erbt JPanel. 
 * Eine Klasse, welche etwas zeichnen mÃ¶chte, kann GraphicSurface
 * erben. Sie muss dann auch die abstrakte Methode 'render' implementieren,
 * welche das Grafikobjekt 'Graphics2D g2' zu VerfÃ¼gung stellt.
 * 
 * GraphicSurface ist ein JPanel. Damit ist auch jeder Erbe ein
 * JPanel und kann somit 'Components' leicht angefÃ¼gt werden.
 */

import java.awt.*;
import javax.swing.*;

public abstract class GraphicSurface extends JPanel
{    
    /*
     * Einige QualitÃ¤tseinstellungen... 
     */
    public Object Antialiasing = RenderingHints.VALUE_ANTIALIAS_ON;
    public Object RenderingQuality = RenderingHints.VALUE_RENDER_SPEED;
    public Object TextAntialiasing = RenderingHints.VALUE_TEXT_ANTIALIAS_ON; 
    
    public boolean clearSurface = true;
    private boolean clearOnce;
    
    private Toolkit toolkit;
    
    public GraphicSurface()
    {
        this.toolkit = getToolkit();
        this.setBackground(new Color(255,255,255));
    }
    
    public abstract void render(int w, int h, Graphics2D g2);
    
     /*
     * Einige QualitÃ¤tseinstellungen... 
     */
    public void setAntialiasing(boolean value) 
    {
       this. Antialiasing = value 
            ? RenderingHints.VALUE_ANTIALIAS_ON
            : RenderingHints.VALUE_ANTIALIAS_OFF;
    }

     /*
     * Einige QualitÃ¤tseinstellungen... 
     */
    public void setTextAntialiasing(boolean value)
    {
        this.TextAntialiasing = value 
            ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
            : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
    }
    
     /*
     * Einige QualitÃ¤tseinstellungen... 
     */
    public void setRenderingQuality(boolean value)
    {
        this.RenderingQuality = value
            ? RenderingHints.VALUE_RENDER_QUALITY
            : RenderingHints.VALUE_RENDER_SPEED;
    }
    
     /*
     * Liefert ein Graphics2D Objekt auf Basis eines Graphics Objekts.
     */
    public Graphics2D createGraphics2D(int width, int height, Graphics g) 
    {

        Graphics2D g2 = (Graphics2D) g;
        
        g2.setBackground(getBackground());
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, Antialiasing);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingQuality);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, TextAntialiasing);

        if (this.clearSurface || this.clearOnce) 
        {
            g2.clearRect(0, 0, width, height);
            this.clearOnce = false;
        }

        return g2;
    }

    /*
     * ÃœberfÃ¼hrt Graphics int Graphics2D und zeichnet...
     */
    @Override
    public void paint(Graphics g) 
    {
        Dimension d = getSize();
        
        Graphics2D g2 = createGraphics2D(d.width, d.height, g);
        
        this.render(d.width, d.height, g2);
        
        g2.dispose();      
    }    
}
```


----------



## ArtjomZab (29. Apr 2008)

Der ModelLayer ist dann das gezeichnete Model


```
package Bib3D;

/*
 * Autor: Artjom Zabelin  
 *  Facharbeit Informatik LK 12.2 T. Selms 
 *
 * Der ModelLayer ist eine Commponent und zeichnet das Model.
 */

import java.awt.*;
import java.awt.font.*;
import java.io.*;

public class ModelLayer extends GraphicSurface
{
    public Model3D Model;    
    
    public Matrix3D Matrix1, Matrix2;
        
    public ModelLayer(File file) throws FileNotFoundException, IOException
    {
        this.Model = new Model3D(file);
        
        this.Matrix1 = new Matrix3D();
        this.Matrix2 = new Matrix3D();
        
        this.Model.reduce();
    }
    
    public void renderInf(int w, int h, Graphics2D g2)
    {
        FontRenderContext FRC = g2.getFontRenderContext();
       
        Font font1 = new Font("Verdana", Font.PLAIN, w/40);
        Font font2 = new Font("Verdana", Font.PLAIN, w/45);
       
        TextLayout tl = new TextLayout("Model-Information", font1, FRC);
        TextLayout tl2 = new TextLayout("Name: " + this.Model.Name, font2, FRC);
        TextLayout tl3 = new TextLayout("Vertices: " + this.Model.ModelHandler.Buffer.nVertices, font2, FRC);
        TextLayout tl4 = new TextLayout("Lines: " + this.Model.ModelHandler.Buffer.nLines, font2, FRC);
       
        tl.draw(g2, (float)(w/30), (float)(h/ (float)1.2));
        tl2.draw(g2, (float)(w/30), (float)(h/ (float)1.14)); 
        tl3.draw(g2, (float)(w/30), (float)(h/ (float)1.08)); 
        tl4.draw(g2, (float)(w/30), (float)(h/ (float)1.03));
    }
        
    public void renderModel(int w, int h, Graphics2D g2)
    {	                           
        if (this.Model.ModelHandler.Buffer.VBuffer == null ||
            this.Model.ModelHandler.Buffer.VBuffer.length <= 0)
        {
	    return;
        }
        
	this.Model.transform();
         
	int bo = this.Model.ModelHandler.Buffer.nLines;
	int lb[] = this.Model.ModelHandler.Buffer.LBuffer;
	int vb[] = this.Model.ModelHandler.Buffer.TBuffer;
        
	if (bo <= 0 || this.Model.ModelHandler.Buffer.VBuffer.length <= 0)
        {
	    return;
        }
        
	for (int i = 0; i < bo; i++) 
        {
	    int T = lb[i];
	    int v1 = ((T >> 16) & 0xFFFF) * 3;
	    int v2 = (T & 0xFFFF) * 3;
	  
	    g2.setColor(new Color(0,0,0));
	    g2.drawLine(vb[v1], vb[v1 + 1],
		       vb[v2], vb[v2 + 1]);
	}
    }
    
    @Override
    public void render(int w, int h, Graphics2D g2) 
    {   
       this.renderInf(w, h, g2);
       g2.translate(w/2, h/2);
       this.renderModel(w, h, g2);
    }

}
```


----------



## ArtjomZab (29. Apr 2008)

Ich wollte euch nicht unbeding den Quelltext zumuten und wollte einfach das Klassen
diagramm hier  posten. Muss ich dieses dafür erst irgendwo hochladen?


----------



## Illuvatar (30. Apr 2008)

Wenn du dich anmeldest, hast du unter "Eigene Dateien" eine gewisse Menge Speicherplatz zur Verfügung.


----------



## EgonOlsen (1. Mai 2008)

ArtjomZab hat gesagt.:
			
		

> Für jede Bewegung berechne ich eine Transformationsmatrix. Diese
> wende ich dann auf jeden zu transformierenden Vektor an. Die Vektoren verbinde ich dann über
> drawLine(x,y), fertig. Auf meinem AMD 3200+ (2.2ghz) habe ich bei 30000 vertices nicht mal 15 frames..!?!?
> Wahrscheinlich sind meine Algorithmen nicht effizient genug. Ich werde später hier mal den Quelltext reinstellen, hab ihn
> gerade nicht zur hand.


Lass doch mal das eigentliche Zeichnen weg. Nützt nicht viel, wenn du an allen möglichen Stellen drehst und am Ende lag es schlicht an der Ausgabegeschwindigkeit.


----------

