Ah thats more like what i'm after!
Would all this happen in the render loop? I'm not too experienced with lwjgl unfortunately, although i do understand the basics.. The below code is my renderer class (with quite a lot taken out) which is based on someone elses basic renderer. Do this look right (roughly) for each object in the render loop:
GL11.glScissor(x, y, width, height);
glEnable(GL_SCISSOR);
GL11.glViewport(...);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glDisable(GL_SCISSOR);
GL11.glMatrixMode(GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glRotatef(rotateModelY, 0, 1, 0); // around vertical axis
GL11.glRotatef(rotateModelX, 1, 0, 0); // around horizontal axis
GL11.glPushMatrix();
renderMesh(object1,0);
GL11.glPopMatrix();
THANKS AGAIN!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
RENDERER CODE:
public class GLRenderer{
private String WINDOW_TITLE = "OBJModel";
private DisplayMode displayMode; //Display perspectives and aspect ratios
public GL_Mesh obj; //Single OBJ Object
private String modelLocation;
private float z = 0.0f; // Depth Into The Screen
private float rotateModelX = 0;
private float rotateModelY = 0;
private boolean normalsOn = true;
private int cursorX, cursorY;
// camera position and rotation (see handleNavigationKeys())
float[] cameraPos = new float[] {0,0,100};
float cameraRotation = 0f;
final float piover180 = 0.0174532925f;// A constant used in navigation
// for mouse drag
Vector3D mousePrevPos = null;
boolean mouseIsDown = false;
Vector3D mousePoint = new Vector3D(.1f,0,100);
// Arrays to hold matrices for projectVerts() operation.
// For memory efficiency, instantiate these once and reuse.
// see getModelviewMatrixA(), getMatrixAsArray() and mesh.projectVerts().
public static float[][] modelViewMatrix = new float[4][4];
public static float[][] projectionMatrix = new float[4][4];
public static int[] viewport = new int[4];
// color of overall scene lighting
float ambient[] = { 0f, 0f, 0f, 1f };
// color of light source
float lightDiffuse[] = { .9f, .9f, .6f, 1f }; // direct light
float lightSpecular[] = { .9f, .9f, .6f, 1f }; // highlight
float lightAmbient[] = { .5f, .0f, .0f, 1f }; // scattered light
// light position: if last value is 0, then this describes light direction.
// If 1, then light position.
float lightPosition[] = { -100f, 100f, 100, 0f };
// color of material
float mtlDiffuse[] = { .6f, 0f, 0f, 1f }; // red
float mtlAmbient[] = { .2f, 0f, 0f, 1f }; // dark red
float mtlSpecular[] = { .8f, .8f, .8f, 1f }; // almost white: very reflective
float mtlShininess = 100f; // 0=no shine, 127=max shine
private boolean done = false;
private boolean norm = false;
private boolean tetra = false;
private boolean renderAnchors = false;
private boolean objLoaded = false;
private Tetrahedron tet;
public int[] anchors;
private GL_Vertex modelCenter;
private boolean wireframe;
public GLRenderer(GL_Mesh mesh){
this.obj = mesh;
objLoaded = true;
}
public GLRenderer(String filename){
this.modelLocation = filename;
run();
}
public void run() {
try {
init();
while (!done) {
if(!norm){
MainLoop();
render();
Display.update();}
}
cleanup();
}
catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void init() throws Exception {
createWindow();
initGL();
if(!objLoaded){
Importer importOBJ = new Importer();
obj = importOBJ.importOBJ(modelLocation);}
// Get the current projection and viewport matrices
// for use in projectVerts(). Modelview matrix will change
// every frame, so we'll get that in render().
projectionMatrix = getProjectionMatrixA();
viewport = getViewportA();
}
public void initGL() {
Display.setVSyncEnabled(false); //Seriously slows down FPS
// Select the Projection Matrix (controls perspective)
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity(); // Reset The Projection Matrix
// Define perspective
GLU.gluPerspective(
30.0f, // Field Of View
(float)displayMode.getWidth() / (float)displayMode.getHeight(), // aspect ratio
0.01f, // near Z clipping plane
1000.0f); // far Z clipping plane
// Select The Modelview Matrix (controls model orientation)
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity(); // Reset The Modelview Matrix
// 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);
// turn lighting on (does not create a light)
GL11.glEnable(GL11.GL_LIGHTING);
// Create a light
// diffuse is the color of direct light from this light source
// specular is the hightlight color
// ambient is the color of scattered light from this source
// position is where the light is, or it's direction
setLight( GL11.GL_LIGHT1, lightDiffuse, lightAmbient, lightSpecular, lightPosition );
// no overall scene lighting
setAmbientLight(ambient);
GL11.glShadeModel(GL11.GL_SMOOTH);
// set the background color
GL11.glClearColor(.08f, .08f, .1f, 1);
GL11.glLineWidth(1);
}
public void createWindow() throws Exception {
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.getWidth() == 800
&& d.getHeight() == 600
&& d.getBitsPerPixel() == 32) {
displayMode = d;
break;
}
}
// set the display to the resolution we picked
Display.setDisplayMode(displayMode);
Display.setTitle(WINDOW_TITLE);
// create the window
// specify Pixel Format:
// 0 -- default bits per pixel for alpha values
// 24 -- 24 bits per pixel for depth buffer
// 0 -- default bits per pixel for stencil buffer
// NOTE:
// we specify 24 bits per pixel instead of the default
// 8 bits because this scene is deep
// (zdepth is .01 - 1000 in the gluPerspective() command)
// and 8 bit values only hold 0-255 (rounding
// errors cause close objects to overlap instead of
// correctly layering.
Display.create(new PixelFormat(0,24,0));
}
public void MainLoop() {
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
done = true;
}
// Has Window been closed
if(Display.isCloseRequested()) {
done = true;
}
// Handle key press events (down/up)
handleKeyPressEvents();
// Handle arrow keys (press and hold)
handleNavigationKeys();
handleMouseEvents();
//cleanup();
}
public void render() {
// Clear screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// reset the coordinate system to center of screen
GL11.glLoadIdentity();
GL11.glPushMatrix();
{
// Place the 'camera'
GLU.gluLookAt( // camera position
cameraPos[0], cameraPos[1], cameraPos[2],
// look at a point directly in front of camera
cameraPos[0]- (float) Math.sin(cameraRotation* piover180), cameraPos[1],
cameraPos[2]- (float) Math.cos(cameraRotation* piover180),
// which way is up
0f, 1f, 0f);
// alternative
// shift and rotate entire scene (opposite to "camera" position)
//GL11.glRotatef((360.0f-cameraRotation), 0, 1f, 0); // first
// rotate around y axis
//GL11.glTranslatef( -cameraPos[0], -cameraPos[1], -cameraPos[2]);
// // then move forward on x,z axis (staying on ground, so no Y
// motion)
// set the light position (have to do this each render() since
// we're moving the scene around with navigation, have to update
// light position. Light pos is transformed just like a vertex).
//setLightPos(GL11.GL_LIGHT1, lightPosition[0], lightPosition[1], lightPosition[2]);
// draw white sphere at light position
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glColor4f(1, 1, .9f, 1);
GL11.glPushMatrix();
{
//GL11.glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
//renderSphere();
}
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPushMatrix();
{
// rotate model (based on mouse drag)
GL11.glRotatef(rotateModelY, 0, 1, 0); // around vertical axis
GL11.glRotatef(rotateModelX, 1, 0, 0); // around horizontal axis
renderMesh(obj,0);
if(tetra){
drawTetrahedron();
}
if(renderAnchors){
highlightFixPoints();
}
//pps+=polycount;
}
GL11.glPopMatrix();
}
GL11.glPopMatrix();
}
public void renderMesh(GL_Mesh o, int textureHandle)
{
GL_Triangle t;
GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
GL11.glBegin(GL11.GL_TRIANGLES);
for (int j = 0; j < o.triangles.length; j++) { // draw all triangles in object
t = o.triangles[j];
GL11.glTexCoord2f(t.uvw1.x, t.uvw1.y);
GL11.glNormal3f(t.norm1.x, t.norm1.y, t.norm1.z);
GL11.glVertex3f( (float)t.p1.pos.x, (float)t.p1.pos.y, (float)t.p1.pos.z);
GL11.glTexCoord2f(t.uvw2.x, t.uvw2.y);
GL11.glNormal3f(t.norm2.x, t.norm2.y, t.norm2.z);
GL11.glVertex3f( (float)t.p2.pos.x, (float)t.p2.pos.y, (float)t.p2.pos.z);
GL11.glTexCoord2f(t.uvw3.x, t.uvw3.y);
GL11.glNormal3f(t.norm3.x, t.norm3.y, t.norm3.z);
GL11.glVertex3f( (float)t.p3.pos.x, (float)t.p3.pos.y, (float)t.p3.pos.z);
}
GL11.glEnd();
}
public void cleanup() {
Display.destroy();
}
public void screenDepth(){
GL11.glTranslatef(0.0f,0.0f,z); // Translate Into/Out Of The Screen By z
}
/**
* Detect changes in key state, ie. a key is pressed or released, and
* call keydown() and keyup() functions. These are non-repeating events
* (keydown will be called only when the key is first pressed).
*/
public void handleKeyPressEvents()
{
while ( Keyboard.next() ) {
if (Keyboard.getEventKeyState()) {
keyDown(Keyboard.getEventKey());
}
else {
keyUp(Keyboard.getEventKey());
}
}
}
/**
* Key event functions (keyDown() and keyUp() are are called by mainloop()).
* @param keycode
*/
public void keyDown(int keycode) {
// Normals off/on
if (keycode == Keyboard.KEY_N) {
normalsOn = !normalsOn;
}
}
public void keyUp(int keycode) {
}
public void handleNavigationKeys()
{
// Turn left
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
cameraRotation += 1.0f;
}
// Turn right
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
cameraRotation -= 1.0f;
}
// move forward in current direction
if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
cameraPos[0] -= (float) Math.sin(cameraRotation * piover180) * 1f;
cameraPos[2] -= (float) Math.cos(cameraRotation * piover180) * 1f;
}
// move backward in current direction
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
cameraPos[0] += (float) Math.sin(cameraRotation * piover180) * 1f;
cameraPos[2] += (float) Math.cos(cameraRotation * piover180) * 1f;
}
// move camera down
if (Keyboard.isKeyDown(Keyboard.KEY_PRIOR)) {
cameraPos[1] += .3f;
}
// move camera up
if (Keyboard.isKeyDown(Keyboard.KEY_NEXT)) {
cameraPos[1] -= .3f;
}
if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
setWireframeOn();
}
if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
setWireframeOff();
}
if (Keyboard.isKeyDown(Keyboard.KEY_T)) {
testCenter();
}
if (Keyboard.isKeyDown(Keyboard.KEY_N)) {
normalise();
}
}
//----------------------------------------------------------------
// Wireframe
//----------------------------------------------------------------
public void setWireframeOff() {
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_CULL_FACE);
wireframe = false;
}
/** enter wireframe mode */
public void setWireframeOn() {
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
GL11.glDisable(GL11.GL_CULL_FACE);
wireframe = true;
}
}