491 lines
12 KiB
Java
491 lines
12 KiB
Java
/*
|
|
* Copyright (c) 2002 Lightweight Java Game Library Project
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of 'Light Weight Java Game Library' nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* $Id$
|
|
*
|
|
* Simple java test program.
|
|
*
|
|
* @author elias_naur <elias_naur@users.sourceforge.net>
|
|
* @version $Revision$
|
|
*/
|
|
|
|
package org.lwjgl.test.opengl;
|
|
|
|
import org.lwjgl.input.*;
|
|
import org.lwjgl.opengl.*;
|
|
import org.lwjgl.*;
|
|
|
|
import java.io.*;
|
|
import java.nio.*;
|
|
import java.util.*;
|
|
|
|
public class Grass {
|
|
|
|
static class Aslod {
|
|
float angle;
|
|
float value;
|
|
float ripple;
|
|
float count;
|
|
}
|
|
private static boolean finished = false;
|
|
private static Random rand = new Random();
|
|
|
|
static {
|
|
try {
|
|
int mode = -1;
|
|
DisplayMode[] modes = Display.getAvailableDisplayModes();
|
|
for (int i = 0; i < modes.length; i++) {
|
|
if (modes[i].width == 640
|
|
&& modes[i].height == 480
|
|
&& modes[i].bpp >= 16) {
|
|
mode = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mode == -1) {
|
|
System.out.println("did not find suitable mode");
|
|
} else {
|
|
System.out.println("Display mode: " + modes[mode]);
|
|
}
|
|
// For now let's just pick a mode we're certain to have
|
|
|
|
Display.setDisplayMode(modes[mode]);
|
|
System.out.println("Created display.");
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
public static final GLWindow gl = new GLWindow("LWJGL Grass", 50, 50, 640, 480, 16, 0, 0,0);
|
|
|
|
static {
|
|
try {
|
|
gl.create();
|
|
Keyboard.create();
|
|
Keyboard.enableBuffer();
|
|
Mouse.create();
|
|
System.out.println("Created OpenGL.");
|
|
} catch (Exception e) {
|
|
System.err.println("Failed to create OpenGL due to " + e);
|
|
System.exit(1);
|
|
}
|
|
|
|
}
|
|
|
|
private static Aslod aslod = new Aslod();
|
|
|
|
private static int mesh;
|
|
private static int program_handle;
|
|
|
|
private static byte[] loadFile(String file) {
|
|
int next;
|
|
java.util.Vector bytes = new java.util.Vector();
|
|
try {
|
|
ClassLoader loader = Grass.class.getClassLoader();
|
|
InputStream stream = new BufferedInputStream(loader.getResourceAsStream(file));
|
|
while ((next = (stream.read())) != -1)
|
|
bytes.add(new Byte((byte) next));
|
|
stream.close();
|
|
byte[] result = new byte[bytes.size()];
|
|
for (int i = 0; i < result.length; i++)
|
|
result[i] = ((Byte) bytes.get(i)).byteValue();
|
|
return result;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
ByteBuffer byte_buf = ByteBuffer.allocateDirect(4);
|
|
byte_buf.order(ByteOrder.nativeOrder());
|
|
GLCaps.determineAvailableExtensions();
|
|
System.out.println("Vertex program supported: " + GLCaps.GL_NV_vertex_program);
|
|
GL.glGenProgramsNV(1, byte_buf.asIntBuffer());
|
|
IntBuffer int_buf = byte_buf.asIntBuffer();
|
|
if (int_buf.get(0) == 0)
|
|
throw new RuntimeException("Could not allocate new vertex program id!");
|
|
|
|
program_handle = int_buf.get(0);
|
|
byte[] program = loadFile("cg_grass2.vp");
|
|
ByteBuffer program_buf = ByteBuffer.allocateDirect(program.length);
|
|
program_buf.order(ByteOrder.nativeOrder());
|
|
program_buf.rewind();
|
|
program_buf.put(program);
|
|
program_buf.rewind();
|
|
GL.glLoadProgramNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
program_handle,
|
|
program_buf.remaining(),
|
|
program_buf);
|
|
/*gl.getIntegerv(GL.PROGRAM_ERROR_POSITION_NV, Sys.getDirectBufferAddress(int_buf));
|
|
System.out.println("error position: " + int_buf.get(0));*/
|
|
|
|
genMesh();
|
|
|
|
float[] LightDiffuse = { 1.0f, 0.0f, 0.0f, 1.0f };
|
|
float[] LightPosition = { 1.0f, 1.0f, 1.0f, 0.0f };
|
|
ByteBuffer light_buf = ByteBuffer.allocateDirect(4 * 4);
|
|
light_buf.order(ByteOrder.nativeOrder());
|
|
FloatBuffer light_buf_f = light_buf.asFloatBuffer();
|
|
light_buf_f.rewind();
|
|
light_buf_f.put(LightDiffuse);
|
|
|
|
GL.glLightfv(
|
|
GL.GL_LIGHT0,
|
|
GL.GL_DIFFUSE,
|
|
light_buf_f);
|
|
light_buf_f.rewind();
|
|
light_buf_f.put(LightPosition);
|
|
GL.glLightfv(
|
|
GL.GL_LIGHT0,
|
|
GL.GL_POSITION,
|
|
light_buf_f);
|
|
GL.glEnable(GL.GL_LIGHT0);
|
|
GL.glEnable(GL.GL_LIGHTING);
|
|
GL.glEnable(GL.GL_DEPTH_TEST);
|
|
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
|
|
GL.glEnable(GL.GL_BLEND);
|
|
GL.glMatrixMode(GL.GL_PROJECTION);
|
|
GLU.gluPerspective(40.0, 1.0, 1.0, 50.0);
|
|
GL.glMatrixMode(GL.GL_MODELVIEW);
|
|
|
|
GLU.gluLookAt(14.0, 10.0, -16.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
|
|
|
aslod.angle = 2.6179935f;
|
|
aslod.value = 0.2f;
|
|
aslod.ripple = 0.0f;
|
|
aslod.count = 0.0f;
|
|
|
|
while (!finished) {
|
|
keyPoll();
|
|
float degree = (1.0f + (aslod.value * 20.0f)) * 0.01745329f;
|
|
|
|
degree *= (0.5 + myrand());
|
|
|
|
ptrAnimate(degree);
|
|
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
|
|
|
//ptrDraw();
|
|
|
|
grsDraw();
|
|
|
|
gl.paint();
|
|
}
|
|
Mouse.destroy();
|
|
Keyboard.destroy();
|
|
gl.destroy();
|
|
}
|
|
|
|
private static float myrand() {
|
|
// returns a value between 0 and 1
|
|
return rand.nextFloat();
|
|
}
|
|
|
|
private static void genGrass(
|
|
float fFaceHeight,
|
|
float fFaceWidth,
|
|
float fX,
|
|
float fZ) {
|
|
int cFaces;
|
|
int numFaces;
|
|
float cWidth;
|
|
float fDecWidth, frndWidth, frndHeight;
|
|
float fRotate;
|
|
float fRigid;
|
|
|
|
numFaces = 5;
|
|
frndHeight =
|
|
fFaceHeight
|
|
+ ((fFaceHeight / 1.5f)
|
|
* (float) java.lang.Math.cos(
|
|
java.lang.Math.abs(rand.nextInt())));
|
|
frndWidth =
|
|
fFaceWidth
|
|
+ ((fFaceWidth / 4.0f)
|
|
* (float) java.lang.Math.cos(
|
|
java.lang.Math.abs(rand.nextInt())));
|
|
fDecWidth = frndWidth / 5.0f;
|
|
fRotate = myrand() * 3.1415f;
|
|
fRigid = ((fRigid = myrand()) < 0.2f) ? 0.2f : fRigid;
|
|
|
|
if (myrand() < 0.3)
|
|
GL.glBegin(GL.GL_LINE_STRIP);
|
|
else
|
|
GL.glBegin(GL.GL_QUAD_STRIP);
|
|
|
|
for (cFaces = 0; cFaces < numFaces; cFaces++) {
|
|
for (cWidth = frndWidth;
|
|
cWidth >= -frndWidth;
|
|
cWidth -= (frndWidth * 2.0f)) {
|
|
GL.glColor4f(fX, fRigid, fZ, (float) cFaces / (float) numFaces);
|
|
GL.glVertex3f(
|
|
(float) (((cFaces - 2) * 0.1f)
|
|
* java.lang.Math.cos(fRotate)
|
|
+ (cWidth) * java.lang.Math.sin(fRotate)),
|
|
cFaces * frndHeight,
|
|
- (float)
|
|
(((cFaces - 2) * 0.1f) * java.lang.Math.sin(fRotate)
|
|
+ (cWidth) * java.lang.Math.cos(fRotate)));
|
|
}
|
|
frndWidth -= fDecWidth;
|
|
}
|
|
GL.glEnd();
|
|
|
|
}
|
|
|
|
private static void genMesh() {
|
|
float cI, cJ, fArea;
|
|
|
|
fArea = 20.0f;
|
|
mesh = GL.glGenLists(1);
|
|
GL.glNewList(mesh, GL.GL_COMPILE);
|
|
for (cI = -fArea / 2; cI < fArea / 2; cI += 0.25f) {
|
|
for (cJ = -fArea / 2; cJ < fArea / 2; cJ += 0.25f) {
|
|
genGrass(0.5f, 0.1f, cI, cJ);
|
|
}
|
|
}
|
|
GL.glEndList();
|
|
}
|
|
|
|
private static void grsDraw() {
|
|
GL.glEnable(GL.GL_VERTEX_PROGRAM_NV);
|
|
GL.glBindProgramNV(GL.GL_VERTEX_PROGRAM_NV, program_handle);
|
|
GL.glTrackMatrixNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
0,
|
|
GL.GL_MODELVIEW_PROJECTION_NV,
|
|
GL.GL_IDENTITY_NV);
|
|
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
4,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
5,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
6,
|
|
1.763609f,
|
|
0.496495f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
7,
|
|
-0.943599f,
|
|
3.203737f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
8,
|
|
4.101107f,
|
|
0.943413f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
9,
|
|
-1.218603f,
|
|
6.259399f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
10,
|
|
7.214299f,
|
|
1.352961f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
11,
|
|
-1.540748f,
|
|
10.080958f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
12,
|
|
10.880035f,
|
|
1.759046f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
13,
|
|
-1.852705f,
|
|
14.468674f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
14,
|
|
14.292879f,
|
|
1.973329f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
15,
|
|
-1.973387f,
|
|
18.506531f,
|
|
0.0f,
|
|
0.0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
16,
|
|
(float) (java.lang.Math.sin(aslod.angle)
|
|
* (aslod.value + aslod.ripple)),
|
|
0.0f,
|
|
(float) (java.lang.Math.cos(aslod.angle)
|
|
* (aslod.value + aslod.ripple)),
|
|
0.0f);
|
|
|
|
GL.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 17, 1.7f, 5f, 2f, 0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
18,
|
|
-0.0187293f,
|
|
0.074261f,
|
|
0.2121144f,
|
|
1.570729f);
|
|
GL.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 20, 0f, 0.5f, 1f, 0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
21,
|
|
0.25f,
|
|
-9f,
|
|
0.75f,
|
|
0.1591549f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
22,
|
|
24.9808f,
|
|
-24.9808f,
|
|
-60.14581f,
|
|
60.14581f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
23,
|
|
85.45379f,
|
|
-85.45379f,
|
|
-64.93935f,
|
|
64.93935f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
24,
|
|
19.73921f,
|
|
-19.73921f,
|
|
-1f,
|
|
1f);
|
|
GL.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 25, 0f, 4f, 0f, 0f);
|
|
GL.glProgramParameter4fNV(
|
|
GL.GL_VERTEX_PROGRAM_NV,
|
|
19,
|
|
1f,
|
|
3.141593f,
|
|
0.5f,
|
|
1f);
|
|
GL.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 26, 0.7f, 0.4f, 0f, 0f);
|
|
GL.glCallList(mesh);
|
|
GL.glDisable(GL.GL_VERTEX_PROGRAM_NV);
|
|
|
|
}
|
|
|
|
/* private static void ptrDraw()
|
|
{
|
|
glRotatef((aslod.angle * 180.0f) / 3.1415f, 0, 1, 0);
|
|
glTranslatef(0, 4.5, -7.5);
|
|
glRotatef(-90, 0, 1, 0);
|
|
glRotatef(-45, 0, 0, 1);
|
|
|
|
glMaterialfv(GL.FRONT, GL.AMBIENT, vec4f(.1f,.1f,0,1).v);
|
|
glMaterialfv(GL.FRONT, GL.DIFFUSE, vec4f(.6f,.6f,.1f,1).v);
|
|
glMaterialfv(GL.FRONT, GL.SPECULAR, vec4f(1,1,.75f,1).v);
|
|
glMaterialf(GL.FRONT, GL.SHININESS, 128.f);
|
|
|
|
glutSolidTeapot(aslod.value*5);
|
|
|
|
gl.rotatef(45, 0, 0, 1);
|
|
gl.totatef(90, 0, 1, 0);
|
|
gl.translatef(0, -4.5, 7.5);
|
|
gl.rotatef(-(aslod.angle * 180.0f) / 3.1415f, 0f, 1f, 0f);
|
|
|
|
}
|
|
*/
|
|
private static void ptrAnimate(float degree) {
|
|
aslod.count += degree;
|
|
aslod.ripple = (float) (java.lang.Math.cos(aslod.count) / 80.0);
|
|
|
|
}
|
|
|
|
private static void keyPoll() {
|
|
Keyboard.read();
|
|
for (int i = 0; i < Keyboard.getNumKeyboardEvents(); i++) {
|
|
Keyboard.next();
|
|
if (!Keyboard.state)
|
|
continue;
|
|
switch (Keyboard.key) {
|
|
case Keyboard.KEY_A :
|
|
aslod.angle += 0.1;
|
|
break;
|
|
case Keyboard.KEY_D :
|
|
aslod.angle -= 0.1;
|
|
break;
|
|
case Keyboard.KEY_W :
|
|
aslod.value += (aslod.value >= 0.15) ? 0.0 : 0.0025;
|
|
break;
|
|
case Keyboard.KEY_S :
|
|
aslod.value -= (aslod.value <= 0.005) ? 0.0 : 0.0025;
|
|
break;
|
|
case Keyboard.KEY_ESCAPE :
|
|
finished = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|