Delphi Opengl Shader Problem

F.b

Lieutenant
Registriert
Feb. 2008
Beiträge
514
Hallo,
da ich mich zurzeit parallel sowohl mit Raytracing als auch mit Opengl mit Delphi beschäftige, viel mir bei Opengl die "schlechte" Beleuchtung doch sehr ins Auge. Also habe ich mittels einem einfachen Shader die Pixelgenaue Beleuchtung aus meinem Raytracer übernommen. Klappt soweit auch sehr gut, nur habe ich Probleme, das Programm mit dem Shader auf unseren Schulrechnern zum Laufen zu kriegen, besser: es geht nicht. Die GLSL-Version ist 1.1 und die GraKa der Rechner nen G41 OnBoard-Chip mit OpenGL 2.0- und ShaderModel4.0-Support. Hat jemand ne Idee, wieso es dort ohne Shader klappt, aber mit nicht?
Danke schonmal im vorraus;)
 
Wie sprichst du die OpenGL Schnittstelle an? Wenn du OpenGL 2.0 Funktionen, Strukturen etc. nutzt, aber auf dem Schulrechner nur OpenGL 1.0 oder ähnliches zur Verfügung hast, dann kannst du wahrscheinlich nur noch auf eine Freie Bibliothek aus dem Netz setzen, die dir die Verknüpfungen zu OpenGL 2.0 bereitstellt. Windows z.B. ist bei 1.1 oder so stehen geblieben und unterstützt erstmal von Haus aus nicht neuere Versionen inkl. neuerer Shadermodelle.

BTW: "Es geht nicht" ist keine konkrete Fehlermeldung eines wie auch immer gearteten Programms. Mehr Input wäre erforderlich, da du doch sicher eine Fehlermeldung o.ä. bekommst. Diese Meldung wäre äußerst interessant um das Problem näher eingrenzen zu können.

Aber, wie dem auch sei, es kann auch Bullshit sein, was ich hier geschrieben habe.
 
ja zu der fehlermeldung: normal wird bei der initialisierung eine meldung von glsl ausgegeben à la "vertex and fragment shader linked" oder eben "compilation error" oder so. auf den schulrechnern ist der string, welcher die message enthält, einfach komplett leer. danach ist das programmfenster einfach komplett weiß, also nicht das wie wenn ein compilerfehler aufgetreten ist, die objekte einfach nicht beleuchtet werden.
zur schnittstelle: ich nutze den header von delphigl.com. Bei der Unterstützung durch Windows weiß ich ehrlich gesagt nicht was du meinst. Und da die GraKa OpenGl 2.0 unterstützt, sollte dies kein Problem sein
 
Hast du mal dir glGetString(GL_EXTENSIONS) ausgeben lassen um sicherzustellen, dass auch wirklich alle nötigen Extensions/Funktionen zur Verfügung gestellt werden?
 
Zuletzt bearbeitet:
Also ich habe selber mal etwas mit OpenGL experimentiert. Zur Unterstützung mit Windows:
Windows unterstützt erstmal nur den Funktionsumfang bis V1.1. Alle weiteren Versionen mit deren neuen Funktionen, Strukturen etc. werden über Pointer angesprochen. Hierfür ist eine Wrapper Bibliothek/Headerdatei notwendig, die die entsprechenden Pointer ermittelt und somit den Zugang zu diesen Funktionen sicherstellt. Das Gute ist, dass bei der von dir verwendeten Header-Datei genau das gemacht wird.
Am Anfang initialisierst du ja hoffentlich mit einem Aufruf von "InitOpenGL;" den ganzen Kram. Damit das ganze aber funktioniert, reicht es nicht aus nur eine Grafikkarte mit der Unterstützung im Computer stecken zu haben, sondern es müssen auch die Hardware-Treiber diese Version unterstützen. D.h. Grafikkarte und Treiber müssen hierfür ausgelegt sein. siehe http://www.opengl.org/wiki/Getting_started und http://www.opengl.org/wiki/Getting_started#Accessing_OpenGL_functions

Wie Cry & Die schon schrieb, überprüfe die Version auf dem Zielrechner mit glGetString und schau ob da alle von dir verwendeten Funktionen mit dieser Version übereinstimmen. Siehe hierzu auch http://www.opengl.org/wiki/FAQ#How_do_I_tell_what_version_of_OpenGL_I.27m_using.3F

Ansonsten viel Erfolg!

BTW: Ist dein Raytracer Open Source? Bin selber sehr interessiert an dieser Materie und dabei mich selber da einzuarbeiten... Vorallem würde mich interessieren wie du das Testproblem löst, d.h. wie du vorgehst um mit hoher Geschwindigkeit herauszufinden, welches Primitive vom Strahl als erstes getroffen wurde.
 
Zuletzt bearbeitet:
ah danke für die aufklärung;).
da wochenende:D ist, werd ich das erst am montag testen können
ich hab meinen raytracer(welcher sich mittlerweile zum pathtracer gemausert hat) nicht veröffentlicht, sondern für meine facharbeit programmiert. wenn du interessiert bist, kann ich dir den sourcecode ja schicken(is in java geschrieben)
EDIT: hohe geschwindigkeit?^^ da ich keine beschleunigungsstruktur wie zB kd-bäume verwende, ist er recht langsam
 
Zuletzt bearbeitet:
Sehe gerade, dass wir schonmal über deinen Raytracer gesprochen hatten. Damals war es ein Refraktionsproblem. Und siehe da, ich hatte dir schonmal die Frage nach der Beschleunigungsstruktur gestellt. Man sieht, ich werde langsam alt und vergesslich. Egal. Nun aber auf dein Angebot würde ich sehr gerne zurückkommen. Also schau mal in dein Postfach, du hast Post. Ansonsten viel Erfolg mit deinem Shaderproblem. Hoffe du wirst es lösen können...

Viele Grüße
Rossibaer
 
Die Version von OpenGL scheint 2.0 zu sein. Da dass Programm den Shader akzeptiert und auch ausführt, wenn nur gl_FragColor = glFrontMaterial.diffuse, muss der Fehler im Shadercode liegen. Nur hab ich leider keine Ahnung, ob eins der Befehle/Variablentypen erst mit einer späteren Version hinzugefügt wurde. Ich hoffe ihr wisst da mehr als ich;)
Code:
//Vertex Shader
varying vec3 position;
varying vec3 normal; 
 
void main(void) 
{
  gl_Position		= gl_ModelViewProjectionMatrix * gl_Vertex;
  gl_FrontColor		= gl_Color;
  gl_TexCoord[0]	= gl_MultiTexCoord0; 
  normal		= normalize(gl_NormalMatrix * gl_Normal);
  position		= vec3(gl_ModelViewMatrix * gl_Vertex);
}


//Fragment Shader
varying vec3 position;
varying vec3 normal;

uniform int ActiveLights;
uniform int lighting;
 
void main(void) 
{
  if(lighting == 1) {
  vec3 lightDir;
  double attenFactor;
  vec3 eyeDir 			= normalize(-position);
  vec4 lightAmbientDiffuse 	= vec4(0.0,0.0,0.0,0.0);
  vec4 lightSpecular 		= vec4(0.0,0.0,0.0,0.0); 	
 
  // iterate all lights
  for (int i=0; i<ActiveLights; ++i)
  {
	// attenuation and light direction
	if (gl_LightSource[i].position.w != 0.0)
	{
		// positional light source
                // Weil die distance-Funktion ne Access-Violation verursacht hat,
                // berechne ich diese per Hand
		double dist	= sqrt(pow(gl_LightSource[i].position.x-
                position.x,2)+pow(gl_LightSource[i].position.y-
                position.y,2)+pow(gl_LightSource[i].position.z-
                position.z,2));
		lightDir	= normalize(gl_LightSource[i].position.xyz - position);
		attenFactor	= 1.0/(	gl_LightSource[i].constantAttenuation + 
					gl_LightSource[i].linearAttenuation * dist +
					gl_LightSource[i].quadraticAttenuation * dist * dist );
	}		
	else 
	{			
		// directional light source			
		attenFactor	= 1.0;			
		lightDir	= gl_LightSource[i].position.xyz;		
	} 		
	// ambient + diffuse		
	lightAmbientDiffuse 	+= gl_FrontLightProduct[i].ambient*attenFactor;		
	lightAmbientDiffuse 	+= gl_FrontLightProduct[i].diffuse *
        max(dot(normal, lightDir), 0.0) * attenFactor; 
	// specular		
	vec3 r 		= normalize(reflect(-lightDir, normal));
	lightSpecular 	+= gl_FrontLightProduct[i].specular * 
			      pow(max(dot(r, eyeDir), 0.0), gl_FrontMaterial.shininess) *
			      attenFactor;	
  } 	
  // compute final color		
  gl_FragColor 	= (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + 
  lightSpecular;
 
  float fog	= (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;	// Intensität berechnen 
  fog		= clamp(fog, 0.0, 1.0);  				// Beschneiden 
  gl_FragColor 	= mix(gl_Fog.color, gl_FragColor, fog);  		// Nebelfarbe einmischen 
  }
  else {
   gl_FragColor = gl_FrontMaterial.diffuse;
  }
}
 
Zuletzt bearbeitet:
Sorry F.b. ich muss da leider passen... Ich würde aber an deiner Stelle mal die Specs von OpenGL 2.0 und dessen Shaderlanguage nachlesen und vielleicht jeden Aufruf, d.h. Funktionen, Variablen, Konstanten mit der Spec abgleichen um vielleicht einen Unterschied entdecken zu können...

siehe GLSL Specification
 
Zuletzt bearbeitet:
Oh man. Es hat einfach aus einem Grund nicht funktioniert: im shader-code müssen bei glsl 1.1 alle Zahlen, welche ganzzahlig sind, trotzdem nen '.0' angefügt bekommen...
Nächstes Problem: Schule davon überzeugen, sich bessere GraKa's anzuschaffen, damit es nicht mit 10 FPS rumruckelt^^
 
Also bist du mittlerweile so weit in Echtzeit (wenn auch nur bei 10FPS) zu raytracen?

Habe mir im übrigen deinen Java Code endlich mal angesehen. Mein lieber Scholli, sieht schon nett aus und so langsam ist es nun auch wieder nicht. Jedoch hast du bisher nur sehr einfache Objekte (3 Kugeln 2 Ebenen und nen Licht drin) Bei komplexen Sachen wirds dann sicher schnell im Minutenbereich landen ohne entsprechende Strukturen. Egal, ich schau mir das mal im Detail genauer an. Kann nur sagen, bisher ist der Code ok. Manchmal verwendest du halt brutal kurze Variablenbezeichnungen, was es recht schwer macht die Bedeutung zu erkennen.

Ach nochwas, wenn du noch einen Tipp für zukünftige Projekte haben willst, dann verwende niemals deutsche Umlaute in Variablen/Funktionen usw.

Grund: NetBeans hat sich standhaft geweigert, den Code zu kompilieren, weil er aus "ö" von der Variable "höhe" ein nicht druckbares Zeichen gemacht hat. Beim Öffnen der Datei kam dann, so ein Gedöhns das wegen UTF8 die Datei nicht richtig gelesen werden kann. Nunja das Problem war recht schnell gelöst, aber dennoch hatte ich ein mulmiges Gefühl dabei im mir fremden Code das "ö" durch "oe" zu ersetzen. Ansonsten denke ich, dass ich mit dem Code ganz gut zurecht komme. Vieles kommt mir schon allein durch meine eigenen Sachen sehr bekannt vor. Raytracer scheinen halt irgendwie sehr ähnlich aufgebaut zu sein... Danke nochmal das du mir den Code geschickt hast.
 
Zuletzt bearbeitet:
Mein Raytracer mit 10 FPS:p schön wärs^^ nein ich meine meine (zugegebenermaßen sehr rudimentäre) 3D-Engine auf Basis von OpenGL, wegen welcher ich den Thread überhaupt gestartet hatte. Aber das liegt nur an den lahmen Intel-Grafikchips.
Ja, das mit der breite/höhe in der Main-Class ist natürlich nicht gut und war eig auch nur als Übergangslösung gedacht. Die Abkürzungen l und ls sind halt aus Faulheit entstanden^^
Der Tracer unterstützt zusätzlich noch Dreiecke, welche gar nicht so langsam berechnet werden wie ich ursprünglich dachte. Ne Beispielszene plus Bild(17 Sek. pro Sample ist verdammt lang^^) is im Anhang.
 

Anhänge

  • Beispielszene1.txt
    Beispielszene1.txt
    7,7 KB · Aufrufe: 239
  • Example4.png
    Example4.png
    313,5 KB · Aufrufe: 195
Wie erzeugst du die Szene, etwa per Hand oder läßt du dir da eine fertige Datei aus Maya, Blender (...) generieren? Ich habs jetzt so gemacht das nen Export Script in Python mir eine (fast) komplette Szene aus Blender als C# Klasse raus lädt. Diese binde ich dann später bei meinem Raytracer ein. Aber ich bin noch sehr weit entfernt von dem was du bisher hast. Alles noch Basics mit denen ich mich rumschlage...

Wenn du Interesse hast kann ich das Script so modifizieren das es dir nen Java Code raus gibt...

Ach nochwas, mit welcher IDE bearbeitest du das Projekt? Ist es Eclipse? Ich hatte geraten und mal NetBeans verwendet, jedoch kam es mit den JAR Dateien nicht so zurecht. Vielleicht auch wegen meiner Unerfahrenheit, weil ich bisher mit Java nichts zu tun hatte, außer paar Codeschnipsel zu lesen und dafür reichte bisher auch ein Notepad.
 
Zuletzt bearbeitet:
Also als IDE verwende ich Eclipse. Zurzeit wird die Szene noch per Hand im Code erzeugt, ich bin jedoch grad am portieren meines Modelloaders von Delphi zu Java
 
Zurück
Oben