Rendery stuff
This commit is contained in:
parent
e871fefb02
commit
e123997fc2
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003 Shaven Puppy Ltd
|
||||||
|
* 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 'Shaven Puppy' 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.
|
||||||
|
*/
|
||||||
|
package org.lwjgl.util.model.renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
* Listens out for events that occur in animations and takes appropriate actions
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public interface AnimationEventListener {
|
||||||
|
/**
|
||||||
|
* Fired when a frame with an action associated with it is rendered
|
||||||
|
* @param src The source Renderer
|
||||||
|
* @param action The action
|
||||||
|
*/
|
||||||
|
public void receiveAnimationEvent(ModelRenderer src, String action);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003 Shaven Puppy Ltd
|
||||||
|
* 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 'Shaven Puppy' 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.
|
||||||
|
*/
|
||||||
|
package org.lwjgl.util.model.renderer;
|
||||||
|
|
||||||
|
import org.lwjgl.util.Renderable;
|
||||||
|
import org.lwjgl.util.model.Frame;
|
||||||
|
import org.lwjgl.util.model.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
* The interface for processing individual frames of rendered models.
|
||||||
|
* Typically the processor will process the frame of animation, and store
|
||||||
|
* the processed results in some data structure that make it easy to render.
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public interface FrameProcessor extends Renderable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a frame.
|
||||||
|
* @param model The model
|
||||||
|
* @param frame The frame to process
|
||||||
|
*/
|
||||||
|
public void process(Model model, Frame frame);
|
||||||
|
|
||||||
|
}
|
|
@ -31,9 +31,9 @@
|
||||||
*/
|
*/
|
||||||
package org.lwjgl.util.model.renderer;
|
package org.lwjgl.util.model.renderer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.lwjgl.util.Renderable;
|
import org.lwjgl.util.Renderable;
|
||||||
|
@ -44,8 +44,7 @@ import org.lwjgl.util.model.Model;
|
||||||
/**
|
/**
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* A simple (and very inefficient) Model renderer. This calculates the model vertices on the fly
|
* Pluggable model renderer
|
||||||
* and uses GL immediate mode to render the result. This is of course very slow.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Material lookups are performed by mapping the material name to a Renderable thing. You must
|
* Material lookups are performed by mapping the material name to a Renderable thing. You must
|
||||||
* suppy appropriate Renderables - typically something that binds a 2D texture and sets up some
|
* suppy appropriate Renderables - typically something that binds a 2D texture and sets up some
|
||||||
|
@ -57,7 +56,7 @@ import org.lwjgl.util.model.Model;
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public class Renderer implements Renderable {
|
public class ModelRenderer implements Renderable {
|
||||||
|
|
||||||
/** Material map: String name->Renderable */
|
/** Material map: String name->Renderable */
|
||||||
private static final Map materials = new HashMap();
|
private static final Map materials = new HashMap();
|
||||||
|
@ -65,6 +64,12 @@ public class Renderer implements Renderable {
|
||||||
/** The model we're rendering */
|
/** The model we're rendering */
|
||||||
private Model model;
|
private Model model;
|
||||||
|
|
||||||
|
/** The frame processor */
|
||||||
|
private FrameProcessor processor;
|
||||||
|
|
||||||
|
/** Animation event listeners */
|
||||||
|
private List listeners;
|
||||||
|
|
||||||
/** The current material */
|
/** The current material */
|
||||||
private Renderable material;
|
private Renderable material;
|
||||||
|
|
||||||
|
@ -75,15 +80,15 @@ public class Renderer implements Renderable {
|
||||||
private final Timer timer = new Timer();
|
private final Timer timer = new Timer();
|
||||||
|
|
||||||
/** Last frame rendered */
|
/** Last frame rendered */
|
||||||
private Frame lastFrame;
|
private Frame currentFrame;
|
||||||
|
|
||||||
/** Visibility */
|
/** Visibility */
|
||||||
private boolean visible;
|
private boolean visible = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C'tor
|
* C'tor
|
||||||
*/
|
*/
|
||||||
public Renderer() {
|
public ModelRenderer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,32 +120,47 @@ public class Renderer implements Renderable {
|
||||||
}
|
}
|
||||||
frame = model.getAnimation(animation);
|
frame = model.getAnimation(animation);
|
||||||
timer.reset();
|
timer.reset();
|
||||||
lastFrame = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a Model
|
* Update the model
|
||||||
*/
|
*/
|
||||||
public void render() {
|
public void update() {
|
||||||
|
|
||||||
// Don't do anything if there's no model or no animation
|
// Don't do anything if there's no model or no animation or no processor
|
||||||
if (model == null || frame == null) {
|
if (model == null || frame == null || processor == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Set up GL state from the Model's material
|
// Work out what frame to show
|
||||||
|
Frame frame = findFrame();
|
||||||
|
if (frame != currentFrame) {
|
||||||
|
currentFrame = frame;
|
||||||
|
processFrame();
|
||||||
|
if (currentFrame.getAction() != null) {
|
||||||
|
fireAnimationEvent(currentFrame.getAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render things
|
||||||
|
*/
|
||||||
|
public void render() {
|
||||||
|
|
||||||
|
// Don't do anything if there's no model or no animation or no processor
|
||||||
|
if (model == null || frame == null || processor == null || !visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up GL state from the Model's material
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
material.render();
|
material.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Work out what frame to show
|
// Render the current frame
|
||||||
Frame frame = findFrame();
|
renderFrame();
|
||||||
if (frame != lastFrame) {
|
|
||||||
lastFrame = frame;
|
|
||||||
processFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Render the processed frame
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,13 +172,43 @@ public class Renderer implements Renderable {
|
||||||
float time = timer.getTime();
|
float time = timer.getTime();
|
||||||
|
|
||||||
// Use a binary search to find the frame
|
// Use a binary search to find the frame
|
||||||
int a = 0, b =
|
int i = 0;
|
||||||
|
for (int j = frame.length - 1; i <= j;) {
|
||||||
|
int k = i + j >> 1;
|
||||||
|
Frame f = frame[k];
|
||||||
|
if (f.getTime() == time) {
|
||||||
|
return f;
|
||||||
|
} else if (f.getTime() < time) {
|
||||||
|
i = k + 1;
|
||||||
|
} else {
|
||||||
|
j = k - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the current frame of animation
|
||||||
|
*/
|
||||||
|
protected void processFrame() {
|
||||||
|
processor.process(model, currentFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the current frame
|
||||||
|
*/
|
||||||
|
protected void renderFrame() {
|
||||||
|
processor.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a material
|
* Add a material
|
||||||
* @param name The material's name
|
*
|
||||||
* @param renderable The renderable object
|
* @param name
|
||||||
|
* The material's name
|
||||||
|
* @param renderable
|
||||||
|
* The renderable object
|
||||||
*/
|
*/
|
||||||
public static void putMaterial(String name, Renderable renderable) {
|
public static void putMaterial(String name, Renderable renderable) {
|
||||||
materials.put(name, renderable);
|
materials.put(name, renderable);
|
||||||
|
@ -218,4 +268,60 @@ public class Renderer implements Renderable {
|
||||||
timer.resume();
|
timer.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the processor.
|
||||||
|
*/
|
||||||
|
public FrameProcessor getProcessor() {
|
||||||
|
return processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the processor. The processor is the clever bit that actually does the
|
||||||
|
* vertex twiddling and rendering.
|
||||||
|
* @param processor The processor to set.
|
||||||
|
*/
|
||||||
|
public void setProcessor(FrameProcessor processor) {
|
||||||
|
this.processor = processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an animation listener
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void addAnimationEventListener(AnimationEventListener listener) {
|
||||||
|
if (listeners == null) {
|
||||||
|
listeners = new ArrayList(1);
|
||||||
|
}
|
||||||
|
listeners.remove(listener);
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an animation listener
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void removeAnimationEventListener(AnimationEventListener listener) {
|
||||||
|
if (listeners == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listeners.remove(listener);
|
||||||
|
if (listeners.size() == 0) {
|
||||||
|
listeners = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire an animation event
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
protected void fireAnimationEvent(String action) {
|
||||||
|
if (listeners == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int n = listeners.size();
|
||||||
|
for (int i = 0; i < n; i ++) {
|
||||||
|
AnimationEventListener listener = (AnimationEventListener) listeners.get(i);
|
||||||
|
listener.receiveAnimationEvent(this, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003 Shaven Puppy Ltd
|
||||||
|
* 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 'Shaven Puppy' 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.
|
||||||
|
*/
|
||||||
|
package org.lwjgl.util.model.renderer;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.util.vector.Vector3f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
* A 3D sprite!
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public class Sprite3D extends ModelRenderer {
|
||||||
|
|
||||||
|
/** Current position */
|
||||||
|
private final Vector3f position = new Vector3f();
|
||||||
|
|
||||||
|
/** Current orientation (axis/angle) */
|
||||||
|
private final Vector3f axis = new Vector3f();
|
||||||
|
private float angle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recognised animation actions
|
||||||
|
*/
|
||||||
|
private static final String ANIM_HIDE = "hide";
|
||||||
|
private static final String ANIM_REWIND = "rewind";
|
||||||
|
private static final String ANIM_GOTO = "goto ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* C'tor
|
||||||
|
*/
|
||||||
|
public Sprite3D() {
|
||||||
|
addAnimationEventListener(new AnimationEventListener() {
|
||||||
|
public void receiveAnimationEvent(ModelRenderer src, String action) {
|
||||||
|
if (action.equals(ANIM_HIDE)) {
|
||||||
|
setVisible(false);
|
||||||
|
} else if (action.equals(ANIM_REWIND)) {
|
||||||
|
rewind();
|
||||||
|
} else if (action.startsWith(ANIM_GOTO)) {
|
||||||
|
setAnimation(action.substring(ANIM_GOTO.length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.lwjgl.util.model.renderer.ModelRenderer#renderFrame()
|
||||||
|
*/
|
||||||
|
protected void renderFrame() {
|
||||||
|
// TODO: rotation
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
GL11.glTranslatef(position.getX(), position.getY(), position.getY());
|
||||||
|
super.renderFrame();
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the position.
|
||||||
|
*/
|
||||||
|
public Vector3f getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue