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

Aktuelle Zeit: Fr Jul 18, 2025 12:10

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 68 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4, 5  Nächste
Autor Nachricht
BeitragVerfasst: Fr Sep 24, 2010 09:09 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
kann mir einer erklären warum das so hier nicht funktioniert?
Code:
glUniform4f(glGetUniformLocation(shader.ProgramObject,  PAnsiChar('LampColor'+inttostr(i))), LampColor[0], LampColor[1], LampColor[2], 1);


haut nur so hin

Code:
var
 idx: AnsiString;
...
idx:='LampColor'+inttostr(i);
glUniform4f(glGetUniformLocation(shader.ProgramObject,  PAnsiChar(idx)), LampColor[0], LampColor[1], LampColor[2], 1)


Ist doch aber eigentlich das gleiche oder? Habe Delphi 2010...


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 24, 2010 09:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Ist doch aber eigentlich das gleiche oder?

Nein. Gut ich will nicht behaupten mich mit Delphi auszukennen, aber in der ersten Variante erzeugst du einen String und gibst einen Pointer drauf an glGetUniformLocation. Der String wird aber nur temporär erzeugt wird und nicht in einer Variable gespeichert. D.h. es wird einfach nur
Code:
PAnsiChar('LampColor'+inttostr(i)))

ausgewertet und der String wieder freigegeben/zerstört. Erst dann wird glGetUniformLocation aufgerufen, mit einem Pointer auf einen mittlerweile ungültigen String.

In der zweiten Variante bleibt der String bis zum Ende deiner Methode gültig.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 24, 2010 19:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 04, 2008 23:15
Beiträge: 39
Wohnort: Oberösterreich
Programmiersprache: ObjPas, C, DivASM
Thmfrnk hat geschrieben:
Ist doch aber eigentlich das gleiche oder? Habe Delphi 2010...

Nein. IntToStr gibt in Delphi2009/10 einen WideString zurück. Da aber bei einer Redeklaration zu PAnsiChar keine Konvertierung durchgeführt wird, wird der Name falsch übergeben.

Der zweite Fall funktioniert, da bei der Zuweisung des String auf "idx" eine Konvertierung auf AnsiString durchgeführt wird.

So funktioniert es ohne eine temporäre Variable. :wink:
Code:
glGetUniformLocation(shader.ProgramObject,  PAnsiChar('LampColor' + AnsiString(IntToStr(i))))


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 24, 2010 21:29 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
mercie, wie ich den Unicodescheiss hasse :D


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 07, 2010 21:17 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
sooo meine Texturprojektion haut ja jetzt hin. Das Problem ist lediglich das nicht nur auf die Vorderseite eines Objektes projeziert wird, sondern auf auf der Rückseite, was ja physikalisch unmöglich ist.. Weiß jemand wie ich das Prolbem lösen kann?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 07, 2010 21:31 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Nun wenn du weißt wo der Lichtquelle ist und wo das gerade gerenderte Fragment ist und du zudem die Normale kennst, kannst du doch leicht feststellen ob die Normale zur Lichtquelle zeigt oder nicht und entsprechend reagieren.

Letztlich wirst du aber eine echte Schattenberechnung wollen, da wären dann ShadowMap bzw. StencilShadow die Schlagworte ;)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 07, 2010 21:46 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
wie würde dann dann aussehen?
im Vertex:
Code:
 normal = gl_NormalMatrix * gl_Normal;
 vec4 posEye =  gl_ModelViewMatrix * gl_Vertex;
 lightDir = vec3(meineLampe[0].position.xyz - posEye.xyz);


im Fragment:
Code:
  vec3 N = normalize(normal);
  vec3 L = normalize(lightDir);
...
  if (Darfichprojezieren) {
...
}



so und was nun?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 07, 2010 21:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Code:
if (dot(N,L) >= 0) {

oder
Code:
if (dot(N,L) < 0) {

je nach dem wie deine Normalen sind. Diesen Wert musst du aber sowieso für die Beleuchtung ausrechnen, oder nicht? Ist ein stink normaler Per-Pixel-Light-Shader....mit dem Unterschied das du mehrere Lichtquellen hast.

Es ist zu empfehlen posEye an den Fragmentshader zu geben und erst im Fragmentshader meineLampe[0].position.xyz - posEye.xyz zu berechnen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Okt 07, 2010 22:11 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
kann ich denn das

normal = gl_NormalMatrix * gl_Normal;

auch so im Fragmentshader machen?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 08:37 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
also da tut sich nix. Bei <0 seh ich garkeine Projektion mehr und bei >=0 siehts aus wie vorher...

hier nochmal meine beiden shader:
Code:
#version 120
const int max_lights = 7;

uniform mat4 TexGenMats[max_lights];
uniform mat4 InvViewMat;

varying vec4 projCoord[max_lights];
varying vec4 posEye;
varying vec3 normal;
void main()
{   

 posEye =  gl_ModelViewMatrix * gl_Vertex;

 vec4 posWorld = InvViewMat * posEye;
   
   for (int i=0; i < max_lights; ++i) {
     projCoord[i] = TexGenMats[i] * posWorld;   
   }
   
   normal = gl_NormalMatrix * gl_Normal;
   
   gl_TexCoord[0] = gl_MultiTexCoord0;   
   
   gl_Position = ftransform();      
}


Code:
#version 120
const int max_lights = 7;

uniform sampler2D projMap0;
uniform sampler2D projMap1;
uniform sampler2D projMap2;
uniform sampler2D projMap3;
uniform sampler2D projMap4;
uniform sampler2D projMap5;
uniform sampler2D projMap6;
uniform sampler2D projMap7;
uniform sampler2D Texture0;

uniform vec4 LampColors[max_lights];       //Lichtfarbe und intensität
uniform int GoboIndex[max_lights];          //gibt an welcher Gobo Sampler projeziert werden soll
uniform vec4 AmbientColor;               //Umgebungsfarbe
uniform vec4 LightPos[max_lights];          //Lampenpositionen für evtl. weitere Berechnungen

varying vec4 projCoord[max_lights];
varying vec4 posEye;
varying vec3 normal;

void main (void)
{
 vec4  ProjMapColor = vec4(0.0, 0.0, 0.0, 0.0); 
 vec4  final_color = AmbientColor;   
 
 
 vec3  N = normalize(normal);
 vec3  L;
 vec3  lightDir;
 //Projektion für jede Lampe 
   for (int i=0; i <= max_lights; ++i)
  if (GoboIndex[i]>=0)
   {
     lightDir = vec3(LightPos[i].xyz - posEye.xyz);
    L = normalize(lightDir);
    if (dot(N,L)>=0)
     if(projCoord[i].q<0.0) {   
           
       if (GoboIndex[i]==0) {
               ProjMapColor = texture2DProj(projMap0, projCoord[i])* LampColors[i];
               }   else
       if (GoboIndex[i]==1) {      
               ProjMapColor = texture2DProj(projMap1, projCoord[i])* LampColors[i];
               } else             
       if (GoboIndex[i]==2) {
               ProjMapColor = texture2DProj(projMap2, projCoord[i])* LampColors[i];
               } else            
       if (GoboIndex[i]==3) {
               ProjMapColor = texture2DProj(projMap3, projCoord[i])* LampColors[i];         
               } else
       if (GoboIndex[i]==4) {
               ProjMapColor = texture2DProj(projMap4, projCoord[i])* LampColors[i];         
               } else
       if (GoboIndex[i]==5) {
               ProjMapColor = texture2DProj(projMap5, projCoord[i])* LampColors[i];         
               } else
       if (GoboIndex[i]==6) {
               ProjMapColor = texture2DProj(projMap6, projCoord[i])* LampColors[i];         
               } else
       if (GoboIndex[i]==7) {
               ProjMapColor = texture2DProj(projMap7, projCoord[i])* LampColors[i];         
               }       
    final_color += ProjMapColor;
   
    }
  }
  gl_FragColor =  final_color * texture2D(Texture0, gl_TexCoord[0].xy);         
}


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 08:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Für die Normale ist das nicht nötig, die kannst du auch im Vertexshader transformieren. Vom Prinzip geht das aber auch im Fragmentshader wenn du unbedingt willst.

Wenn ich es mir recht überlege kann auch
Zitat:
lightDir = vec3(meineLampe[0].position.xyz - posEye.xyz);

im Vertexshader bleiben. Ich hab da gestern Unsinn erzählt, dachte irgendwie das würde Probleme mit der Interpolation geben wenn das Polygon die Lichtquelle schneidet. Aber es ist natürlich das gleiche:
Zitat:
light - [(1-t)*p1 + t*p2]
= (1-t)*light + t*light - (1-t)*p1 - t*p2
= (1-t)*(light-p1) + t*(light-p2)

Die Probleme wenn das Polygon die Lichtquelle schneidet gibt es sowieso, weil dann lightDir 0 wird und du nicht mehr Normalisieren kannst. Sorry, war einfach zu spät gestern ;)

Übrigens ist der Variablename posEye total irreführend.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 08:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
also da tut sich nix. Bei <0 seh ich garkeine Projektion mehr und bei >=0 siehts aus wie vorher...

Ist den die Position der Lichtquellen im gleichen Koordinatensystem wie posEye? Vielleicht posWorld statt posEye ?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 08:58 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
und was soll ich ändern? Steige durch deine Formel net so wirklich durch..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 09:31 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
halt, warte ich glaub ich verwechsele das jetzt mit weiteren objekten hinter der projektion... Ich glaube
da hilft mir wirklich nur eine Schattenberechnung... könnt ich die denn einfach in meinen aktuellen Shader integriere?

Ich weiß ich brauch irgendwie die Tiefeninformationen.. Ich will jedoch ungern für jeden Projektor meine Szene nochmal rendern.. Aktuell Render ich für 7 Lichtquellen 1x die Szene..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Okt 08, 2010 09:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Ich weiß ich brauch irgendwie die Tiefeninformationen.. Ich will jedoch ungern für jeden Projektor meine Szene nochmal rendern..

Du hast die Wahl zwischen ShadowMaps und StencilVolumen. Bei ShadowMaps musst du die Szene aus der Perspektive jeder Lichtquelle rendern und du benutzt dann quasi den Z-Buffer als ShadowMap wenn du die eigentliche Szene renderst.

StencilVolumen funktioniert anders. Dort baust du das Volumen des Schattens als Geometrie nach und führst dann mit Hilfe des Stencil-Buffers einen Inside-Test (*) für diese Volumen aus. Das geht natürlich extrem auf die Füllrate, weil das Volumen eine große Fläche hat. Zudem ändert sich die Geometrie des Volumens immer wenn sich irgendwas bewegt.

(*) Ausgehend vom aktuellen Pixel schießt du einen Strahl in eine beliebige Richtung und zählst die Ein- und Austritte aus dem Volumen. Wenn die Anzahl ungerade ist bist zu im Volumen. Sowas geht mit dem Stencil-Buffer ziemlich gut.

_________________
Yeah! :mrgreen:


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 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 ]