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?
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 :)
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 (http://www.falloutsoftware.com/tutorials/gl/gl8.htm#how_opengl_shades_objects) 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();
}
}
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 :)
thx 4 your help, now I know better :D