import java.nio.*; // Native IO buffers: LWJGL uses these to efficiently exchange data with system memory
import java.util.*;
import org.lwjgl.Sys;
import org.lwjgl.opengl.*;
import org.lwjgl.opengl.glu.GLU;
import org.lwjgl.opengl.glu.Sphere;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.glu.*;
/**
* Circle crawling in random direction, turning random colors and leaving traces on the screen
*/
public class circles {
private boolean done = false;
private final String windowTitle = "Crawlies";
private DisplayMode displayMode;
double startTime, currentTime;
Random rn = new Random();
int randx =0, randy = 0, randz =0;
int randr =0, randg = 0, randb = 0;
float r = .5f, g = .1f, b = .1f;
Sphere s = new Sphere();
float cameraX = 0;
float cameraZ = 10;
float cameraY = 0;
/**
* Main function just creates and runs the application.
*/
public static void main(String args[]) {
circles app = new circles();
app.run();
}
/**
* Initialize the app, then sit in a render loop until done==true.
*/
public void run() {
try {
init();
while (!done) {
mainloop();
render();
Display.update();
}
cleanup();
}
catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
/**
* Initialize the environment
* @throws Exception
*/
private void init() throws Exception {
initDisplay();
initGL();
startTime = currentTime = getTimeInMillis();
}
/**
* Create an OpenGL display, in this case a fullscreen window.
* @throws Exception
*/
private void initDisplay() throws Exception {
// set to full screen, no chrome
Display.setFullscreen(false);
// get all possible display resolutions
DisplayMode d[] = Display.getAvailableDisplayModes();
// find a resolution we like
for (int i = 0; i < d.length; i++) {
if (d[i].getWidth() == 800
&& d[i].getHeight() == 600
&& d[i].getBitsPerPixel() == 32) {
displayMode = d[i];
break;
}
}
Display.setVSyncEnabled(true);
Display.setFullscreen(false);
// set the display to the resolution we picked
Display.setDisplayMode(displayMode);
Display.setTitle(windowTitle);
// create the window
Display.create();
}
/**
* Initialize OpenGL
*
*/
private void initGL() {
// make sure OpenGL correctly layers objects
GL11.glEnable(GL11.GL_DEPTH_TEST);
// OpenGL won't draw backward facing triangles ("back faces")
GL11.glEnable(GL11.GL_CULL_FACE);
// set the background color
GL11.glClearColor(0f, 0f, .07f, 1);
// blending
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// Force normals to length 1
GL11.glEnable(GL11.GL_NORMALIZE);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
/**
* Handle keyboard input. Just check for escape key or user
* clicking to close the window.
*/
private void mainloop() {
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { // Escape is pressed
done = true;
}
if(Display.isCloseRequested()) { // Window is closed
done = true;
}
}
// float backZ=1, frontZ=0;
/**
* Render the scene.
*/
private void render() {
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){
cameraX += .1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){
cameraX -= .1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
cameraZ -= .1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
cameraZ += .1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_A)){
cameraY -= .1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_S)){
cameraY += .1;
}
// Select the Projection Matrix (controls perspective)
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity(); // Reset The Projection Matrix
// Define perspective
GLU.gluPerspective(
45.0f, // Field Of View
(float)displayMode.getWidth() / (float)displayMode.getHeight(), // aspect ratio
0.1f, // near Z clipping plane
100.0f); // far Z clipping plane
// Where is the 'eye'
GLU.gluLookAt(
0f, cameraY, cameraZ, // eye position
cameraX, 0f, 0f, // target to look at
0f, 1f, 0f); // which way is up
GL11.glMatrixMode(GL11.GL_MODELVIEW);
// System.out.println(cameraX);
// Clear screen and depth buffer
// GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
currentTime = getTimeInMillis();
if(currentTime - startTime > 100){ drawCircles();
// drawSun();
// drawGlare();
startTime = currentTime;}
}
private void drawCircles()
{
float x = 0, y = 0, z = 0;
switch(randx){
case 0: x = -.2f; break;
case 1: x = 0; break;
case 2: x = .2f; break;
}
switch(randy){
case 0: y = -.2f; break;
case 1: y = 0; break;
case 2: y = .2f; break;
}
switch(randz){
case 0: z = -.2f; break;
case 1: z = 0; break;
case 2: z = .2f; break;
}
switch(randr){
case 0: r -= .05f; break;
case 1: break;
case 2: r += .05f; break;
}
switch(randg){
case 0: g -= .05f; break;
case 1: break;
case 2: g += .05f; break;
}
switch(randb){
case 0: b -= .05f; break;
case 1: break;
case 2: b += .05f; break;
}
if(r
<0) r =0;
if(r>1) r =1;
if(g<0) g =0;
if(g>1) g =1;
if(b<0) b =0;
if(b>1) b =1;
GL11.glEnable(GL11.GL_BLEND);
GL11.glTranslatef(x, y, z);
GL11.glColor4f(r, g, b, .02f);
renderSphere();
randx = rn.nextInt(3);
randy = rn.nextInt(3);
randz = rn.nextInt(3);
randr = rn.nextInt(3);
randg = rn.nextInt(3);
randb = rn.nextInt(3);
}
/**
* Cleanup all the resources.
*
*/
private void cleanup() {
Display.destroy();
}
/**
* Simple way to setup a light. Uses same color for direct light (diffuse),
* reflected highlight (specular) and scattered light (ambient). Ambient
* color is darkened to 1/4 of the light color.
* @param GLLightHandle
* @param color
* @param position
*/
public static void setLight(int GLLightHandle, float[] color, float[] position )
{
float[] ambientLight = {color[0]/4f, color[1]/4f, color[2]/4f, color[3]/4f};
FloatBuffer lightColor = allocFloats(color);
FloatBuffer ambientColor = allocFloats(ambientLight);
FloatBuffer ltPosition = allocFloats(position);
GL11.glLight(GLLightHandle, GL11.GL_DIFFUSE, lightColor); // color of the direct illumination
GL11.glLight(GLLightHandle, GL11.GL_SPECULAR, lightColor); // color of the highlight (same as direct light)
GL11.glLight(GLLightHandle, GL11.GL_AMBIENT, ambientColor); // color of the scattered light (darker)
GL11.glLight(GLLightHandle, GL11.GL_POSITION, ltPosition);
GL11.glEnable(GLLightHandle); // Enable the light (GL_LIGHT1 - 7)
}
/**
* Set the color of a 'positional' light (a light that has a specific
* position within the scene).
*
* Params:
* an OpenGL light number (GL11.GL_LIGHT1),
* 'Diffuse': color of direct light from this source,
* 'Ambient': color of scattered light from this source
* 'Specular': color of this light reflected off a surface,
* position.
*/
public static void setLight( int GLLightHandle,
float[] diffuseLightColor, float[] ambientLightColor,
float[] specularLightColor, float[] position )
{
FloatBuffer ltDiffuse = allocFloats(diffuseLightColor);
FloatBuffer ltAmbient = allocFloats(ambientLightColor);
FloatBuffer ltSpecular = allocFloats(specularLightColor);
FloatBuffer ltPosition = allocFloats(position);
GL11.glLight(GLLightHandle, GL11.GL_DIFFUSE, ltDiffuse); // color of the direct illumination
GL11.glLight(GLLightHandle, GL11.GL_AMBIENT, ltAmbient); // color of the reflected light
GL11.glLight(GLLightHandle, GL11.GL_SPECULAR, ltSpecular); // color of the highlight (same as direct light)
GL11.glLight(GLLightHandle, GL11.GL_POSITION, ltPosition);
GL11.glEnable(GLLightHandle); // Enable the light (GL_LIGHT1 - 7)
//GL11.glLightf(GLLightHandle, GL11.GL_QUADRATIC_ATTENUATION, .005F); // how light beam drops off
}
/**
* Set the color of the Global Ambient Light. Affects all objects in
* scene regardless of their placement.
*/
public static void setAmbientLight(float[] ambientLightColor) {
FloatBuffer ltAmbient = allocFloats(ambientLightColor);
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, ltAmbient);
}
public static final int SIZE_FLOAT = 4;
public static FloatBuffer allocFloats(int howmany) {
return ByteBuffer.allocateDirect(howmany * SIZE_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
}
public static FloatBuffer allocFloats(float[] floatarray) {
FloatBuffer fb = ByteBuffer.allocateDirect(floatarray.length * SIZE_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
fb.put(floatarray).flip();
return fb;
}
/**
* call the LWJGL Sphere class to create sphere geometry,
* with normals
*/
public static void renderSphere() {
Sphere s = new Sphere(); // an LWJGL class for drawing sphere
s.setOrientation(GLU.GLU_OUTSIDE); // normals point outwards
s.setTextureFlag(true); // generate texture coords
s.draw(1, 48, 48); // run GL commands to draw sphere
}
/**
* Create a texture from the given image.
*/
public static int makeTexture(GLImage textureImg)
{
if ( textureImg == null ) {
return 0;
}
else {
return makeTexture(textureImg.pixelBuffer, textureImg.w, textureImg.h);
}
}
/**
* Create a texture from the given pixels in RGBA format. Set the texture
* to repeat in both directions and use LINEAR for magnification.
* @return the texture handle
*/
public static int makeTexture(ByteBuffer pixels, int w, int h)
{
// get a new empty texture
int textureHandle = allocateTexture();
// 'select' the new texture by it's handle
GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
// set texture parameters
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST);
// Create the texture from pixels
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, w, h, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels);
return textureHandle;
}
/**
* Allocate a texture (glGenTextures) and return the handle to it.
*/
public static int allocateTexture()
{
IntBuffer textureHandle = allocInts(1);
GL11.glGenTextures(textureHandle);
return textureHandle.get(0);
}
public static final int SIZE_INT = 4;
public static IntBuffer allocInts(int howmany) {
return ByteBuffer.allocateDirect(howmany * SIZE_INT).order(ByteOrder.nativeOrder()).asIntBuffer();
}
public float getZdepth(float x, float y, float z) {
Vector3D projectedPoint = projectPoint(x,y,z);
return projectedPoint.z();
}
// in screen space, Z is a number from 0-1 (not same as geometry Z)
public Vector3D projectPoint(float x, float y, float z) {
float[] projectedXYZ = new float[3];
float[][] modelMatrix = getModelviewMatrixA();
float[][] projectionMatrix = getProjectionMatrixA();
int[] viewport = getViewportA();
Vector3D projectedPoint;
// project point to screen space and return x,y,z
GLU.gluProject(x, y, z, modelMatrix, projectionMatrix, viewport, projectedXYZ);
projectedPoint = new Vector3D(projectedXYZ[0], // screen x
projectedXYZ[1], // screen y
projectedXYZ[2]); // z depth value is 0.0 - 1.0
return projectedPoint;
}
public static FloatBuffer getModelviewMatrix()
{
FloatBuffer bufferModelviewMatrix = allocFloats(16);
bufferModelviewMatrix.clear();
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, bufferModelviewMatrix);
return bufferModelviewMatrix;
}
public static FloatBuffer getProjectionMatrix()
{
FloatBuffer bufferProjectionMatrix = allocFloats(16);
bufferProjectionMatrix.clear();
GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, bufferProjectionMatrix);
return bufferProjectionMatrix;
}
public static IntBuffer getViewport()
{
IntBuffer bufferViewport = allocInts(16);
bufferViewport.clear();
GL11.glGetInteger(GL11.GL_VIEWPORT, bufferViewport);
return bufferViewport;
}
/**
* Copy a FloatBuffer matrix to a 4x4 float array. The 4x4 float array
* is passed in, not allocated inside the function, to reduce garbage
* collection needs.
*
* @param fb source FloatBuffer containing 16 values of 4x4 matrix
* @param fa target float[4][4] array will hold the matrix
*/
public static /*float[][]*/ void getMatrixAsArray(FloatBuffer fb , float[][] fa) {
//float[][] fa = new float[4][4];
fa[0][0] = fb.get();
fa[0][1] = fb.get();
fa[0][2] = fb.get();
fa[0][3] = fb.get();
fa[1][0] = fb.get();
fa[1][1] = fb.get();
fa[1][2] = fb.get();
fa[1][3] = fb.get();
fa[2][0] = fb.get();
fa[2][1] = fb.get();
fa[2][2] = fb.get();
fa[2][3] = fb.get();
fa[3][0] = fb.get();
fa[3][1] = fb.get();
fa[3][2] = fb.get();
fa[3][3] = fb.get();
//return fa;
}
// Arrays to hold commonly used matrices
// For memory efficiency, instantiate these once and reuse.
// see getModelviewMatrixA(), getMatrixAsArray() and project().
public static float[][] modelViewMatrix = new float[4][4];
public static float[][] projectionMatrix = new float[4][4];
public static int[] viewport = new int[4];
/**
* Return the modelview matrix as a 4x4 float array
*/
public static float[][] getModelviewMatrixA()
{
FloatBuffer b = getModelviewMatrix(); // get matrix in FloatBuffer
getMatrixAsArray(b,modelViewMatrix); // copy into array
return modelViewMatrix; // return the array
}
/**
* Return the projection matrix as a 4x4 float array
*/
public static float[][] getProjectionMatrixA()
{
FloatBuffer b = getProjectionMatrix();
getMatrixAsArray(b,projectionMatrix);
return projectionMatrix;
}
/**
* Return the Viewport data as array of 4 floats
*/
public static int[] getViewportA()
{
IntBuffer ib = getViewport();
int[] viewport = new int[4];
viewport[0] = ib.get(0);
viewport[1] = ib.get(1);
viewport[2] = ib.get(2);
viewport[3] = ib.get(3);
return viewport;
}
public static long ticksPerSecond = 0; // used to calculate time
public static double getTimeInSeconds()
{
if (ticksPerSecond == 0) { // initialize ticksPerSecond
ticksPerSecond = Sys.getTimerResolution();
}
return (((double)Sys.getTime())/(double)ticksPerSecond);
}
/**
* Convenience function returns time in milliseconds. Calls
* getTimeInSeconds().
*/
public static double getTimeInMillis()
{
return (double) (getTimeInSeconds() * 1000.0);
}
}