Does anyone know what i have done wrong, i cant seem to port the lesson over to lwjgl.
http://rafb.net/p/TsCcES15.html (http://rafb.net/p/TsCcES15.html)
Iv included the whole program. If someone wanted to try it here is a link for the object that it loads
http://rafb.net/p/8usltF25.html (http://rafb.net/p/8usltF25.html)
It runs fine, except there is no shadow.
Iv also tried making the pixel format (0, 16, 1) yet it still wont do anything could it be my video card?
I was gonna try it out, but the links are dead :-\
oops sorry, didnt realize how short lasting that code paste site is.
here is a link that should last
http://users.on.net/~bobjob/nehe/Lesson27.java (http://users.on.net/~bobjob/nehe/Lesson27.java) code
http://users.on.net/~bobjob/nehe/Object2.txt (http://users.on.net/~bobjob/nehe/Object2.txt) object
thanx in advance, this is realllly drivn me nuts cant understand why it wont work.
I'll assume you aren't Mark Bernard and didn't write the code and won't mind me bashing it.... It was HORRIBLE code :-\
Well, horrible code aside, I did get it to render correctly. The code, as written in the LWJGL port of the NeHe tutorial, didn't come close to working (the author probably never actually tried it ::)).
I'll try paste the methods I changed:
private void initGL() { // All Setup For OpenGL Goes Here
initGLObjects();
int width = 640;
int height = 480;
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
GL11.glClearDepth(1.0f); // Depth Buffer Setup
GL11.glClearStencil(0); // Stencil Buffer Setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations
floatBuffer = ByteBuffer.allocateDirect(64).order(ByteOrder.nativeOrder()).asFloatBuffer();
byteBuffer = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder());
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, (FloatBuffer)floatBuffer.put(lightPos).flip()); // Set Light1 Position
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer)floatBuffer.put(lightAmb).flip()); // Set Light1 Ambience
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)floatBuffer.put(lightDif).flip()); // Set Light1 Diffuse
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_SPECULAR, (FloatBuffer)floatBuffer.put(lightSpc).flip()); // Set Light1 Specular
GL11.glEnable(GL11.GL_LIGHT1); // Enable Light1
GL11.glEnable(GL11.GL_LIGHTING); // Enable Lighting
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT, (FloatBuffer)floatBuffer.put(matAmb).flip()); // Set Material Ambience
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, (FloatBuffer)floatBuffer.put(matDif).flip()); // Set Material Diffuse
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR, (FloatBuffer)floatBuffer.put(matSpc).flip()); // Set Material Specular
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SHININESS, (FloatBuffer)floatBuffer.put(matShn).flip()); // Set Material Shininess
GL11.glCullFace(GL11.GL_BACK); // Set Culling Face To Back Face
GL11.glEnable(GL11.GL_CULL_FACE); // Enable Culling
GL11.glClearColor(0.1f, 1.0f, 0.5f, 1.0f); // Set Clear Color (Greenish Color)
q = new Sphere(); // Initialize Quadratic
q.setNormals(GL11.GL_SMOOTH); // Enable Smooth Normal Generation
q.setTextureFlag(false); // Disable Auto Texture Coords
GL11.glViewport(0,0,width,height); // Reset The Current Viewport
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
GL11.glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(45.0f,
(float) displayMode.getWidth() / (float) displayMode.getHeight(),
0.05f,100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
GL11.glLoadIdentity(); // Reset The Modelview Matrix
}
private void render() {
float Minv[] = new float[16];
float wlp[] = new float[4];
float lp[] = new float[4];
// Clear Color Buffer, Depth Buffer, Stencil Buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
GL11.glLoadIdentity(); // Reset Modelview Matrix
GL11.glTranslatef(0.0f, 0.0f, -20.0f); // Zoom Into Screen 20 Units
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, (FloatBuffer)byteBuffer.asFloatBuffer().put(lightPos).flip()); // Position Light1
GL11.glTranslatef(spherePos[0], spherePos[1], spherePos[2]); // Position The Sphere
q.draw(1.5f, 32, 16); // Draw A Sphere
// calculate light's position relative to local coordinate system
// dunno if this is the best way to do it, but it actually works
// if u find another aproach, let me know ;)
// we build the inversed matrix by doing all the actions in reverse order
// and with reverse parameters (notice -xrot, -yrot, -ObjPos[], etc.)
GL11.glLoadIdentity(); // Reset Matrix
GL11.glRotatef(-yrot, 0.0f, 1.0f, 0.0f); // Rotate By -yrot On Y Axis
GL11.glRotatef(-xrot, 1.0f, 0.0f, 0.0f); // Rotate By -xrot On X Axis
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, (FloatBuffer)floatBuffer.clear()); // Retrieve ModelView Matrix (Stores In Minv)
floatBuffer.get(Minv, 0, 16);
lp[0] = lightPos[0]; // Store Light Position X In lp[0]
lp[1] = lightPos[1]; // Store Light Position Y In lp[1]
lp[2] = lightPos[2]; // Store Light Position Z In lp[2]
lp[3] = lightPos[3]; // Store Light Direction In lp[3]
vMatMult(Minv, lp); // We Store Rotated Light Vector In 'lp' Array
GL11.glTranslatef(-objPos[0], -objPos[1], -objPos[2]); // Move Negative On All Axis Based On ObjPos[] Values (X, Y, Z)
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX,(FloatBuffer)floatBuffer.clear()); // Retrieve ModelView Matrix From Minv
floatBuffer.get(Minv, 0, 16);
wlp[0] = 0.0f; // World Local Coord X To 0
wlp[1] = 0.0f; // World Local Coord Y To 0
wlp[2] = 0.0f; // World Local Coord Z To 0
wlp[3] = 1.0f;
vMatMult(Minv, wlp); // We Store The Position Of The World Origin Relative To The
// Local Coord. System In 'wlp' Array
lp[0] += wlp[0]; // Adding These Two Gives Us The
lp[1] += wlp[1]; // Position Of The Light Relative To
lp[2] += wlp[2]; // The Local Coordinate System
GL11.glColor4f(0.7f, 0.4f, 0.0f, 1.0f); // Set Color To An Orange
GL11.glLoadIdentity(); // Reset Modelview Matrix
GL11.glTranslatef(0.0f, 0.0f, -20.0f); // Zoom Into The Screen 20 Units
drawGLRoom(); // Draw The Room
GL11.glTranslatef(objPos[0], objPos[1], objPos[2]); // Position The Object
GL11.glRotatef(xrot, 1.0f, 0.0f, 0.0f); // Spin It On The X Axis By xrot
GL11.glRotatef(yrot, 0.0f, 1.0f, 0.0f); // Spin It On The Y Axis By yrot
drawGLObject(obj); // Procedure For Drawing The Loaded Object
castShadow(obj, lp); // Procedure For Casting The Shadow Based On The Silhouette
GL11.glColor4f(0.7f, 0.4f, 0.0f, 1.0f); // Set Color To Purplish Blue
GL11.glDisable(GL11.GL_LIGHTING); // Disable Lighting
GL11.glDepthMask(false); // Disable Depth Mask
GL11.glTranslatef(lp[0], lp[1], lp[2]); // Translate To Light's Position
// Notice We're Still In Local Coordinate System
q.draw(0.2f, 16, 8); // Draw A Little Yellow Sphere (Represents Light)
GL11.glEnable(GL11.GL_LIGHTING); // Enable Lighting
GL11.glDepthMask(true); // Enable Depth Mask
xrot += xspeed; // Increase xrot By xspeed
yrot += yspeed; // Increase yrot By yspeed
GL11.glFlush(); // Flush The OpenGL Pipeline
}
// connectivity procedure - based on Gamasutra's article
// hard to explain here
private void setConnectivity(GlObject o) {
int p1i, p2i, p1j, p2j;
int P1i, P2i, P1j, P2j;
int i,j,ki,kj;
for(i=0;i<o.nPlanes-1;i++) {
for(j=i+1;j<o.nPlanes;j++) {
for(ki=0;ki<3;ki++) {
if(o.planes[i].neigh[ki] == 0){
for(kj=0;kj<3;kj++){
p1i=ki;
p1j=kj;
p2i=(ki+1)%3;
p2j=(kj+1)%3;
p1i=o.planes[i].p[p1i];
p2i=o.planes[i].p[p2i];
p1j=o.planes[j].p[p1j];
p2j=o.planes[j].p[p2j];
P1i=((p1i+p2i)-Math.abs(p1i-p2i))/2;
P2i=((p1i+p2i)+Math.abs(p1i-p2i))/2;
P1j=((p1j+p2j)-Math.abs(p1j-p2j))/2;
P2j=((p1j+p2j)+Math.abs(p1j-p2j))/2;
if((P1i==P1j) && (P2i==P2j)){ //they are neighbours
o.planes[i].neigh[ki] = j+1;
o.planes[j].neigh[kj] = i+1;
}
}
}
}
}
}
}
private void castShadow(GlObject o, float lp[]){
int i;
float side;
//set visual parameter
for (i=0;i<o.nPlanes;i++){
// chech to see if light is in front or behind the plane (face plane)
side = o.planes[i].planeEq.a*lp[0]+
o.planes[i].planeEq.b*lp[1]+
o.planes[i].planeEq.c*lp[2]+
o.planes[i].planeEq.d;
if (side >0) o.planes[i].visible = true;
else o.planes[i].visible = false;
}
GL11.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT
| GL11.GL_ENABLE_BIT | GL11.GL_POLYGON_BIT | GL11.GL_STENCIL_BUFFER_BIT);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDepthMask(false);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glEnable(GL11.GL_STENCIL_TEST);
GL11.glColorMask(false, false, false, false);
GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0xffffffff);
// first pass, stencil operation increases stencil value
GL11.glFrontFace(GL11.GL_CCW);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_INCR);
doShadowPass(o, lp);
// second pass, stencil operation decreases stencil value
GL11.glFrontFace(GL11.GL_CW);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_DECR);
doShadowPass(o, lp);
GL11.glFrontFace(GL11.GL_CCW);
GL11.glColorMask(true, true, true, true);
//draw a shadowing rectangle covering the entire screen
GL11.glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glStencilFunc(GL11.GL_NOTEQUAL, 0, 0xffffffff);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glVertex3f(-0.1f, 0.1f,-0.10f);
GL11.glVertex3f(-0.1f,-0.1f,-0.10f);
GL11.glVertex3f( 0.1f, 0.1f,-0.10f);
GL11.glVertex3f( 0.1f,-0.1f,-0.10f);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glPopAttrib();
}
private void doShadowPass(GlObject o, float[] lp){
int i, j, k, jj;
int p1, p2;
Point v3 = new Point();
Point v4 = new Point();
for (i=0; i<o.nPlanes;i++){
if (o.planes[i].visible)
for (j=0;j<3;j++){
k = o.planes[i].neigh[j];
if ((k != 0) || (!o.planes[k-1].visible)){
// here we have an edge, we must draw a polygon
p1 = o.planes[i].p[j];
jj = (j+1)%3;
p2 = o.planes[i].p[jj];
//calculate the length of the vector
v3.x = (o.points[p1].x - lp[0])*100;
v3.y = (o.points[p1].y - lp[1])*100;
v3.z = (o.points[p1].z - lp[2])*100;
v4.x = (o.points[p2].x - lp[0])*100;
v4.y = (o.points[p2].y - lp[1])*100;
v4.z = (o.points[p2].z - lp[2])*100;
//draw the polygon
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glVertex3f(o.points[p1].x,
o.points[p1].y,
o.points[p1].z);
GL11.glVertex3f(o.points[p1].x + v3.x,
o.points[p1].y + v3.y,
o.points[p1].z + v3.z);
GL11.glVertex3f(o.points[p2].x,
o.points[p2].y,
o.points[p2].z);
GL11.glVertex3f(o.points[p2].x + v4.x,
o.points[p2].y + v4.y,
o.points[p2].z + v4.z);
GL11.glEnd();
}
}
}
}
}
Basically I changed the use of java.nio buffers to be used correctly and an 'if' that was wrong. Maybe some other tidbits around...
Hope that helps ;D
hmmm, dang im not sure which version i pasted, there is the lwjgl source from the nehe site, which doesnt even load models properly, I could only go as far as to fix that. there is also the version that i just coppied off the visual c++ version to java best i could.
thanx for trying. I give up! im going to leave shadows till last.
ohhhhh you worked out how to actually fix it (didnt relise), i added the changes you put in, thanx man, your a gun!