lightning and material

Started by jagdfalke, December 08, 2006, 14:07:45

Previous topic - Next topic

jagdfalke

Hi,
I'm trying to bring lightning into my scene and copied some code from the redbook into my code. Well, the cube does look different but not the way I expected it to look like.

I added this to #initOpenGL:
       GL11.glShadeModel(GL11.GL_SMOOTH);
        
        float[] light_position_arr = {10f, 10f, 0f, 0f};
        
		FloatBuffer light_position = BufferUtils.createFloatBuffer(8);
			light_position.put(light_position_arr);
        	
		GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, light_position);
        GL11.glEnable(GL11.GL_LIGHT0);


and this is the render-Methode of the cube-class:
public void render() {
		float half_radius = radius/2f;
		
	    float[] mat_specular_arr = {1f, 1f, 1f, 1f};
	    float[] mat_shininess_arr = {50.0f};
        FloatBuffer mat_specular = BufferUtils.createFloatBuffer(8);
    		mat_specular.put(mat_specular_arr);
    	FloatBuffer mat_shininess = BufferUtils.createFloatBuffer(8);
			mat_shininess.put(mat_shininess_arr);
	    
        GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR, mat_specular);
        GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SHININESS, mat_shininess);
		
        
		GL11.glBegin(GL11.GL_QUADS);
	        // Front Face
	        GL11.glColor3f(colorFront[0], colorFront[1], colorFront[2]);
	        GL11.glNormal3f(0f, 0f, 1f);
	        GL11.glVertex3f(-half_radius, -half_radius,  half_radius);
	        GL11.glVertex3f( half_radius, -half_radius,  half_radius);	
	        GL11.glVertex3f( half_radius,  half_radius,  half_radius);
	        GL11.glVertex3f(-half_radius,  half_radius,  half_radius);
	        
	        // Back Face
	        GL11.glColor3f(colorBack[0], colorBack[1], colorBack[2]);
	        GL11.glNormal3f(0f, 0f, -1f);
	        GL11.glVertex3f(-half_radius, -half_radius, -half_radius);
	        GL11.glVertex3f(-half_radius,  half_radius, -half_radius);
	        GL11.glVertex3f( half_radius,  half_radius, -half_radius);	
	        GL11.glVertex3f( half_radius, -half_radius, -half_radius);
	        
	        // Top Face
	        GL11.glColor3f(colorTop[0], colorTop[1], colorTop[2]);
	        GL11.glNormal3f(0, 1, 0);
	        GL11.glVertex3f(-half_radius,  half_radius, -half_radius);
	        GL11.glVertex3f(-half_radius,  half_radius,  half_radius);
	        GL11.glVertex3f( half_radius,  half_radius,  half_radius);
	        GL11.glVertex3f( half_radius,  half_radius, -half_radius);
	        
	        // Bottom Face
	        GL11.glColor3f(colorBottom[0], colorBottom[1], colorBottom[2]);
	        GL11.glNormal3f(0, -1, 0);
	        GL11.glVertex3f(-half_radius, -half_radius, -half_radius);
	        GL11.glVertex3f( half_radius, -half_radius, -half_radius);
	        GL11.glVertex3f( half_radius, -half_radius,  half_radius);
	        GL11.glVertex3f(-half_radius, -half_radius,  half_radius);
	        
	        // Right face
	        GL11.glColor3f(colorRight[0], colorRight[1], colorRight[2]);
	        GL11.glNormal3f(1, 0, 0);
	        GL11.glVertex3f( half_radius, -half_radius, -half_radius);
	        GL11.glVertex3f( half_radius,  half_radius, -half_radius);
	        GL11.glVertex3f( half_radius,  half_radius,  half_radius);
	        GL11.glVertex3f( half_radius, -half_radius,  half_radius);
	        
	        // Left Face
	        GL11.glColor3f(colorLeft[0], colorLeft[1], colorLeft[2]);
	        GL11.glNormal3f(-1, 0, 0);
	        GL11.glVertex3f(-half_radius, -half_radius, -half_radius);
	        GL11.glVertex3f(-half_radius, -half_radius,  half_radius);
	        GL11.glVertex3f(-half_radius,  half_radius,  half_radius);
	        GL11.glVertex3f(-half_radius,  half_radius, -half_radius);	    
	    GL11.glEnd();		
	}


The cube is neither black (because I can still see it with black background) nor of the color I defined. Whats going on?

Fool Running

Try adding
        glEnable(GL_COLOR_MATERIAL);
        glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

to the initOpenGL() method. When you start using lighting, the calculations use the glMaterial() values by default. If you don't supply a glMaterial(GL_FRONT, GL_DIFFUSE, color) it will take the diffuse color as black. The above lines turn on what I think is called "color tracking" which makes the calculations use the values you specify in glColor3f() for the diffuse and ambient material properties.

Hope that helps :)
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

jagdfalke

Yeah, thx, it really helps.
But there are still problems: Shouldn't this enabel a global amient light ???
        float[] global_ambient_arr = {1f, 1f, 1f, 1f};
        FloatBuffer global_ambient = BufferUtils.createFloatBuffer(8);
        	global_ambient.put(global_ambient_arr);
        GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, global_ambient);

Well, when I delete the other light from the example before, I see nothing but darkness. No light at all ... why?
(by the way: is this tutorial crap?)

EDIT: Changes this light's color doesn't make any difference, too:
        float[] ambient_color_arr = {1.0f, 1.0f, 1.0f, 1.0f};
        FloatBuffer ambient_color = BufferUtils.createFloatBuffer(8);	
        ambient_color.put(ambient_color_arr);
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambient_color);
        GL11.glEnable(GL11.GL_LIGHT0);




Here the full code in case somebody wants to compile it.
import org.lwjgl.*;
import org.lwjgl.opengl.*;
import org.lwjgl.opengl.glu.*;
import java.nio.*;

public class GLApp {

	public boolean finished;
    public String windowTitle 			= "Rotating Cube";

    public DisplayMode displayMode, originalDisplayMode;       	
    public int displayWidth 			= 800;
    public int displayHeight 			= 600;
    public int displayColorBits 		= 24;
    public int displayFrequency 		= 60;
    public int depthBufferBits 			= 24;     		
    public boolean fullScreen 			= false;    	
    public float aspectRatio 			= 0;   
    public int viewportX, viewportY;   
    public int viewportW, viewportH;   
        
    private Axis axis;
    private Cube cube;
    private FramePerSecond fps;
    public float rotation 				= 0f;

    public void run() {
    	init();
        while (!finished) {
            if (!Display.isVisible()) {
            	try  {
            		Thread.sleep(200L);
            	} catch(Exception ex) {}
            } else if (Display.isCloseRequested()) {
                finished = true;
            }
            mainLoop();
            Display.update();
        }
        cleanup();
        System.exit(0);
    }
    public void cleanup() {
    	Display.destroy();
    }
    
    /*
     * MainLoop
     */
    public void mainLoop() {
    	logic();
    	render();
    }
    public void logic() {
    	fps.update();
    	rotation += .3;   	
    }
    public void render() {
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        
        GLU.gluLookAt(5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f);
        
        // draw axis
        GL11.glPushMatrix();
        	axis.render();
        GL11.glPopMatrix();
        
        // render cube
        GL11.glPushMatrix();
	        GL11.glRotatef(rotation, (float)0, (float)1, (float)0);
	        cube.render();
        GL11.glPopMatrix();
    }

 
    /*
     * Initialization
     */
    public void init() {
        initDisplay();
        initOpenGL();
        
    	axis = new Axis(20f);
    	cube = new Cube(1f);
    	fps = new FramePerSecond();
    }

    public void initOpenGL() {
        GL11.glClearDepth(1.0f); 			// Depth Buffer Setup
        GL11.glClearColor(0f, 0f, 0f, 0f); 	// Black Background
        GL11.glEnable(GL11.GL_DEPTH_TEST); 	// Enables Depth Testing  // Need this ON if using textures
        GL11.glDepthFunc(GL11.GL_LEQUAL); 	// The Type Of Depth Testing To Do
    
        GL11.glViewport(viewportX, viewportY, viewportW, viewportH);
       
        setPerspective();

        
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
       
        
        GL11.glEnable(GL11.GL_NORMALIZE);
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        
        //global ambient
        float[] global_ambient_arr = {1f, 1f, 1f, 1f};
        FloatBuffer global_ambient = BufferUtils.createFloatBuffer(8);
        	global_ambient.put(global_ambient_arr);
        GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, global_ambient);
        
        
        float[] ambient_color_arr = {1.0f, 1.0f, 1.0f, 1.0f};
        FloatBuffer ambient_color = BufferUtils.createFloatBuffer(8);	
        ambient_color.put(ambient_color_arr);
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambient_color);
        GL11.glEnable(GL11.GL_LIGHT0);
        
      
        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT_AND_DIFFUSE);
    }
    public void setPerspective() {
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(30f, aspectRatio, 1f, 30f);
    } 

    public boolean initDisplay () {
        originalDisplayMode = Display.getDisplayMode();

                
        if ( (displayMode = getDisplayMode(displayWidth, displayHeight, displayColorBits, displayFrequency)) == null) {
            if ( (displayMode = getDisplayMode(800, 600, 32, 60)) == null) {
            	if( (displayMode = getDisplayMode(800, 600, 24, 60)) == null) {
                    if ( (displayMode = getDisplayMode(800, 600, 16, 60)) == null) {
                        if ( (displayMode = getDisplayMode(originalDisplayMode.getWidth(), originalDisplayMode.getHeight(), originalDisplayMode.getBitsPerPixel(), originalDisplayMode.getFrequency())) == null) {
                            System.out.println("Can't find a compatible Display Mode!!!");
                        }
                    }
            	}
            }
        }
        try {
            Display.setDisplayMode(displayMode);
        } catch (Exception exception) {
            System.exit(1);
        }
        
        // Initialize the Window
        try {
            Display.create(new PixelFormat(0, depthBufferBits, 0));  // set bits per buffer: alpha, depth, stencil
            Display.setTitle(windowTitle);
            Display.setFullscreen(fullScreen);
            Display.setVSyncEnabled(true);
            System.out.println("GLApp.initDisplay(): Created OpenGL window.");
        } catch (Exception exception1) {
            System.err.println("GLApp.initDisplay(): Failed to create OpenGL window: " + exception1);
            System.exit(1);
        }
        
        // Set viewport width/height and Aspect ratio.
        if (aspectRatio == 0f) {
            aspectRatio = (float)displayMode.getWidth() / (float)displayMode.getHeight();
        }
        
        // viewport may not match shape of screen.  Adjust to fit.
        viewportH = displayMode.getHeight();                        // viewport Height
        viewportW = (int) (displayMode.getHeight() * aspectRatio);  // Width
        if (viewportW > displayMode.getWidth()) {
            viewportW = displayMode.getWidth();
            viewportH = (int) (displayMode.getWidth() * (1 / aspectRatio));
        }
        
        // center viewport in screen
        viewportX = (int) ((displayMode.getWidth()-viewportW) / 2);
        viewportY = (int) ((displayMode.getHeight()-viewportH) / 2);
        return true;
    }
    public DisplayMode getDisplayMode(int w, int h, int colorBits, int freq) {
        try {
            DisplayMode adisplaymode[] = Display.getAvailableDisplayModes();
            DisplayMode dm = null;
            for (int j = 0; j < adisplaymode.length; j++) {
                dm = adisplaymode[j];
                if (dm.getWidth() == w && dm.getHeight() == h && dm.getBitsPerPixel() == colorBits &&
                    dm.getFrequency() == freq) {
                    return dm;
                }
            }
        }
        catch (LWJGLException e) {
            System.out.println("GLApp.getDisplayMode(): Exception " + e);
        }
        return null;
    }
    

    
    
    public static void main(String args[]) {
        GLApp demo = new GLApp();
        	demo.run();
    }
 
}

Fool Running

Finally had a chance to try your code...
The problem with your colors is that you need to flip() the FloatBuffer after you put stuff in it. otherwise the pointer is pointing to the end of the buffer and nothing happens. like this: global_ambient.put(global_ambient_arr).flip();

In your cube class: GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SHININESS, mat_shininess); should be GL11.glMateriali(GL11.GL_FRONT, GL11.GL_SHININESS, integerValue);

I think that's all I did to get it working right...

Hope that helps ;D

EDIT: No, the tutorial isn't crap, Its just done slightly different in Java :)
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

jagdfalke

thx 4 your help, now I know better :D