# 1x Punktlicht auf 5 Objekte benutzen



## JavaKing (16. Sep 2008)

Ich habe 5 Würfel und diese möchte ich mit einem Spotlicht "markieren".
Das heisst ich drücke die Taste "1" dann soll ein Spotlicht auf den Würfel 1 fallen. Drücke ich wieder "1" soll das Spotlich deaktivert werden.
Dies möchte ich mit allen 5 Würfeln umsetzen. Leider verstehe ich nicht warum mein unten gezeigter Source Code nicht funktioniert (gl.glDisable(GL_LIGHT1); ) fehlt noch, müsste meines Erachtens bei
if (lockedWuerfel[0]1=1){gl.glDisable(GL_LIGHT1);} mit rein, leider funktioniert ja noch nichtmal das ich alle 5 Würfel mit Spotlicht beleuchten kann. :-(




```
public void init(GLAutoDrawable drawable){

       gl.glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
       
       gl.glEnable(GL_LIGHTING);
       gl.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, FloatBuffer.wrap(new float[] { 1.0f,1.0f, 1.0f, 1}));
       gl.glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, FloatBuffer.wrap(new float[] { 1.0f }));
       // Lichtquelle aktivieren

       gl.glEnable(GL_NORMALIZE);  // Normalisiert das Licht
       gl.glEnable(GL_LIGHT2);  // Normalisiert das Licht

       // Licht 1
       gl.glLightfv(GL_LIGHT1, GL_POSITION, FloatBuffer.wrap(new float[] { 0,0,4 ,1 })); // Punkt
       gl.glLightfv(GL_LIGHT1, GL_AMBIENT, FloatBuffer.wrap(new float[] { 1.0f, 1.0f, 1.0f, 1} ));
       gl.glLightfv(GL_LIGHT1, GL_DIFFUSE, FloatBuffer.wrap(new float[] { 1.0f, 1.0f, 1.0f, 1} ));
       gl.glLightfv(GL_LIGHT1, GL_SPECULAR, FloatBuffer.wrap(new float[] { 1.0f, 1.0f, 1.0f, 1}));
       gl.glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 0 );
       gl.glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 4.5f);      

       gl.glLightfv(GL.GL_LIGHT2, GL.GL_POSITION, FloatBuffer.wrap( new float[] { 5.0f, -4.0f, 5.0f, 1.0f}));
       gl.glLightfv(GL.GL_LIGHT2, GL.GL_AMBIENT, FloatBuffer.wrap(new float[]{1,1,1, 1f}));
       gl.glLightfv(GL.GL_LIGHT2, GL.GL_DIFFUSE, FloatBuffer.wrap(new float[] { 1, 1,1, 1f }));
       gl.glLightfv(GL.GL_LIGHT2, GL.GL_SPECULAR, FloatBuffer.wrap(new float[] {1, 1, 1, 1f }));  
}
```



```
private void drawScene(GL gl, boolean select){
            gl.glEnable(GL.GL_LIGHT1);
            if (lockedWuerfel[0]==1){
            light_x = -2.65f;//links rechts
            light_y = -0.76f;//oben unten
            }
            else if(lockedWuerfel[1]==1){
            light_x = -1.6f;//links rechts
            light_y = 0.50f;//oben unten
            }
            else if(lockedWuerfel[2]==1){
            light_x = -0.5f;//links rechts
            light_y = -0.76f;//oben unten
            }
            else if(lockedWuerfel[3]==1){
            light_x = 0.65f;//links rechts
            light_y = 0.50f;//oben unten
            }
            else if(lockedWuerfel[4]==1){
            light_x = 1.75f;//links rechts
            light_y = -0.76f;//oben unten
            }

gl.glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x,light_y,light_z, 1 })); // Punkt   
}
```



```
public void keyPressed(KeyEvent evt) {
      //markieren der Würfel zum späteren selektieren der Auswahl
      if (evt.getKeyCode() == KeyEvent.VK_1) {
  
          if (lockedWuerfel[0]==1) 
            {
                lockedWuerfel[0]=-1;
            }
            else
            {
                lockedWuerfel[0]=1;
            }
        }
     
      if (evt.getKeyCode() == KeyEvent.VK_2) {
            if (lockedWuerfel[1]==1) 
            {
                lockedWuerfel[1]=-1;
            }
            else
            {
               lockedWuerfel[1]=1;
            }
         }
      
      if (evt.getKeyCode() == KeyEvent.VK_3) {
            if (lockedWuerfel[2]==1) 
            {
                lockedWuerfel[2]=-1;
            }
            else
            {
                lockedWuerfel[2]=1;
            }
         }
      
      if (evt.getKeyCode() == KeyEvent.VK_4) {
            if (lockedWuerfel[3]==1) 
            {
                lockedWuerfel[3]=-1;
            }
            else
            {
                lockedWuerfel[3]=1;
            }
         }
      
      if (evt.getKeyCode() == KeyEvent.VK_5) {
            if (lockedWuerfel[4]==1) 
            {
                lockedWuerfel[4]=-1;
            }
            else
            {
                lockedWuerfel[4]=1;
            }
         }
}
```


----------



## Fancy (16. Sep 2008)

Moin,

ich bin mir noch nicht sicher wie sich Dein Programm verhalten soll. Was sollte den passieren wenn Würfel 1 bereits beleuchtet ist und Teste 2 gedrückt wird? Soll dann Würfel 1 und 2 leuchten oder soll Würfel 1 ausgehen?

Und was ist mit GL.GL_LIGHT2 soll das direktionales Licht sein das immer auf alle Würfel fällt? Die gesetzten Werte für ambient, diffuse und specular sehen mir auch etwas merkwürdig aus (bei beiden Lichtquellen)? Sieht das den so aus wie Du es wolltest?

Gruß,
Michael


----------



## JavaKing (16. Sep 2008)

> ich bin mir noch nicht sicher wie sich Dein Programm verhalten soll. Was sollte den passieren wenn Würfel 1 bereits beleuchtet ist und Teste 2 gedrückt wird? Soll dann Würfel 1 und 2 leuchten oder soll Würfel 1 ausgehen?



Es soll Würfel 1 und Würfel 2 angehen. Im Prinzip können alle 5 Würfel mit Spotlicht belegt werden. Ein/Aus 1-5



> Und was ist mit GL.GL_LIGHT2 soll das direktionales Licht sein das immer auf alle Würfel fällt? Die gesetzten Werte für ambient, diffuse und specular sehen mir auch etwas merkwürdig aus (bei beiden Lichtquellen)? Sieht das den so aus wie Du es wolltest?



Ich hab noch ein Lämpchen gebastelt das im Raum steht. Die Lampe sieht soweit gut aus, allerdings ist der Raum wohl viel zu dunkel. Meine weißen Würfel sind nämlich schwarz sobald ich das "Licht an" schalte.
Vielleicht hab ich die Lampe auch falsch positioniert...


----------



## Fancy (17. Sep 2008)

Moin,

also wenn mit Deinen obigen Beleuchtungswerten die Szene noch zu dunkel ist, stimmt irgendwas noch nicht. Immerhin sind alle Werte maximal, da sollte es eigentlich nicht mehr allzu viele dunkle Stellen geben. Sind vielleicht die Materialeigenschaften nicht richtig gesetzt oder die Lichtquellen falsch ausgerichtet (dann würde nur der ambiente Teil wirken)?

Mit der Positionierung und Ausrichtung der Lichtquellen muss man eh ein wenig aufpassen. Hintergrund ist, das Positionierungen die per GL_POSITION übergeben werden mit der aktuellen ModelView Matrix projiziert werden aber Ausrichtungen die per GL_SPOT_DIRECTION übergeben werden lediglich mit den Rotationskomponenten der ModelView verrechnet werden. Ein setzen der Position innerhalb der init() ist deshalb mit Vorsicht zu genießen. 

Ein weiterer Problempunkt besteht darin, dass wenn Du eine Lichtquelle während eines Renderlaufs änderst um mehrere Objekte zu beleuchten (und damit eigentlich mehrere Lichtquellen simulierst), werden Objekte die eigentlich von mehreren Lichtquellen beeinflusst werden sollten, nicht mehr korrekt beleuchtet. Dies musst Du ggf. beim Anlegen der Szene beachten.

Was Deine if else Konstruktionen angeht, also das geht auch kürzer (s.u.).  Außerdem würde alleine die if else Verzeigung der drawScene() verhindern, dass gleichzeitig mehr als ein Würfel beleuchtet wird.

Als Beispiel wie es gehen könnte:


```
package fancy.jf.light;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.GLUT;

public class LightFF implements GLEventListener, KeyListener {

   private static final int quantityCube   = 5;

   private GL               gl             = null;
   private GLU              glu            = null;
   private GLUT             glut           = null;

   private boolean[]        spotEnabled    = null;
   private float[]          spotDirectionX = null;


   @Override
   public void init(GLAutoDrawable drawable) {

       gl = drawable.getGL();
       glu = new GLU();
       glut = new GLUT();

       // setup gl basics
       gl.glShadeModel(GL.GL_SMOOTH);
       gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
       gl.glClearDepth(1.0f);
       gl.glEnable(GL.GL_DEPTH_TEST);
       gl.glDepthFunc(GL.GL_LEQUAL);
       gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

       // setup material
       gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.4f, 0.4f, 0.4f, 1.0f }, 0);
       gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 0.4f, 0.8f, 0.4f, 1.0f }, 0);
       gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 1.0f, 1.0f, 1.0f, 1.0f }, 0);
       gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 25.0f }, 0);

       // setup light
       gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, new float[] { 0.15f, 0.15f, 0.15f, 1 }, 0);
       gl.glLightModelfv(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, new float[] { 1.0f }, 0);

       gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, new float[] { 0.5f, 0.5f, 0.5f, 1.0f }, 0);
       gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1.0f }, 0);
       gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, new float[] { 0.9f, 0.9f, 0.9f, 1.0f }, 0);
       gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_CUTOFF, 5f);
       gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_EXPONENT, 2f);

       gl.glEnable(GL.GL_LIGHTING);

       // setup spot arrays
       spotEnabled = new boolean[quantityCube];
       spotDirectionX = new float[quantityCube];
       for (int i = 0; i < quantityCube; i++) {
           spotEnabled[i] = false;
           spotDirectionX[i] = (quantityCube / 2.0f) * -2.0f + 1.0f + i * 2.0f;
       }

   }


   @Override
   public void display(GLAutoDrawable drawable) {


       gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
       gl.glLoadIdentity();
       glu.gluLookAt(0, 4, 5, 0, 0, 0, 0, 1, 0);

       // set light position
       gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0.0f, 2.0f, 10.0f, 1.0f }, 0);

       gl.glTranslatef((quantityCube / 2.0f) * -2.0f + 1.0f, 0.0f, 0.0f);
       for (int i = 0; i < quantityCube; i++) {

           // switch light
           if (spotEnabled[i]) gl.glEnable(GL.GL_LIGHT0);

           // set light direction and draw
           gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, new float[] { spotDirectionX[i], -1.5f, -10f }, 0);
           glut.glutSolidCube(1.0f);
           gl.glTranslatef(2.0f, 0.0f, 0.0f);
           gl.glDisable(GL.GL_LIGHT0);
       }

   }


   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

       if (height <= 0) height = 1;

       gl.glMatrixMode(GL.GL_PROJECTION);
       gl.glLoadIdentity();
       glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 50.0);
       gl.glMatrixMode(GL.GL_MODELVIEW);
       gl.glLoadIdentity();
   }


   @Override
   public void keyPressed(KeyEvent e) {

       final int key = e.getKeyCode() - KeyEvent.VK_1;
       if (0 <= key && key <= spotEnabled.length) spotEnabled[key] = !spotEnabled[key];
   }


   @Override
   public void keyReleased(KeyEvent e) {}


   @Override
   public void keyTyped(KeyEvent e) {}


   @Override
   public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}


   public static void main(String[] args) {

       final LightFF main = new LightFF();
       final Frame frame = new Frame();
       final GLCanvas canvas = new GLCanvas();
       final Animator animator = new FPSAnimator(canvas, 60, true);
       canvas.addGLEventListener(main);
       canvas.addKeyListener(main);
       frame.add(canvas);
       frame.setSize(1000, 500);
       frame.addWindowListener(new WindowAdapter() {
           @Override
           public void windowClosing(WindowEvent e) {
               new Thread(new Runnable() {
                   public void run() {
                       animator.stop();
                       System.exit(0);
                   }
               }).start();
           }
       });
       frame.setVisible(true);
       animator.start();
       canvas.requestFocusInWindow();
   }

}
```

Gruß,
Michael


----------



## JavaKing (17. Sep 2008)

Habe deine Beispiel mal in ein neues Projekt eingebunden. Es lässt sich auch starten, aber sobald ich die Taste 1 betätige kommt folgende Fehlermeldung.

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x035d5beb, pid=2964, tid=2936
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_07-b03 mixed mode, sharing)
# Problematic frame:
# C  [ialmgicd.dll+0x15beb]
#
# An error report file with more information is saved as hs_err_pid2964.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seconds)


----------



## Fancy (17. Sep 2008)

Moin,

sehr interessant. Ich muss zugeben, dass ich das Beispiel gestern nur unter einem Nvidia OpenGL3 beta Treiber ausprobiert habe und einfach davon ausgegangen bin das es überall laufen würde (steckt immerhin nix dramatisches drin).

Allerdings habe ich es gerade auch auf einem Notebook mit Intel on Bord Grafikkarte getestet und da läuft es aber auch wie es sollte. Bei Deiner Fehlermeldung gehe ich davon aus das Du ebenfalls einen Rechner mit Intel Grafikkarte nutzt?

Woran es nun liegt, ist leider aus der Ferne schwierig zu beurteilen. Kannst Du die genaue Absturzstelle um Code eingrenzen (zur Not durch auskommentieren einzelner Zeilen)?

Was mich wundert ist das ich hier keine ialmgicd.dll habe und die Version die ich davon im Netz gefunden habe, hat an der Adresse 0x15beb nichts was den Absturz verursachen könnte. Steht in der Datei hs_err_pid2964.log evtl. noch etwas Nützliches drin?

Ansonsten wäre noch interessant:
-	welche Intelkarte
-	welche Treiberversion
-	welche Windowsversion
-	welche JoGL Version

Und um zu sehen was davon bei JoGL ankommt, wäre es hilfreich die Ausgabe des folgenden Programms zu posten:


```
package fancy.jf.info;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;

public class Info implements GLEventListener {

    private GL gl = null;


    @Override
    public void init(GLAutoDrawable drawable) {

        gl = drawable.getGL();

        System.out.println(gl.glGetString(GL.GL_VERSION));
        System.out.println(gl.glGetString(GL.GL_EXTENSIONS));

    }


    @Override
    public void display(GLAutoDrawable drawable) {}


    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}


    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}


    public static void main(String[] args) {

        final Info main = new Info();
        final Frame frame = new Frame();
        final GLCanvas canvas = new GLCanvas();
        canvas.addGLEventListener(main);
        frame.add(canvas);
        frame.setSize(50, 50);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                new Thread(new Runnable() {
                    public void run() {
                        System.exit(0);
                    }
                }).start();
            }
        });
        frame.setVisible(true);
    }

}
```

Gruß,
Michael


----------



## JavaKing (17. Sep 2008)

init:
deps-jar:
compile-single:
run-single:
1.4.0 - Build 4.14.10.3889

GL_ARB_depth_texture GL_ARB_fragment_program GL_ARB_multitexture GL_ARB_point_parameters GL_ARB_shadow GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_ARB_transpose_matrix GL_ARB_vertex_program GL_ARB_window_pos GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_EXT_cull_vertex GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_multi_draw_arrays GL_EXT_packed_pixels GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_filter_anisotropic GL_EXT_texture3D GL_3DFX_texture_compression_FXT1 GL_IBM_texture_mirrored_repeat GL_NV_blend_square GL_NV_texgen_reflection GL_SGIS_generate_mipmap GL_WIN_swap_hint 
BUILD SUCCESSFUL (total time: 19 seconds)


- welche Intelkarte 
 - Intel(R) 82915G/GV/910GL Express Chipset Family
- welche Treiberversion 
    6.14.10.3889
- welche Windowsversion 
 Windows XP SP2
- welche JoGL Version 
Ich habe hier nur eine jogl.jar rumfliegen. Sorry


Ich werde es später nochmal auf einen besseren PC austesten. Ich denke dort sollte es gehen.


----------



## JavaKing (18. Sep 2008)

Habe dies nun an einem anderen PC ausprobiert, da funktioniert dein Beispiel perfekt.

Leider konnte ich das für mein Problem noch nicht umsetzen.

Vielleicht ist dazu noch interessant wie ich meinen Würfel erstelle :


```
void SpielWuerfelList(GL gl)
{
        spiel_wuerfel1 = gl.glGenLists(1);
        gl.glNewList(spiel_wuerfel1, GL_COMPILE); 
        gl.glPushMatrix();
         //Würfel mit Augen Zeichenen     
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, FloatBuffer.wrap(new float[] { 0, 0, 0}));
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, FloatBuffer.wrap(new float[] { 0.0f, 0.0f, 0.0f}));
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, FloatBuffer.wrap(new float[] { 1.0f, 1.0f, 1.0f}));
        gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, 10);   
            
        gl.glScaled(0.5f, 0.5f, 0.5f);
        gl.glColor4d(1,1,1,1);
        glut.glutSolidCube(2);
        
        gl.glMaterialfv(GL_FRONT, GL_AMBIENT, FloatBuffer.wrap(new float[] { 1, 1, 1}));
        gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, FloatBuffer.wrap(new float[] { 0.6f, 0.6f, 0.6f}));
        gl.glMaterialfv(GL_FRONT, GL_SPECULAR, FloatBuffer.wrap(new float[] { 0.1f, 0.1f, 0.1f}));
        gl.glMaterialf(GL_FRONT, GL_SHININESS, 50);
        
        //1
        gl.glPushMatrix();
        gl.glTranslated(0, 0, 0.9f);
        gl.glColor4d(0,0,0,0);
        glut.glutSolidSphere(0.2, 10, 10);
        gl.glPopMatrix();
        
        //2
        gl.glPushMatrix();
        gl.glRotated(-90, 0, 1, 0);
        gl.glTranslated(-0.5f, 0.5, -0.9f);
        gl.glColor4d(0,0,0,0);
        glut.glutSolidSphere(0.2, 10, 10);
        gl.glPopMatrix();
        
        gl.glPushMatrix();
        gl.glRotated(-90, 0, 1, 0);
        gl.glTranslated(0.5f, -0.5, -0.9f);
        gl.glColor4d(0,0,0,0);
        glut.glutSolidSphere(0.2, 10, 10);
        gl.glPopMatrix();

    [...]
}
```

Ich denke mein Problem liegt das ich den Würfel schon mit diesen Licht glMaterialfv Eigenschaften belege. Das muss ich aber damit ich einen weißen Würfel habe mit schwarzen "Augen".
Vorschläge wie ich mein Beleuchtungsproblem löse ?


----------



## Fancy (18. Sep 2008)

Moin,

erstmal zum Problem PC:

Ich hab das heute mal auf einem Rechner laufen lassen, der dieselbe Grafikkarte hatte wie der Rechner mit dem es bei Dir Probleme gab. Genauer:

Grafikkarte: Intel(R) 82915G/GV/910GL Express Chipset Family 
Treiber version: 6.14.10.4410 
OpenGL: 1.4.0 - Build 4.14.10.4410 
Betriebsystem: Windows XP SP3 
Java: Java(TM) SE Runtime Environment (build 1.6.0_07-b06) 
JoGL: 1.1.1

Auf diesem Rechner gab es allerdings keinerlei Probleme. Ich vermute also, dass Du da z.B. eine alte evtl. fehlerhafte JoGL Version drauf hast oder der Treiber der Grafikkarte schlichtweg mal ein Update vertragen könnte (immerhin dürfte der so um die 4 Jahre alt sein).  

Was Dein Beleuchtungsproblem angeht:



			
				JavaKing hat gesagt.:
			
		

> Ich denke mein Problem liegt das ich den Würfel schon mit diesen Licht glMaterialfv Eigenschaften belege.



Ja, da ist zumindest schon mal ein Fehler, wenn auch vermutlich anders als Du denkst. 

Erstmal musst Du wissen, dass glColor keinerlei Wirkung mehr hat, sobald mit glEnable(GL_LIGHTING) die OpenGL Beleuchtung aktiviert wird. Das Aussehen der Oberflächen wird dann ausschließlich über die glMaterial Eigenschaften beeinflusst.

Das Problem an Deinem Code oben ist nun, das Du bei den Materialeigenschaften des Würfels sowohl den Ambient- als auch den Diffusen- Teil auf Null gesetzt hast. Dies bedeutet, dass der Würfel erstmal keinerlei Licht reflektiert und damit vollkommen schwarz ist. Der von Dir gesetzte Glanzanteil wirkt dagegen nur in einer relativ eng eingefassten Winkelsituation zwischen Lampe, Fläche und Kamera.

Die Materialeigenschaften die Du für die Augen gesetzt hast, erscheinen mir auch nicht sonderlich sinnvoll.

Hier mal mein Beispielcode von oben, ergänzt um ein paar "Augen" und "sinnvolle" Materialeigenschaften.


```
package fancy.jf.javaking;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.GLUT;

public class Cubes implements GLEventListener, KeyListener {

    private static final int quantityCube    = 5;

    private GL               gl              = null;
    private GLU              glu             = null;
    private GLUT             glut            = null;

    private boolean[]        spotEnabled     = null;
    private float[]          spotDirectionX  = null;

    int                      displayListCube = 0;
    private float            angle           = 0;


    @Override
    public void init(GLAutoDrawable drawable) {

        gl = drawable.getGL();
        glu = new GLU();
        glut = new GLUT();

        // setup gl basics
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

        // setup light
        gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, new float[] { 0.3f, 0.3f, 0.3f, 1 }, 0);
        gl.glLightModelfv(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, new float[] { 1.0f }, 0);

        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, new float[] { 0.5f, 0.5f, 0.5f, 1.0f }, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1.0f }, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, new float[] { 0.9f, 0.9f, 0.9f, 1.0f }, 0);
        gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_CUTOFF, 5f);
        gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_EXPONENT, 2f);
        
        gl.glEnable(GL.GL_LIGHTING);

        // setup spot arrays
        spotEnabled = new boolean[quantityCube];
        spotDirectionX = new float[quantityCube];
        for (int i = 0; i < quantityCube; i++) {
            spotEnabled[i] = false;
            spotDirectionX[i] = (quantityCube / 2.0f) * -2.0f + 1.0f + i * 2.0f;
        }
        
        // create display list
        createDisplayListCube();

    }
    

    
    private void createDisplayListCube(){
        displayListCube = gl.glGenLists(1);
        gl.glNewList(displayListCube, GL.GL_COMPILE);
        gl.glPushMatrix();
        
        // set cube material 
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.25f, 0.20f, 0.20f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 1.0f, 0.82f, 0.82f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 0.29f, 0.29f, 0.29f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 11.3f }, 0); 
        
        // draw cube
        glut.glutSolidCube(1.0f);
        
        // set eye material
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.05f, 0.05f, 0.06f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 0.18f, 0.17f, 0.22f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 0.33f, 0.32f, 0.34f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 38.4f }, 0);
     
        
        // draw eye 1
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye draw 2
        gl.glPushMatrix();
        gl.glTranslatef(-0.25f, -0.5f, -0.25f);  glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 3
        gl.glPushMatrix();
        gl.glTranslatef(-0.5f, -0.25f, -0.25f);  glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.25f);     glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.25f);     glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 4
        gl.glPushMatrix();
        gl.glTranslatef(0.5f, -0.25f, -0.25f);   glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.5f, -0.0f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, -0.5f, 0.0f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 5
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.5f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(-0.25f, 0.0f, -0.25f);   glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, 0.0f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, -0.5f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 6
        gl.glPushMatrix();
        gl.glTranslatef(-0.25f, -0.25f, -0.5f);  glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, .0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, .0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, -0.5f, 0.0f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, .0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, .0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        gl.glPopMatrix();
        gl.glEndList();
    }


    @Override
    public void display(GLAutoDrawable drawable) {

        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        glu.gluLookAt(0, 4, 5, 0, 0, 0, 0, 1, 0);

        // set light position
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0.0f, 1.5f, 10.0f, 1.0f }, 0);

        gl.glTranslatef((quantityCube / 2.0f) * -2.0f + 1.0f, 0.0f, 0.0f);
        for (int i = 0; i < quantityCube; i++) {

            // switch light
            if (spotEnabled[i]) gl.glEnable(GL.GL_LIGHT0);

            // set light direction and draw
            gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, new float[] { spotDirectionX[i], -1.5f, -10f }, 0);

            gl.glPushMatrix();
            gl.glRotatef(angle += 0.2f, 0.3f, 0.5f, 0.7f);
            gl.glCallList(displayListCube);
            gl.glPopMatrix();

            gl.glTranslatef(2.0f, 0.0f, 0.0f);

            gl.glDisable(GL.GL_LIGHT0);
        }
    }


    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

        if (height <= 0) height = 1;

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 50.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }


    @Override
    public void keyPressed(KeyEvent e) {

        final int key = e.getKeyCode() - KeyEvent.VK_1;
        if (0 <= key && key <= spotEnabled.length) spotEnabled[key] = !spotEnabled[key];
    }


    @Override
    public void keyReleased(KeyEvent e) {}


    @Override
    public void keyTyped(KeyEvent e) {}


    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}


    public static void main(String[] args) {

        final Cubes main = new Cubes();
        final Frame frame = new Frame();
        final GLCanvas canvas = new GLCanvas();
        final Animator animator = new FPSAnimator(canvas, 60, true);
        canvas.addGLEventListener(main);
        canvas.addKeyListener(main);
        frame.add(canvas);
        frame.setSize(1000, 500);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                new Thread(new Runnable() {
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });
        frame.setVisible(true);
        animator.start();
        canvas.requestFocusInWindow();
    }

}
```

Um mal ein Gefühl zu bekommen wie empfindlich die Standart OpenGL Beleuchtung ist, kannst Du auch mal probeweise die Position der Beleuchtung minimal ändern, auf:


```
// set light position
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0.0f, 2.5f, 10.0f, 1.0f }, 0);
```


Das was Du dann siehst ist genau das Problem weshalb Tesselierung oder Shader sinn machen, aber eben erst wenn die Beleuchtung einigermaßen das macht was sie soll. 

Gruß,
Michael


----------



## JavaKing (20. Sep 2008)

Hallo also ich habe jetzt versucht dein Beispiel in mein Programmcode zu integrieren.
Leider funktioniert die Beleuchtung nicht. Mein restliches Programm funktioniert einwandfrei nur beim Tastendruck sind die Würfel nicht beleuchtet :
Vermutlich habe ich GL.GL_POSITION und GL_SPOT_DIRECTION falsch gesetzt, leider verstehe ich aber nicht was falsch sein könnte.

Edit:
Ja es liegt an GL_Position, habe jetzt einfach (0,0,1,0) verwendet also von vorne auf die Würfel. Das klappt einwandfrei
Ich möchte jetzt einfach von oben das Licht setzen das nach unten strahlt???


```
private void drawScene(GL gl, boolean select) 
 { 
 [...]
glu.gluLookAt(0,0,-5, 0,-4,-5, 0,0,-1); 
        // set light position
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0,0,4 ,1 }, 0); 
        for (int i = 0; i < 5; i++) {

        // switch light
        //if (lockedWuerfel[i]==1) 
        gl.glEnable(GL.GL_LIGHT0);

        // set light direction and draw
        gl.glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { -2.11f,-0.16f,light_z, 1 })); // Punkt

        gl.glPushMatrix();
        gl.glTranslated((i-4)+i,-6.48,-6);
        if (select) {
            gl.glLoadName(i+1);
        }
        StartRotation(gl, gewuerfelt_liste[i],lockedWuerfel[i]);
        gl.glPopMatrix();
        gl.glDisable(GL.GL_LIGHT0);
        } 
[..]
}
```


----------



## Fancy (21. Sep 2008)

Moin,

Du musst Dir beim Positionieren der Beleuchtung die Szene genau vorstellen. Insbesondere wo sich Deine Lampe befindet (GL_POSITION), wo sich Dein zu beleuchtendes Objekt befindet (Würfel) und was nötig ist um von der Lampe zu Deinem Würfel zu kommen (GL_SPOT_DIRECTION).

Was mir auffällt, in Zeile 17 verschiebst Du Deinen Würfel in Abhängigkeit von i auf der x-Achse. Das heißt also, alle Deine Würfel befinden sich auf einer Geraden die parallel zur lokalen x-Achse verläuft. In Zeile 14 hingegen ist lediglich die z Position mit einer Variablen belegt, diese wird jedoch nicht mal in der Schleife verändert. Wenn Du das so machen möchtest wie im Beispiel (also das die Lampe fest über den Würfeln hängt) dann musst Du mit GL_SPOT_DIRECTION (ebenfalls in Abhängigkeit von i) den Spot Deiner Lampe auf den jeweiligen Würfel ausrichten. Dies heißt, die Bewegung Deines Spots muss ebenfalls eine Gerade beschreiben, die parallel zur lokalen x-Achse verläuft.

Des Weiteren gibst Du in Zeile 14 als Richtung 4 Koordinaten an, wobei als letzte Koordinate eine 1 übergeben wird. Dies geht so leider nicht. GL_SPOT_DIRECTION übernimmt nur die ersten 3 Koordinaten und setzt den 4. Wert immer implizit auf 0. Dies bedeutet, es handelt sich nicht um einen Punkt, sondern um einen Richtungsvektor. Um Dir das vorstellen zu können, musst Du Dir überlegen, wo Deine Lampe ist und was Du tun musst um von da aus Deinen Würfel zu treffen.

(Übrigens, Deine mit gluLookAt gesetzte Kameraausrichtung ist alles andere als glücklich. Oben / Unten liegt bei Dir auf der z-Achse, wobei kleine z Werte oben und große unten sind. Dies macht es nicht gerade einfacher.)

Aber gut, in Deinem Koordinatensystem gilt z.B.:

Beleuchtung gerade von oben:

```
//  Zeile  6: gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0.0f, -6.48f, -20.0f, 1.0f }, 0);
//  Zeile 14: gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, new float[] { (i-4)+i, 0.0f, 14.0f }, 0);
```

Beleuchtung von schräg oben/vorne (wie auf einer Bühne):

```
//  Zeile  6: gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { 0.0f, 2.48f, -25.0f, 1.0f }, 0);
//  Zeile 14: gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, new float[] { (i-4)+i, -8.0f, 19.0f }, 0);
```

Gruß,
Michael


----------



## JavaKing (21. Sep 2008)

Vielen Dank für deine Antwort. Aber dein Beispiel ist doch eigentlich ein gerichtetes Licht oder ?
Leider funktioniert das einfach umstellen von GL_Position und GL_Direction von dir nicht. Is nur ein leichtes Licht zu sehen.
Ich wollte ja ein Spotlight machen. Ich habe das jetzt auch ein wenig anders gelöst.
Habe mir 5 Lichtquellen erschaffen die dann von oben auf die Würfel treffen. Funktioniert auch super.

Als Untergrund habe ich jedoch eine Tischplatte (GL_POLYGON).
Also die Würfel liegen auf dem Tisch. Die Lichtquelle(n) strahlen von oben auf die Würfel. Müsste ich da bei Spotlight nicht einen Lichtkegel auf der Tischfläche sehen ? Es werden nämlich "nur" die Würfel beleuchtet.
Also entweder ist das richtig so oder meine Tischplatte ist nicht richtig tessiliert.

Kann es sein das hier die z Koordinaten nicht berücksichtigt werden und es deshalb nicht richtig tessiliert ist ?

```
// Tischplatte
        tischplatte = gl.glGenLists(1); 
        gl.glNewList(tischplatte, GL_COMPILE);
          gl.glEnable(GL_TEXTURE_2D);
          text_tischplatte.bind();

        float w = 6+6; 
        float h = 3+3; 
        float xOffset = -6; 
        float yOffset = -3; 
        int segments = 200; 
        for (int x=0; x<segments; x++) { 
            for (int y=0; y<segments; y++)     { 
        // Relative Positionen der 4 Eckpunkte, alle zwischen 0 und 1 
        float rx0 = x * (1.0f / segments); 
        float ry0 = y * (1.0f / segments); 
        float rx1 = (x+1) * (1.0f / segments); 
        float ry1 = (y+1) * (1.0f / segments); 

        // Positionen der Expunkte des Rechtecks im Raum 
        float x0 = xOffset + rx0 * w; 
        float y0 = yOffset + ry0 * h; 
        float x1 = xOffset + rx1 * w; 
        float y1 = yOffset + ry1 * h; 

        gl.glBegin(GL_POLYGON); 
        gl.glTexCoord2f(rx0,ry1); gl.glVertex3f(x0, -3.0f, y1); //Punkt hinten links 
        gl.glTexCoord2f(rx0,ry0); gl.glVertex3f(x1, -3.0f, y1); //Punkt hinten rechts
        gl.glTexCoord2f(rx1,ry0); gl.glVertex3f(x1, -3.0f, y0); //Punkt vorne rechts
        gl.glTexCoord2f(rx1,ry1); gl.glVertex3f(x0, -3.0f, y0); // Punkt vorne links
        gl.glEnd(); 
    } 
}
```

Nicht schön, nicht speicherschonend. Aber es funktioniert....

```
if(isselected2){
            //von oben schauen :-)
            if (lockedWuerfel[0]==1){
            //Würfel 1
            gl.glEnable(GL_LIGHT1);
            light_x_1 = -4.8f;//links rechts
            light_y_1 = 0.48f;//oben unten            
            }
            else {gl.glDisable(GL_LIGHT1);}
            if (lockedWuerfel[1]==1){
            //Würfel 2
            gl.glEnable(GL_LIGHT3);
            light_x_2 = -2.55f;//links rechts
            light_y_2 = 0.48f;//oben unten            
            }else{gl.glDisable(GL_LIGHT3);}

            if (lockedWuerfel[2]==1){
            //Würfel 3
            gl.glEnable(GL_LIGHT4);
            light_x_3 = -0.35f;//links rechts
            light_y_3 = 0.48f;//oben unten
            }else{gl.glDisable(GL_LIGHT4);}
            
            if (lockedWuerfel[3]==1){
            //Würfel 4
            gl.glEnable(GL_LIGHT5);

            light_x_4 = 1.75f;//links rechts
            light_y_4 = 0.48f;//oben unten
            }else{gl.glDisable(GL_LIGHT5);}
            
            if (lockedWuerfel[4]==1){
            //Würfel 5
            gl.glEnable(GL_LIGHT6);
            light_x_5 = 3.85f;//links rechts
            light_y_5 = 0.48f;//oben unten   
            }else{gl.glDisable(GL_LIGHT6);}
            
            
            gl.glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x_1,light_y_1,light_z, 1 })); // Punkt 
            gl.glLightfv(GL_LIGHT3, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x_2,light_y_2,light_z, 1 })); // Punkt 
            gl.glLightfv(GL_LIGHT4, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x_3,light_y_3,light_z, 1 })); // Punkt 
            gl.glLightfv(GL_LIGHT5, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x_4,light_y_4,light_z, 1 })); // Punkt 
            gl.glLightfv(GL_LIGHT6, GL_SPOT_DIRECTION, FloatBuffer.wrap(new float[] { light_x_5,light_y_5,light_z, 1 })); // Punkt 
            gl.glTranslatef(-0.4f,-0.6f,0.8f);
            glu.gluLookAt(0,0,-5, 0,-4,-5, 0,0,-1);
```


----------



## Fancy (21. Sep 2008)

Moin,



			
				JavaKing hat gesagt.:
			
		

> Aber dein Beispiel ist doch eigentlich ein gerichtetes Licht oder ?



Nein, siehe hier. Nur GL_POSITION erwatet 4 Koordinatenparameter. Was da übergeben wird sind homogene Koordinaten. Ist w = 1 handelt es sich um einen Punkt im Raum und damit um eine Punktlichtquelle. Wenn w = 0 wird kein Punkt übergeben, sondern eine Richtung und damit handelt es sich um eine unendlich weit entfernte und gerichtete Lichtquelle. 

GL_SPOT_DIRECTION erwartet 3 Koordinatenparameter. Es handelt sich hierbei jedoch auch um homogene Koordinaten, dabei wird implizit w = 0 gesetzt, es handelt sich also immer um eine Richtung.



			
				JavaKing hat gesagt.:
			
		

> Leider funktioniert das einfach umstellen von GL_Position und GL_Direction von dir nicht. Is nur ein leichtes Licht zu sehen.



Dann werden Deine Würfel vermutlich nicht um Ihren lokalen Koordinatenursprung gezeichnet und liegen damit nicht im Spot. Die von mir angegebenen Werte richten das Licht auf die von Dir mit glTranslate gesetzten Koordinaten.



			
				JavaKing hat gesagt.:
			
		

> Habe mir 5 Lichtquellen erschaffen die dann von oben auf die Würfel treffen. Funktioniert auch super.



Ja, kannst Du so machen. Wenn Du darunter auch noch eine Ebene beleuchten willst, ist dies sogar sinnvoll.



			
				JavaKing hat gesagt.:
			
		

> Die Lichtquelle(n) strahlen von oben auf die Würfel. Müsste ich da bei Spotlight nicht einen Lichtkegel auf der Tischfläche sehen ? Es werden nämlich "nur" die Würfel beleuchtet.



Ja, grundsätzlich schon. Bist Du sicher, dass das entsprechende Licht noch eingeschaltet ist während die Tischplatte gezeichnet wird, sowie der Kegeldurchmesser groß genug ist? (Einen Schatten der Würfel wirst Du so einfach allerdings auch nicht sehen)



			
				JavaKing hat gesagt.:
			
		

> Also entweder ist das richtig so oder meine Tischplatte ist nicht richtig tessiliert.



Oder die Normale Deines Polygons ist falsch.



			
				JavaKing hat gesagt.:
			
		

> Kann es sein das hier die z Koordinaten nicht berücksichtigt werden und es deshalb nicht richtig tessiliert ist ?



Setze mal in der init():


```
gl.glPolygonMode(GL.GL_BACK, GL.GL_LINE);
gl.glPolygonMode(GL.GL_FRONT, GL.GL_LINE);
```

Dann solltest Du sehen ob die Tesselierung stimmt. (Deine Tischplatte sollte dann als gleichmäßiges Gitternetz zu sehen sein, sofern segments einen sinnvollen Wert hat) 


(Als allgemeiner Tipp: Versuche doch mal in Zukunft Deine Programme ein wenig sauberer zu schreiben und das OpenGL mehr zu ordnen. Das kostet zwar scheinbar erstmal Zeit, spart aber auch Zeit weil die meisten Fehler gar nicht mehr auftreten und die, die noch auftreten sind schneller gefunden.) 

Gruß,
Michael


----------



## JavaKing (21. Sep 2008)

> Ja, grundsätzlich schon. Bist Du sicher, dass das entsprechende Licht noch eingeschaltet ist während die Tischplatte gezeichnet wird, sowie der Kegeldurchmesser groß genug ist? (Einen Schatten der Würfel wirst Du so einfach allerdings auch nicht sehen)



Es wird bei Tastendruck aktiviert und dann nochmal tastendruck deaktiviert.



> Dann solltest Du sehen ob die Tesselierung stimmt. (Deine Tischplatte sollte dann als gleichmäßiges Gitternetz zu sehen sein, sofern segments einen sinnvollen Wert hat)



Also das sehe ich ein Gitternetz.



> (Als allgemeiner Tipp: Versuche doch mal in Zukunft Deine Programme ein wenig sauberer zu schreiben und das OpenGL mehr zu ordnen. Das kostet zwar scheinbar erstmal Zeit, spart aber auch Zeit weil die meisten Fehler gar nicht mehr auftreten und die, die noch auftreten sind schneller gefunden.)



Beim nächsten Projekt werde ich das sicherlich machen. Ich habe ja jetzt schon ein wenig Erfahrung sammeln können.

Woran könnte es noch liegen das ich kein Kegellicht auf dem Tisch sehe ?


----------



## Fancy (21. Sep 2008)

Moin,

dann setze mal die Normale Deiner Tischplatte (sofern nicht schon geschehen). Wahrscheinlich am besten im Codeblock aus Deinem vorherigern Post in Zeile 25 (also direkt vor glBegin(GL_POLYGON)). 

Versuche mal:


```
gl.glNormal3f(0, 1, 0);
```

Wenn das nicht geht, dann mal -1 (weiß nicht wo in Deinem Kontext da gerade oben ist).

Die Normale ist ein Richtungsvektor der senkrecht zur Fläche stehen soll und wird eigentlich zur Berechnung der korrekten Beleuchtungswerte benötigt.

Gruß,
Michael


----------



## JavaKing (21. Sep 2008)

Leider keine Veränderung weder mit 1 noch mit -1


----------



## Fancy (22. Sep 2008)

Moin,

mehr Möglichkeiten gibt meine Glaskugel zurzeit leider auch nicht her. Das Problem an der Ferndiagnose ist, das OpenGL als Zustandsmaschine implementiert wurde. Das heißt jeder Wert / Parameter / Zustand der irgendwo / irgendwann mal gesetzt wurde, wirkt bis das etwas anderes gesetzt wird. Deshalb muss man eigentlich Dein komplettes Programm kennen um den Zustand in einer bestimmten Methode abschätzen zu können.

So wie ich das sehe, hast Du jetzt 3 Möglichkeiten:

1.	Du suchst einfach weiter und hoffst das Du den Fehler findest.
2.	Du stellst Deinen Sourcecode online (ideallerweise per public svn oder cvs).
3.	Ich gebe Dir ein weiteres, an Deine aktuelle Lichtsituation angepasstes Beispiel und Du versuchst den Fehler über einen Vergleich der beiden Programme einzugrenzen.

Falls Du dich für das Beispiel entscheidest:
(Diesmal 5 einzelne Spots und eine Tischplatte)


```
package fancy.jf.javaking;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.GLUT;

public class Cubes2 implements GLEventListener, KeyListener {

    private static final int quantityCube     = 5;

    private GL               gl               = null;
    private GLU              glu              = null;
    private GLUT             glut             = null;

    private int              displayListCube  = 0;
    private int              displayListFloor = 0;
    private float            angle            = 0;
    
    private boolean[]        spotEnabled      = null;


    @Override
    public void init(GLAutoDrawable drawable) {

        gl = drawable.getGL();
        glu = new GLU();
        glut = new GLUT();

        spotEnabled = new boolean[quantityCube];

        // setup gl basics
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

        // setup light
        gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, new float[] { 0.5f, 0.5f, 0.5f, 1 }, 0);
        gl.glLightModelfv(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, new float[] { 1.0f }, 0);

        for (int i = 0; i < quantityCube; i++) {
            gl.glLightfv(GL.GL_LIGHT0 + i, GL.GL_AMBIENT, new float[] { 0.5f, 0.5f, 0.5f, 1.0f }, 0);
            gl.glLightfv(GL.GL_LIGHT0 + i, GL.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1.0f }, 0);
            gl.glLightfv(GL.GL_LIGHT0 + i, GL.GL_SPECULAR, new float[] { 0.9f, 0.9f, 0.9f, 1.0f }, 0);
            gl.glLightf(GL.GL_LIGHT0 + i, GL.GL_SPOT_CUTOFF, 6.4f);
            gl.glLightf(GL.GL_LIGHT0 + i, GL.GL_SPOT_EXPONENT, 2f);
        }

        gl.glEnable(GL.GL_LIGHTING);

        // setup display lists
        createDisplayListCube();
        createDisplayListFloor();

    }
    
    
    private void createDisplayListCube(){
        displayListCube = gl.glGenLists(1);
        gl.glNewList(displayListCube, GL.GL_COMPILE);
        gl.glPushMatrix();
        
        // set cube material 
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.25f, 0.20f, 0.20f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 1.0f, 0.82f, 0.82f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 0.29f, 0.29f, 0.29f, 0.9f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 11.3f }, 0); 
        
        // draw cube
        glut.glutSolidCube(1.0f);
        
        // set eye material
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.05f, 0.05f, 0.06f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 0.18f, 0.17f, 0.22f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 0.33f, 0.32f, 0.34f, 0.8f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 38.4f }, 0);
     
        
        // draw eye 1
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 2
        gl.glPushMatrix();
        gl.glTranslatef(-0.25f, -0.5f, -0.25f);  glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 3
        gl.glPushMatrix();
        gl.glTranslatef(-0.5f, -0.25f, -0.25f);  glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.25f);     glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.25f);     glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 4
        gl.glPushMatrix();
        gl.glTranslatef(0.5f, -0.25f, -0.25f);   glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.5f, -0.0f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, -0.5f, 0.0f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 5
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.5f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(-0.25f, 0.0f, -0.25f);   glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, 0.5f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, 0.0f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.0f, -0.5f);      glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        // draw eye 6
        gl.glPushMatrix();
        gl.glTranslatef(-0.25f, -0.25f, -0.5f);   glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.5f, -0.5f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glTranslatef(0.0f, 0.25f, 0.0f);       glut.glutSolidSphere(0.1, 5, 5);
        gl.glPopMatrix();
        
        gl.glPopMatrix();
        gl.glEndList();
    }
    
    
    private void createDisplayListFloor() {
        displayListFloor = gl.glGenLists(1);
        gl.glNewList(displayListFloor, GL.GL_COMPILE);
        
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, new float[] { 0.25f, 0.14f, 0.06f, 1.0f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, new float[] { 0.4f, 0.23f, 0.10f, 1.0f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, new float[] { 0.77f, 0.45f, 0.2f, 1.0f }, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, new float[] { 76.8f }, 0);
        
        //draw floor
        final float step = 0.5f;
        final float size = 12.0f;
        gl.glNormal3f(0.0f, 1.0f, 0.0f);
        gl.glBegin(GL.GL_QUADS);
        for (float x = -(size / 2); x < (size / 2); x += step) {
            for (float y = -(size / 2); y < (size / 2); y += step) {
                gl.glVertex3f(x,        0.0f, y);
                gl.glVertex3f(x + step, 0.0f, y);
                gl.glVertex3f(x + step, 0.0f, y + step);
                gl.glVertex3f(x,        0.0f, y + step);
            }
        }
        gl.glEnd();

        gl.glEndList();
    }


    @Override
    public void display(GLAutoDrawable drawable) {

        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        glu.gluLookAt(0, 2, 8, 0, 0, 0, 0, 1, 0);
        
        gl.glPushMatrix();
        gl.glTranslatef((quantityCube / 2.0f) * -2.0f + 1.0f, 0.0f, 0.0f);
        for (int i = 0; i < quantityCube; i++) {

            // switch light
            if (spotEnabled[i]) gl.glEnable(GL.GL_LIGHT0 + i);
            else gl.glDisable(GL.GL_LIGHT0 + i); 

            // set light direction
            gl.glLightfv(GL.GL_LIGHT0 + i, GL.GL_POSITION, new float[] { 0.0f, 10.0f, 0.0f, 1.0f }, 0);
            gl.glLightfv(GL.GL_LIGHT0 + i, GL.GL_SPOT_DIRECTION, new float[] { 0.0f, -10.0f, 0.0f }, 0);

            // draw cube
            gl.glPushMatrix();
            gl.glRotatef(angle += 0.2f, 0.3f, 0.5f, 0.7f);
            gl.glCallList(displayListCube);
            gl.glPopMatrix();

            gl.glTranslatef(2.0f, 0.0f, 0.0f);
            
        }
        gl.glPopMatrix();
        
        // draw floor
        gl.glTranslatef(0.0f, -0.8f, 0.0f);
        gl.glScalef(1.0f, 1.0f, 0.3f);
        gl.glCallList(displayListFloor);
                
    }


    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

        if (height <= 0) height = 1;

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 50.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }


    @Override
    public void keyPressed(KeyEvent e) {

        final int key = e.getKeyCode() - KeyEvent.VK_1;
        if (0 <= key && key < spotEnabled.length) spotEnabled[key] = !spotEnabled[key];
    }


    @Override
    public void keyReleased(KeyEvent e) {}


    @Override
    public void keyTyped(KeyEvent e) {}


    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}


    public static void main(String[] args) {

        final Cubes2 main = new Cubes2();
        final Frame frame = new Frame();
        final GLCanvas canvas = new GLCanvas();
        final Animator animator = new FPSAnimator(canvas, 60, true);
        canvas.addGLEventListener(main);
        canvas.addKeyListener(main);
        frame.add(canvas);
        frame.setSize(1000, 500);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                new Thread(new Runnable() {
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });
        frame.setVisible(true);
        animator.start();
        canvas.requestFocusInWindow();
    }

}
```

(Persönliche Meinung nach betrachten des Beispiels: Sei froh das Deine Tischplatte nicht beleuchtet ist, verursacht Augenkrebs.)

Gruß,
Michael


----------



## JavaKing (24. Sep 2008)

Habe dein Beispiel getestet, das sieht wirklich furchtbar aus.^^ Meinen Lichtkegel habe ich leider nicht hinbekommen, anscheinden strahlt meine Lichquelle von z=4 aus. Aber warum ist mein Würfel dann von oben beleuchtet. Bei einem cutoffwinkel von 5f. Ich werde das jetzt aber nicht weiter verfolgen, sieht gut aus so wie es ist.

Möchte mich nochmal recht herzlich für die vielen Erklärungen und Beispiele bedanken. Ohne das Forum hier wäre ich wohl nie soweit gekommen. Danke ! :toll:


----------

