hello
iam trying to recode the "Stencil Shadow Volume" from C to java, but i dont know why, i cant get it to work, althrough its the same
netbeans project : http://www.politea.sk/tmp/Shadows.zip
iam trying to recode the "Stencil Shadow Volume" from C to java, but i dont know why, i cant get it to work, althrough its the same
netbeans project : http://www.politea.sk/tmp/Shadows.zip
PHP:
package org.yourorghere;
import com.sun.opengl.impl.windows.PIXELFORMATDESCRIPTOR;
import java.awt.*;
import java.awt.event.*;
import javax.media.opengl.*;
import com.sun.opengl.util.*;
import javax.media.opengl.glu.GLU;
public class Shadows implements GLEventListener, MouseListener, MouseMotionListener, MouseWheelListener, KeyListener {
boolean g_bRenderShadowVolume = true;
float g_fAmountOfExtrusion = 5.0f;
float g_lightPosition[] = { 2.0f, 6.0f, 0.0f, 1.0f }; // World position of light source
static float view_scale = 1.0f;
// GL_C3F_V3F
public class Vertex {
public float r, g, b;
public float x, y, z;
private Vertex(float ir, float ig, float ib, float ix,float iy, float iz) {
r = ir; g = ig; b = ib; x = ix; y = iy; z = iz;
}
public float getX() {return x;}
};
public Vertex[] g_shadowCasterVerts =
{
new Vertex(1.0f, 1.0f, 1.0f, -1.0f, 2.5f, -1.0f),
new Vertex(1.0f, 1.0f, 1.0f, -1.0f, 2.5f, 1.0f ),
new Vertex(1.0f, 1.0f, 1.0f, 1.0f, 2.5f, 1.0f ),
new Vertex(1.0f, 1.0f, 1.0f, 1.0f, 2.5f, -1.0f ),
};
public float[] g_shadowCasterNormal = { 0.0f, 1.0f, 0.0f };
class ShadowCaster {
Vertex[] verts;// = new Vertex(0f,0f,0f,0f,0f,0f); // Vertices of the actual shadow casting object
float[] normal; // A surface normal for lighting
int numVerts; // Total number of vertices
int shadowVolume; // Display list for holding the shadow volume
};
ShadowCaster g_shadowCaster = new ShadowCaster();
public static void main(String[] args)
{
Frame frame = new Frame("Simple JOGL Application");
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new Shadows());
frame.add(canvas);
frame.setSize(640, 480);
final Animator animator = new Animator(canvas);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
// Run this on another thread than the AWT event queue to
// make sure the call to Animator.stop() completes before
// exiting
new Thread(new Runnable()
{
public void run()
{
animator.stop();
System.exit(0);
}
}).start();
}
});
// Center frame
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();
}
void extendVertex(float[] newVert, float[] lightPosit, Vertex vert, float ext) {
float[] lightDir = new float[3];
// Create a vector that points from the light's position to the original vertex.
lightDir[0] = vert.x - lightPosit[0];
lightDir[1] = vert.y - lightPosit[1];
lightDir[2] = vert.z - lightPosit[2];
// Then use that vector to extend the original vertex out to a new position.
// The distance to extend or extrude the new vector is specified by t.
newVert[0] = lightPosit[0] + lightDir[0] * ext;
newVert[1] = lightPosit[1] + lightDir[1] * ext;
newVert[2] = lightPosit[2] + lightDir[2] * ext;
}
void buildShadowVolume(GLAutoDrawable drawable, ShadowCaster caster, float[] lightPosit, float ext ) {
GL gl = drawable.getGL();
if ( caster.shadowVolume != -1 )
gl.glDeleteLists( caster.shadowVolume, 0 );
caster.shadowVolume = gl.glGenLists(1);
gl.glNewList( caster.shadowVolume, gl.GL_COMPILE );
{
gl.glDisable( gl.GL_LIGHTING );
gl.glBegin( gl.GL_QUADS );
{
gl.glColor3f( 0.2f, 0.8f, 0.4f );
float[] vExtended = new float[3];
//
// For each vertex of the shadow casting object, find the edge
// that it helps define and extrude a quad out from that edge.
//
for( int i = 0; i < caster.numVerts; ++i )
{
// Define the edge we're currently working on extruding...
int e0 = i;
int e1 = i+1;
// If the edge's second vertex is out of array range,
// place it back at 0
if( e1 >= caster.numVerts )
e1 = 0;
// v0 of our extruded quad will simply use the edge's first
// vertex or e0.
gl.glVertex3f(caster.verts[e0].x, caster.verts[e0].y, caster.verts[e0].z);
// v1 of our quad is created by taking the edge's first
// vertex and extending it out by some amount.
extendVertex(vExtended, lightPosit, caster.verts[e0], ext);
gl.glVertex3f(vExtended[0], vExtended[1], vExtended[2]);
// v2 of our quad is created by taking the edge's second
// vertex and extending it out by some amount.
extendVertex( vExtended, lightPosit, caster.verts[e1], ext );
gl.glVertex3f( vExtended[0], vExtended[1], vExtended[2] );
// v3 of our extruded quad will simply use the edge's second
// vertex or e1.
gl.glVertex3f( caster.verts[e1].x, caster.verts[e1].y, caster.verts[e1].z );
}
}
gl.glEnd();
gl.glEnable( gl.GL_LIGHTING );
}
gl.glEndList();
}
void renderScene(GLAutoDrawable drawable) {
//
// Place the view
//
GL gl = drawable.getGL();
GLUT glut = new GLUT();
gl.glMatrixMode( gl.GL_MODELVIEW );
gl.glLoadIdentity();
gl.glTranslatef( 0.0f, -2.0f, -15.0f );
//gl.glRotatef( 0, 1.0f, 0.0f, 0.0f );
//gl.glRotatef( 0, 0.0f, 1.0f, 0.0f );
//gl.glRotatef(90, 1, 0, 0);
if (mouseRButtonDown) {
view_scale += (prevMouseY - nowMouseY) / 10000f;
}
//gl.glScalef(view_scale, view_scale, view_scale);
gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
//
// Render the floor...
//
gl.glPushMatrix();
{
gl.glBegin( gl.GL_QUADS );
{
gl.glNormal3f( 0.0f, 1.0f, 0.0f );
gl.glVertex3f(-5.0f, 0.0f, -5.0f );
gl.glVertex3f(-5.0f, 0.0f, 5.0f );
gl.glVertex3f( 5.0f, 0.0f, 5.0f );
gl.glVertex3f( 5.0f, 0.0f, -5.0f );
}
gl.glEnd();
}
gl.glPopMatrix();
//
// Render a teapot so we'll have something else to cast a shadow on
// besides the floor.
//
gl.glPushMatrix();
{
gl.glTranslatef( -2.0f, 0.8f, 0.0f );
gl.glRotatef( 180.0f, 0.0f, 1.0f, 0.0f );
gl.glColor3f( 1.0f, 1.0f ,1.0f );
glut.glutSolidTeapot(1.0);
}
gl.glPopMatrix();
//
// Render the light's position as a sphere...
//
gl.glDisable( gl.GL_LIGHTING );
gl.glPushMatrix();
{
// Place the light...
gl.glLightfv( gl.GL_LIGHT0, gl.GL_POSITION, g_lightPosition, 0);
// Place a sphere to represent the light
gl.glTranslatef( g_lightPosition[0], g_lightPosition[1], g_lightPosition[2] );
gl.glColor3f(1.0f, 1.0f, 0.5f);
glut.glutSolidSphere( 0.1, 8, 8 );
}
gl.glPopMatrix();
gl.glEnable( gl.GL_LIGHTING );
//
// Render the shadow caster (i.e. the quad)
//
gl.glPushMatrix();
{
// Hmmm... I can't transform the shadow caster unless the
// buildShadowVolume function is able to take this into account.
// This is because the shadow volume is built in world space.
//glTranslatef( 0.0f, 2.5f, 0.0f );
//glRotatef( -g_fSpinY_R, 1.0f, 0.0f, 0.0f );
//glRotatef( -g_fSpinX_R, 0.0f, 1.0f, 0.0f );
gl.glBegin( gl.GL_POLYGON );
{
gl.glNormal3f(g_shadowCaster.normal[0],g_shadowCaster.normal[1], g_shadowCaster.normal[2]);
for( int i = 0; i < g_shadowCaster.numVerts; ++i )
{
gl.glVertex3f( g_shadowCaster.verts[i].x, g_shadowCaster.verts[i].y, g_shadowCaster.verts[i].z );
}
}
gl.glEnd();
}
gl.glPopMatrix();
}
public void init(GLAutoDrawable drawable)
{
// Use debug pipeline
// drawable.setGL(new DebugGL(drawable.getGL()));
//PIXELFORMATDESCRIPTOR pfd = null;
//pfd.nVersion((short)1);
//pfd.dwFlags( PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER);
//pfd.iPixelType(PFD_TYPE_RGBA);
//pfd.cColorBits((byte)16);
//pfd.cDepthBits((byte)16);
//pfd.cStencilBits((byte)8);
//int PixelFormat;
//g_hDC = GetDC( g_hWnd );
//PixelFormat = ChoosePixelFormat( g_hDC, &pfd );
//SetPixelFormat( g_hDC, PixelFormat, &pfd);
//g_hRC = wglCreateContext( g_hDC );
//wglMakeCurrent( g_hDC, g_hRC );
GL gl = drawable.getGL();
GLU glu = new GLU();
//System.err.println("INIT GL IS: " + gl.getClass().getName());
gl.glClearStencil(128);
// Enable VSync
gl.setSwapInterval(1);
// Setup the drawing area and shading mode
//gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.
gl.glClearColor( 0.35f, 0.53f, 0.7f, 1.0f );
gl.glEnable(gl.GL_LIGHTING);
gl.glEnable(gl.GL_LIGHT0);
gl.glEnable(gl.GL_DEPTH_TEST);
gl.glMatrixMode( gl.GL_PROJECTION );
gl.glLoadIdentity();
glu.gluPerspective( 45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
// Enable a single OpenGL light.
float[] lightAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
float[] lightSpecular = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, lightDiffuse, 0);
gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR, lightSpecular, 0);
gl.glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT, lightAmbient, 0);
//
// Set up the shadow caster...
//
g_shadowCaster.verts = g_shadowCasterVerts;
g_shadowCaster.normal = g_shadowCasterNormal;
g_shadowCaster.numVerts = (4);
g_shadowCaster.shadowVolume = -1;
drawable.addMouseListener(this);
drawable.addMouseMotionListener(this);
drawable.addMouseWheelListener(this);
drawable.addKeyListener(this);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
GL gl = drawable.getGL();
GLU glu = new GLU();
if (height <= 0) // avoid a divide by zero error!
height = 1;
final float h = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, h, 1.0, 20.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void display(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
//
// Using the light's position, extend or extrude each vertex of the shadow
// caster out by an amount specified by g_fAmountOfExtrusion.
//
buildShadowVolume(drawable, g_shadowCaster, g_lightPosition, g_fAmountOfExtrusion );
//
// Prepare to render a new scene by clearing out all of the buffers.
//
gl.glClear( gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT | gl.GL_STENCIL_BUFFER_BIT );
// Initialize the depth buffer by rendering the scene into it.
gl.glColorMask( false, false, false, false );
renderScene(drawable);
//
// Create the special shadow stencil...
//
// Set the appropriate states for creating a stencil for shadowing.
gl.glEnable( gl.GL_CULL_FACE );
gl.glEnable( gl.GL_STENCIL_TEST );
gl.glDepthMask(false);
//gl.glDisable(GL.GL_DEPTH_TEST);
gl.glStencilFunc( gl.GL_ALWAYS, 0, 0 );
// Render the shadow volume and increment the stencil every where a front
// facing polygon is rendered.
gl.glStencilOp( gl.GL_KEEP, gl.GL_KEEP, gl.GL_INCR );
gl.glCullFace( gl.GL_BACK );
gl.glCallList( g_shadowCaster.shadowVolume );
// Render the shadow volume and decrement the stencil every where a back
// facing polygon is rendered.
gl.glStencilOp( gl.GL_KEEP, gl.GL_KEEP, gl.GL_DECR );
gl.glCullFace( gl.GL_FRONT );
gl.glCallList( g_shadowCaster.shadowVolume );
// When done, set the states back to something more typical.
gl.glDepthMask( true );
gl.glDepthFunc( gl.GL_LEQUAL );
gl.glColorMask( true, true, true, true );
gl.glStencilOp( gl.GL_KEEP, gl.GL_KEEP, gl.GL_KEEP );
gl.glCullFace( gl.GL_BACK );
gl.glDisable( gl.GL_CULL_FACE );
//
// Render the shadowed part...
//
gl.glStencilFunc( gl.GL_EQUAL, 1, 1 );
gl.glDisable( gl.GL_LIGHT0 );
renderScene(drawable);
//
// Render the lit part...
//
gl.glStencilFunc( gl.GL_EQUAL, 0, 1 );
gl.glEnable( gl.GL_LIGHT0 );
renderScene(drawable);
// When done, set the states back to something more typical.
gl.glDepthFunc( gl.GL_LESS );
gl.glDisable( gl.GL_STENCIL_TEST );
if( g_bRenderShadowVolume )
{
gl.glPolygonMode( gl.GL_FRONT_AND_BACK, gl.GL_LINE );
gl.glCallList( g_shadowCaster.shadowVolume );
gl.glPolygonMode( gl.GL_FRONT_AND_BACK, gl.GL_FILL );
}
//gl.SwapBuffers(1);
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
{}
static int prevMouseX = 0, prevMouseY = 0, nowMouseX, nowMouseY;
static boolean mouseRButtonDown = false;
private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
public void mouseClicked(MouseEvent e) {
//prevMouseX = e.getX();
//prevMouseY = e.getY();
//System.out.println("Pressed");
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mousePressed(MouseEvent e) {
if ((e.getModifiers() & e.BUTTON1_MASK) != 0) {
//view_scale += 0.5;
}
if ((e.getModifiers() & e.BUTTON3_MASK) != 0) {
//view_scale -= 0.5;
}
prevMouseX = e.getX();
prevMouseY = e.getY();
//System.out.println("Pressed");
//throw new UnsupportedOperationException("Not supported yet.");
if ((e.getModifiers() & e.BUTTON3_MASK) != 0) {
mouseRButtonDown = true;
}
}
public void mouseReleased(MouseEvent e) {
if ((e.getModifiers() & e.BUTTON3_MASK) != 0) {
mouseRButtonDown = false;
}
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseEntered(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseExited(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseDragged(MouseEvent e) {
//System.out.println("> " + e.getY() + " #" + prevMouseY);
if ((e.getModifiers() & e.BUTTON3_MASK) != 0) {
nowMouseX = e.getX();
nowMouseY = e.getY();
//if (e.getY() > prevMouseY) {
// view_scale += (e.getY() - prevMouseY) / 10000f;
//} else {
//}
//System.out.println(Float.toString((e.getY() - prevMouseY) / 1000f));
//view_scale += 0.01;
//System.out.println(Float.toString(view_scale));
}
if ((e.getModifiers() & e.BUTTON1_MASK) != 0) {
int x = e.getX();
int y = e.getY();
Dimension size = e.getComponent().getSize();
float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width);
float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height);
prevMouseX = x;
prevMouseY = y;
view_rotx += thetaX;
view_roty += thetaY;
}
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseMoved(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseWheelMoved(MouseWheelEvent e) {
//System.out.println("");
if (e.getWheelRotation() < 0) {
view_scale += 0.1;
} else {
view_scale -= 0.1;
}
//throw new UnsupportedOperationException("Not supported yet.");
}
public void keyTyped(KeyEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void keyPressed(KeyEvent e) {
//System.out.print("dfsdf");
if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_F5) {
g_lightPosition[0] += 0.1f;
}
if (key == KeyEvent.VK_F6) {
g_lightPosition[0] -= 0.1f;
}
if (key == KeyEvent.VK_F7) {
g_lightPosition[1] += 0.1f;
}
if (key == KeyEvent.VK_F8) {
g_lightPosition[1] -= 0.1f;
}
}
}
public void keyReleased(KeyEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
}