diff --git a/src/java/org/lwjgl/test/opengl/Grass.java b/src/java/org/lwjgl/test/opengl/Grass.java new file mode 100644 index 00000000..105e3e8a --- /dev/null +++ b/src/java/org/lwjgl/test/opengl/Grass.java @@ -0,0 +1,320 @@ +import org.lwjgl.input.*; +import org.lwjgl.opengl.*; +import org.lwjgl.*; + +import java.net.*; +import java.io.*; +import java.nio.*; +import java.util.*; + + class Aslod { + float angle; + float value; + float ripple; + float count; + } + +public class Grass { + + private static boolean finished = false; + private static Random rand = new Random(); + + static { + try { + DisplayMode[] modes = Display.getAvailableDisplayModes(); + System.out.println("Available display modes:"); + for (int i = 0; i < modes.length; i ++) + System.out.println(modes[i]); + // For now let's just pick a mode we're certain to have + Display.create(new DisplayMode(800, 600, 16, 60), false); + System.out.println("Created display."); + } catch (Exception e) { + System.err.println("Failed to create display due to "+e); + System.exit(1); + } + } + + public static final GL gl = new GL(16, 0, 16, 8); + public static final GLU glu = new GLU(gl); + 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 = ClassLoader.getSystemClassLoader(); + URL url = loader.getResource(file); + InputStream stream = new BufferedInputStream(url.openStream()); + 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()); + System.out.println("Vertex program supported: " + gl.NV_vertex_program); + gl.genProgramsNV(1, Sys.getDirectBufferAddress(byte_buf)); + 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.loadProgramNV(GL.VERTEX_PROGRAM_NV, program_handle, program_buf.remaining(), Sys.getDirectBufferAddress(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.lightfv(GL.LIGHT0, GL.DIFFUSE, Sys.getDirectBufferAddress(light_buf_f)); + light_buf_f.rewind(); + light_buf_f.put(LightPosition); + gl.lightfv(GL.LIGHT0, GL.POSITION, Sys.getDirectBufferAddress(light_buf_f)); + gl.enable(GL.LIGHT0); + + gl.enable(GL.LIGHTING); + + gl.enable(GL.DEPTH_TEST); + + gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA); + gl.enable(GL.BLEND); + + gl.matrixMode(GL.PROJECTION); + glu.perspective(40.0, 1.0, 1.0, 50.0); + + gl.matrixMode(GL.MODELVIEW); + + glu.lookAt(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.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); + + //ptrDraw(); + + grsDraw(); + + gl.swapBuffers(); + } + Mouse.destroy(); + Keyboard.destroy(); + gl.destroy(); + Display.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.begin(GL.LINE_STRIP); + + else + gl.begin(GL.QUAD_STRIP); + + for (cFaces = 0; cFaces < numFaces; cFaces++) + { + for (cWidth = frndWidth; cWidth >=-frndWidth; cWidth-=(frndWidth * 2.0f)) + { + gl.color4f(fX, fRigid, fZ, (float)cFaces/(float)numFaces); + + gl.vertex3f((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.end(); + + } + + private static void genMesh() { + float cI, cJ, fArea; + + fArea = 20.0f; + mesh = gl.genLists(1); + gl.newList(mesh, 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.endList(); + + } + + private static void grsDraw() + { + gl.enable(GL.VERTEX_PROGRAM_NV); + gl.bindProgramNV(GL.VERTEX_PROGRAM_NV, program_handle); + gl.trackMatrixNV(GL.VERTEX_PROGRAM_NV, 0, GL.MODELVIEW_PROJECTION_NV, GL.IDENTITY_NV); + + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 4, 0.0f, 0.0f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 5, 0.0f, 0.0f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 6, 1.763609f, 0.496495f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 7, -0.943599f, 3.203737f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 8, 4.101107f, 0.943413f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 9, -1.218603f, 6.259399f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 10, 7.214299f, 1.352961f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 11, -1.540748f, 10.080958f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 12, 10.880035f, 1.759046f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 13, -1.852705f, 14.468674f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 14, 14.292879f, 1.973329f, 0.0f, 0.0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 15, -1.973387f, 18.506531f, 0.0f, 0.0f); + gl.programParameter4fNV( 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.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 17, 1.7f, 5f, 2f, 0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 18, -0.0187293f, 0.074261f, 0.2121144f, 1.570729f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 20, 0f, 0.5f, 1f, 0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 21, 0.25f, -9f, 0.75f, 0.1591549f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 22, 24.9808f, -24.9808f, -60.14581f, 60.14581f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 23, 85.45379f, -85.45379f, -64.93935f, 64.93935f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 24, 19.73921f, -19.73921f, -1f, 1f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 25, 0f, 4f, 0f, 0f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 19, 1f, 3.141593f, 0.5f, 1f); + gl.programParameter4fNV( GL.VERTEX_PROGRAM_NV, 26, 0.7f, 0.4f, 0f, 0f); + gl.callList(mesh); + gl.disable(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; + } + } + } + +} + diff --git a/src/java/org/lwjgl/test/opengl/cg_grass2.cg b/src/java/org/lwjgl/test/opengl/cg_grass2.cg new file mode 100644 index 00000000..4a743e9e --- /dev/null +++ b/src/java/org/lwjgl/test/opengl/cg_grass2.cg @@ -0,0 +1,72 @@ +#pragma bind app2vert.position = ATTR0 +#pragma bind app2vert.normal = ATTR2 +#pragma bind app2vert.color = ATTR3 + + +struct app2vert : application2vertex +{ + float4 position; //in object space + float3 normal; //in object space + float4 color; +}; + +#pragma bind vert2frag.HPOS = HPOS +#pragma bind vert2frag.COL0 = COL0 + +struct vert2frag : vertex2fragment +{ + float4 HPOS; + float4 COL0; +}; + +vert2frag main(app2vert IN, + uniform float4x4 ModelViewProj, + uniform float4 Stiff[12], + uniform float4 Load) +{ + vert2frag OUT; + float4 position; + float3 normal; + float3 disloc; + float4 dif; + float index; + float teta; + float alpha; + + alpha = IN.position.y / 1.7; + + // matrix line index + index = IN.color.a * 5 * 2; + + // straw stiffness (randomic) + Load = Load * IN.color.y; + + disloc.x = IN.position.x + dot(Stiff[index].xy, Load.xz); + disloc.y = IN.position.y; + disloc.z = IN.position.z + dot(Stiff[index + 1].xy, Load.xz); + + // find the normal + teta = acos(IN.position.y / length(disloc)); + + normal = IN.position.xyz - disloc.xyz; + normal.y = sin(teta) * length(disloc); + normal = normalize(normal); + + position.x = disloc.x + IN.color.x; + position.y = disloc.y; + position.z = disloc.z + IN.color.z; + position.w = 1; + + OUT.HPOS = mul(ModelViewProj, position); + + // calculate diffuse lighting off the normal that was just calculated + float4 lightPos = float4(0,4,0,0); + float4 lightVec = normalize(lightPos - position); + float diffuseInten = dot(lightVec.xyz, normal); + + diffuseInten = (diffuseInten < 0.5) ? 0.5 : diffuseInten; + + OUT.COL0 = float4(IN.color.y * 0.7, 0.7, 0.4, alpha) * diffuseInten; + + return OUT; +} diff --git a/src/java/org/lwjgl/test/opengl/cg_grass2.vp b/src/java/org/lwjgl/test/opengl/cg_grass2.vp new file mode 100644 index 00000000..892a6430 --- /dev/null +++ b/src/java/org/lwjgl/test/opengl/cg_grass2.vp @@ -0,0 +1,116 @@ +!!VP1.0 +# NV_vertex_program generated by NVIDIA Cg compiler +# cgc version 1.5.0001, build date Sep 12 2002 15:49:58 +# command line args: -profile vp20 cg_grass2.cg +# nv30vp backend compiling 'main' program +#vendor NVIDIA Corporation +#version 1.0.1 +#profile vp20 +#program main +#semantic main.ModelViewProj +#semantic main.Stiff +#semantic main.Load +#var float4 IN.position : $vin.ATTR0 : ATTR0 : 0 : 1 +#var float3 IN.normal : $vin.ATTR2 : ATTR2 : 0 : 1 +#var float4 IN.color : $vin.ATTR3 : ATTR3 : 0 : 1 +#var float4x4 ModelViewProj : : c[0], 4 : 1 : 1 +#var float4 Stiff[0] : : c[4] : 2 : 1 +#var float4 Stiff[1] : : c[5] : 2 : 1 +#var float4 Stiff[2] : : c[6] : 2 : 1 +#var float4 Stiff[3] : : c[7] : 2 : 1 +#var float4 Stiff[4] : : c[8] : 2 : 1 +#var float4 Stiff[5] : : c[9] : 2 : 1 +#var float4 Stiff[6] : : c[10] : 2 : 1 +#var float4 Stiff[7] : : c[11] : 2 : 1 +#var float4 Stiff[8] : : c[12] : 2 : 1 +#var float4 Stiff[9] : : c[13] : 2 : 1 +#var float4 Stiff[10] : : c[14] : 2 : 1 +#var float4 Stiff[11] : : c[15] : 2 : 1 +#var float4 Load : : c[16] : 3 : 1 +#var float4 HPOS : $vout.HPOS : HPOS : -1 : 1 +#var float4 COL0 : $vout.COL0 : COL0 : -1 : 1 +#const c[17] = 1.7 5 2 0 +#const c[18] = -0.0187293 0.074261 0.2121144 1.570729 +#const c[20] = 0 0.5 1 0 +#const c[21] = 0.25 -9 0.75 0.1591549 +#const c[22] = 24.9808 -24.9808 -60.14581 60.14581 +#const c[23] = 85.45379 -85.45379 -64.93935 64.93935 +#const c[24] = 19.73921 -19.73921 -1 1 +#const c[25] = 0 4 0 0 +#const c[19] = 1 3.141593 0.5 1 +#const c[26] = 0.7 0.4 0 0 + MUL R2, c[16], v[3].y; + MUL R0, v[3].w, c[17].y; + MUL R1, R0.x, c[17].z; + ARL A0.x, R1.x; + MUL R0, c[A0.x + 4].xyxx, R2.xzxx; + ADD R0, R0.x, R0.y; + ADD R3.x, v[0].x, R0.x; + MOV R3.y, v[0].y; + MUL R0, c[A0.x + 5].xyxx, R2.xzxx; + ADD R0, R0.x, R0.y; + ADD R3.z, v[0].z, R0.x; + ADD R2.x, R3.x, v[3].x; + MOV R2.y, R3.y; + ADD R2.z, R3.z, v[3].z; + MOV R2.w, c[19].x; + DP4 R0.x, c[0], R2; + DP4 R0.y, c[1], R2; + DP4 R0.z, c[2], R2; + DP4 R0.w, c[3], R2; + MOV o[HPOS], R0; + ADD R1.xz, v[0].xyzx, -R3.xyzx; + DP3 R0, R3.xyzx, R3.xyzx; + RSQ R0, R0.x; + RCP R0, R0.x; + RCP R3, R0.x; + MUL R6, v[0].y, R3.x; + MAX R5, R6.x, -R6.x; + MAD R3, c[18].x, R5.x, c[18].y; + MAD R3, R3.x, R5.x, -c[18].z; + MAD R4, R3.x, R5.x, c[18].w; + ADD R3, c[19].x, -R5.x; + RSQ R3, R3.x; + RCP R3, R3.x; + MUL R5, R4.x, R3.x; + SLT R4, R6.x, c[17].w; + MUL R3, c[17].z, R4.x; + MUL R3, R3.x, R5.x; + ADD R3, R5.x, -R3.x; + MAD R3, R4.x, c[19].y, R3.x; + MAD R6, c[21].w, R3.x, -c[21].x; + EXP R6.y, R6.x; + ADD R3, c[20].xyzx, -R6.yyyy; + MUL R5, R3.xyzx, R3.xyzx; + SLT R4.x, R6.y, c[21].x; + SGE R3, R6.yyyy, c[21].yzyy; + MOV R4.yz, R3.xxyw; + DP3 R4.y, R4.xyzx, c[24].zwzz; + MAD R3, c[22].xyxx, R5.xyzx, c[22].zwzz; + MAD R3, R3.xyzx, R5.xyzx, c[23].xyxx; + MAD R3, R3.xyzx, R5.xyzx, c[23].zwzz; + MAD R3, R3.xyzx, R5.xyzx, c[24].xyxx; + MAD R3, R3.xyzx, R5.xyzx, c[24].zwzz; + DP3 R5.x, R3.xyzx, -R4.xyzx; + MUL R1.y, R5.x, R0.x; + DP3 R0, R1.xyzx, R1.xyzx; + RSQ R0, R0.x; + MUL R3, R0.x, R1.xyzx; + ADD R1, c[25], -R2; + DP4 R0, R1, R1; + RSQ R0, R0.x; + MUL R0, R0.x, R1; + DP3 R2, R0.xyzx, R3.xyzx; + SLT R1, R2.x, c[19].z; + ADD R0, c[19].w, -R1.x; + MUL R0, R0.x, R2.x; + MAD R2, R1.x, c[19].z, R0.x; + MUL R1.x, v[3].y, c[26].x; + MOV R1.y, c[26].x; + MOV R1.z, c[26].y; + RCP R0, c[17].x; + MUL R1.w, v[0].y, R0.x; + MUL o[COL0], R1, R2.x; +END +# 72 instructions +# End of program