0
votes

I have been making a project in light weight java graphics library where i have loaded a model and rendered it with a color per triangle fine. My next step is to rotate the model around its center. From reading articles and source code i have a general understanding of what i need to do but i don't fully understand the glTranslatef() method. From my under standing you want to

glPushMatrix()

glTranslatef(0,0,0);

glRotatef(roation values);

glTranslatef(original coords);

render model

then glPopMatrix();

My main problem is i am manually doing the math in my glVertex() method calls instead of translating them i believe which is making the translation back from 0,0,0 to it's original spot difficult. Thanks for your time and help.

package render;

import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glNormal3f;
import static org.lwjgl.opengl.GL11.glVertex3f;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.lwjgl.util.vector.Vector3f;

import models.Faces;
import models.Material;
import models.Model;
import models.OBJLoader;

public class OBJRender {
    Material material = new Material();
    private int count;
    Model m = null;
    Vector3f rgb = null;
    Vector3f v1 = new Vector3f();
    Vector3f v2 = new Vector3f();
    Vector3f v3 = new Vector3f();

public void load_model(String model_name){ //loads model data
    try{
        m = OBJLoader.loadModel(new File("res/obj/"+model_name+".obj"));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void model_render(Vector3f coords, Vector3f degrees){
    count = 0; //count of triangle for coloring
    model_rotate(coords, degrees); //coords is the obj coords degrees is rotation coords
    glBegin(GL_TRIANGLES);
    for (Faces face : m.faces) {
        String mat = OBJLoader.getMaterialList().get(count);
        rgb = material.getMaterial(mat);
        glColor3f(rgb.x, rgb.y, rgb.z);
        Vector3f n1 = m.normals.get((int) face.normals.x - 1);        
        v1 = m.vertices.get((int) face.Vertex.x - 1);
        Vector3f n2 = m.normals.get((int) face.normals.y - 1);            
        v2 = m.vertices.get((int) face.Vertex.y - 1);           
        Vector3f n3 = m.normals.get((int) face.normals.z - 1);
        v3 = m.vertices.get((int) face.Vertex.z - 1);
        glNormal3f(n1.x, n1.y, n1.z);
        glVertex3f(coords.x-v1.x, coords.y+v1.y+80, coords.z-v1.z);
        glNormal3f(n2.x, n2.y, n2.z);
        glVertex3f(coords.x-v2.x, coords.y+v2.y+80, coords.z-v2.z);
        glNormal3f(n3.x, n3.y, n3.z);
        glVertex3f(coords.x-v3.x, coords.y+v3.y+80, coords.z-v3.z);
        count++;
    }
    glClearColor(rgb.x,rgb.y,rgb.z,0);
    glEnd();
    glPopMatrix();
}

public void model_rotate(Vector3f coords, Vector3f degrees){
    glPushMatrix();
    glTranslatef(-0, -0, -0);
    glRotatef(degrees.y,0,1,0);
    }
}
1
The sequence is actually glTranslate(center), glRotate(angle), glTranslate( - center). But when you're modifying the vertex coordinates, this has to be taken into account, and you have to compute the new center. (You should probably not do this. Just render the object as-it-is, and use only the glTranslate etc. calls to transform it).Marco13
So from what your saying you want me to exclusively use glTranslate to rotate my model?Ryan
glTranslate and glRotate, of course (this was what the "etc." stood for). The key point is: You usually don't modify vertex coordinates manually when you want to transform the whole object. Instead, you use the "original" vertex coordinates, and transform the object by manipulating the modelview matrix with glTranslate and glRotate (and glScale, if you want to).Marco13
can you give me a example of how to do this.Ryan
ive tried to translate to (0,0,0) rotate then (-0,-0,-0) back but it still renders off of where it should.Ryan

1 Answers

1
votes

Although it is still not entirely clear what the actual question is (apart from "What do I have to change so that the code does what I want"), an attempt to answer:

When you load an object, for example, from an OBJ file, you usually will not modify the vertex coordinates. You will just use them as they are read from the file. When you want to transform the object as a whole, you use the OpenGL matrix operations - in this case, only glTranslate and glRotate.

In order to rotate the object about its center, you first have to know this center. In doubt, you can compute it from the vertices or the bounding box of the object.

Then, in order to rotate the object around its center, you have to

  • Move the object, using glTranslate, so that the center of the object is at the origin
  • Rotate the object, using glRotate
  • Move the object back to its original position, using glTranslate

Note that these operations are applied to the object in the opposite order than they appear in the source code. So the sequence of calls will be

glTranslatef( center.x,  center.y,  center.z);
glRotatef(rotationAngleDeg,0,0,1);
glTranslatef(-center.x, -center.y, -center.z);

Here is a MCVE that uses a simple rectangle consisting of 4 vertices as the object, and rotates it about its center. You can see that in the glVertex calls, it simply uses the vertices as they are (in your case, they would be read from the OBJ file). The whole transformation is done on the GL_MODELVIEW matrix, using the commands mentioned above.

import static org.lwjgl.opengl.GL11.*;
import java.awt.Canvas;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;

public class RotateAboutCenter
{
    public static void main(String[] args)
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500,500);
        f.setLocationRelativeTo(null);
        Canvas canvas = new Canvas();
        f.add(canvas);
        try
        {
            Display.setParent(canvas);
            f.setVisible(true);
            Display.create();
        }
        catch (LWJGLException e)
        {
            e.printStackTrace();
        }
        while (!Display.isCloseRequested())
        {
            draw();
            Display.update();
            try
            {
                Thread.sleep(10);
            }
            catch (InterruptedException e)
            {
                Thread.currentThread().interrupt();
            }
            rotationAngleDeg += 1.0f;
        }
        Display.destroy();
    }

    private static float rotationAngleDeg = 0;

    // The vertices of the model
    private static Vector3f v0 = new Vector3f(10,10,0);
    private static Vector3f v1 = new Vector3f(20,10,0);
    private static Vector3f v2 = new Vector3f(20,20,0);
    private static Vector3f v3 = new Vector3f(10,20,0);

    // The center of the model
    private static Vector3f center = new Vector3f(15,15,0);

    private static void draw() 
    {
        // Basic setup of view etc.
        int w = Display.getWidth();
        int h = Display.getHeight();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        GLU.gluPerspective(45, (float) w / (float) h, 0.1f, 1000);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        GLU.gluLookAt(0,0,70,0,0,0,0,1,0);

        glPushMatrix();

        // ===================================================================
        // Now, do the model transform. Remember that this has to 
        // be read "backwards":

        // THIRD STEP: Move the model back so that its center is
        // again at its original position
        glTranslatef(center.x, center.y, center.z);

        // SECOND STEP: Rotate the model about the origin (which now
        // is the center of the model)
        glRotatef(rotationAngleDeg,0,0,1);

        // FIRST STEP: Translate the model so that its center is at the origin
        glTranslatef(-center.x, -center.y, -center.z);

        // ===================================================================

        // Draw the object, with its original coordinates. All the
        // transforms are now contained in the MODELVIEW matrix.
        glBegin(GL_TRIANGLES);
        glColor3f(1,0,0);
        glVertex3f(v0.x, v0.y, v0.z);
        glVertex3f(v1.x, v1.y, v1.z);
        glVertex3f(v3.x, v3.y, v3.z);
        glVertex3f(v1.x, v1.y, v1.z);
        glVertex3f(v2.x, v2.y, v2.z);
        glVertex3f(v3.x, v3.y, v3.z);

        glEnd();
        glPopMatrix();
    }
}