Programming > OpenGL

Nehe Lesson 27 shadows

(1/2) > >>

bobjob:
Does anyone know what i have done wrong, i cant seem to port the lesson over to lwjgl.
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

It runs fine, except there is no shadow.

bobjob:
Iv also tried making the pixel format (0, 16, 1) yet it still wont do anything could it be my video card?

Fool Running:
I was gonna try it out, but the links are dead :-\

bobjob:
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 code
 http://users.on.net/~bobjob/nehe/Object2.txt object

thanx in advance, this is realllly drivn me nuts cant understand why it wont work.

Fool Running:
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:

--- Code: ---    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();
                    }
                }
        }
    }
}

--- End code ---
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

Navigation

[0] Message Index

[#] Next page

Go to full version