Package aspect.core

Source Code of aspect.core.AspectRenderer

/*
* Copyright (C) 2014 MillerV
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package aspect.core;

import aspect.util.Angles;
import aspect.util.Vector2;
import aspect.util.Vector3;
import aspect.render.Canvas;
import aspect.render.ViewModel;
import aspect.entity.Entity;
import aspect.render.Light;
import aspect.resources.modeling.Vertex;
import aspect.util.Color;
import aspect.util.AbstractTransform;
import aspect.util.Matrix4x4;
import aspect.util.Transform;
import aspect.util.Trig;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.Display.*;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

/**
* This is the utility class used to render the scene. Note that typically
* Entity.draw() should be used to render 3D objects and setCameraViewpoint
* should be used to control the camera.
*
* @author MillerV
*/
public class AspectRenderer {

    private static int pushedMatrices;

    private static RenderMode mode;

    private static FloatBuffer modelViewMatrix;
    private static FloatBuffer projectionMatrix;

    private static boolean resized = false;

    static ViewModel skybox;

    public static boolean FBO_ENABLED = false;

    /**
     * The default camera viewpoint, which uses cameraPos and cameraRot as its
     * position and rotation.
     */
    public static final Transform DEFAULT_CAMERA = new Transform();

    /**
     * The current camera viewpoint.
     */
    public static AbstractTransform camera = DEFAULT_CAMERA;

    /**
     * Change between 2D and 3D rendering modes. It is usually not necessary to
     * call this method yourself.
     *
     * @param mode the new RenderMode
     */
    public static void setRenderMode(RenderMode mode) {

        if (mode == AspectRenderer.mode && !resized) {
            return;
        }

        if (mode == RenderMode.PERSPECTIVE) {
            glViewport(0, 0, getWidth(), getHeight());
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            float aspect = (float) getWidth() / (float) getHeight();
            gluPerspective(60, aspect, 0.01f, 1000);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glEnable(GL_DEPTH_TEST);
            glEnable(GL_ALPHA_TEST);
            glEnable(GL_LIGHTING);
            glDisable(GL_COLOR_MATERIAL);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glShadeModel(GL_SMOOTH);
            glFrontFace(GL_CCW);
            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
            setupCamera();
        } else {
            glDisable(GL_DEPTH_TEST);
            glDisable(GL_LIGHTING);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluOrtho2D(0, getCanvasWidth(), 0, getCanvasHeight());
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
        }

        resized = false;
        AspectRenderer.mode = mode;
    }

    public static void onDisplayResize() {
        resized = true;
    }

    public static void setCulling(boolean allow) {
        if (allow) {
            glEnable(GL_CULL_FACE);
        } else {
            glDisable(GL_CULL_FACE);
        }
    }

    /**
     * Clears the color and depth buffers so that the scene can be redrawn. It
     * is not necessary to call this method yourself.
     */
    public static void clearRenderer() {
        clearRenderer(camera);

    }

    public static void clearRenderer(AbstractTransform viewpoint) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        viewpoint.transformCamera();
        Light.drawLights();
    }

    /**
     * Prints the OpenGL version currently supported.
     */
    public static void printGlVersion() {
        System.out.println("GL VENDOR: " + glGetString(GL_VENDOR));
        System.out.println("GL RENDERER: " + glGetString(GL_RENDERER));
        System.out.println("GL VERSION: " + glGetString(GL_VERSION));
        System.out.println();
    }

    /**
     * Get the height of the window.
     *
     * @return the window height in pixels
     */
    public static int getCanvasHeight() {
        return getHeight();
    }

    /**
     * Get the width of the window.
     *
     * @return the window width in pixels
     */
    public static int getCanvasWidth() {
        return getWidth();
    }

    /**
     * Get the x coordinate of the left window bound, relative to the left edge
     * of the screen.
     *
     * @return the x coordinate of the window
     */
    public static int getCanvasX() {
        return getX();
    }

    /**
     * Get the y coordinate of the upper window bound, relative to the upper
     * edge of the screen.
     *
     * @return the y coordinate of the window
     */
    public static int getCanvasY() {
        return getY();
    }

    public static void setupCamera() {
        camera.transformCamera();
    }

    /**
     * Push a new matrix to the top of the OpenGL matrix stack. It is not
     * necessary to call this method yourself if you are using draw3D or
     * Entity.draw();
     */
    public static void pushMatrix() {
        glPushMatrix();
        pushedMatrices++;
    }

    /**
     * Pop the matrix from the top of the OpenGL matrix stack. It is not
     * necessary to call this method yourself if you are using draw3D or
     * Entity.draw(). This method will return false if there is no matrix to
     * pop, and will only pop matrices that were pushed using pushMatrix().
     *
     * @return whether a matrix could be popped.
     */
    public static boolean popMatrix() {
        if (pushedMatrices > 0) {
            glPopMatrix();
            pushedMatrices--;
            return true;
        } else {
            return false;
        }
    }

    /**
     * Clear the depth buffer, meaning that any new objects will be drawn over
     * those already drawn, regardless of their depth.
     */
    public static void clearDepthBuffer() {
        glClear(GL_DEPTH_BUFFER_BIT);
    }

    /**
     * Save the depth buffer into a IntBuffer, so that it can be restored later
     * on.
     *
     * @return the saved buffer
     * @see #restoreDepthBuffer(java.nio.IntBuffer)
     */
    public static IntBuffer saveDepthBuffer() {
        IntBuffer depth = BufferUtils.createIntBuffer(getWidth() * getHeight());
        glReadPixels(0, 0, getWidth(), getHeight(), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, depth);
        return depth;
    }

    /**
     * Restore the depth buffer from a saved IntBuffer.
     *
     * @param depth the saved buffer
     * @see #saveDepthBuffer()
     */
    public static void restoreDepthBuffer(IntBuffer depth) {
        glRasterPos2i(0, 0);
        glDrawPixels(getWidth(), getHeight(), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, depth);
    }

    /**
     * Clear the color buffer, drawing a black rectangle over the screen but
     * keeping the depth buffer, meaning that objects drawn behind those already
     * drawn will be hidden.
     */
    public static void clearColorBuffer() {
        glClear(GL_COLOR_BUFFER_BIT);
    }

    public static void color(Color color) {
        glColor4f(color.red, color.green, color.blue, color.alpha);
    }

    public static void texCoord(Vector2 texCoord) {
        glTexCoord2f(texCoord.x, texCoord.y);
    }

    public static void normal(Vector3 normal) {
        normal = normal.normalize();
        glNormal3f(normal.x, normal.y, normal.z);
    }

    public static void vertex(Vertex vertex) {
        color(vertex.color);
        texCoord(vertex.texcoord);
        normal(vertex.normal);
        vertex(vertex.position);
    }

    public static void vertex(Vector3 vertex) {
        glVertex3f(vertex.x, vertex.y, vertex.z);
    }

    public static void vertex(Vector2 vertex) {
        glVertex2f(vertex.x, vertex.y);
    }

    public static void begin(GeometryType type) {
        glBegin(type.glEnum);
    }

    public static void end() {
        glEnd();
    }

    public static Color getPixelColor(Vector2 p) {
        FloatBuffer buff = BufferUtils.createFloatBuffer(3);
        glReadPixels((int)p.x, (int)p.y, 1, 1, GL_RGB, GL_FLOAT, buff);
        return new Color(buff.get(), buff.get(), buff.get());
    }

    /**
     * Reverts the matrix on top of the OpenGL matrix stack to the identity
     * matrix, meaning it will not transform geometry. Any transformations
     * applied to matrices further down the stack will still be applied to
     * objects.
     */
    public static void loadIdentity() {
        glLoadIdentity();
    }

    /**
     * Applies a translation transformation to the matrix on top of the OpenGL
     * matrix stack.
     *
     * @param trans the Vector3 to translate by
     */
    public static void translate(Vector3 trans) {
        glTranslatef(trans.x, trans.y, trans.z);
    }

    /**
     * Applies a translation to the matrix on top of the OpenGL matrix stack.
     *
     * @param trans the Vector2 to translate by
     */
    public static void translate(Vector2 trans) {
        glTranslatef(trans.x, trans.y, 0);
    }

    public static void lookAt(Vector3 position, Vector3 at, Vector3 up) {
        gluLookAt(position.x, position.y, position.z, at.x, at.y, at.z, up.x, up.y, up.z);
    }

    public static void lookAt(Vector3 at, Vector3 up) {
        lookAt(Vector3.zero(), at, up);
    }

    /**
     * Applies an x rotation to the matrix on top of the OpenGL matrix stack.
     *
     * @param angle the angle to rotate by
     */
    public static void rotateX(float angle) {
        rotate(angle, Vector3.xAxis());
    }

    /**
     * Applies a y rotation to the matrix on top of the OpenGL matrix stack.
     *
     * @param angle the angle to rotate by
     */
    public static void rotateY(float angle) {
        rotate(angle, Vector3.yAxis());
    }

    /**
     * Applies a z rotation to the matrix on top of the OpenGL matrix stack.
     *
     * @param angle the angle to rotate by
     */
    public static void rotateZ(float angle) {
        rotate(angle, Vector3.zAxis());
    }

    /**
     * Applies a rotation to the matrix on top of the OpenGL matrix stack around
     * the given Vector3.
     *
     * @param angle the angle to rotate by
     * @param v the Vector3 to rotate around
     */
    public static void rotate(float angle, Vector3 v) {
        glRotatef(Trig.toDegrees(angle), v.x, v.y, v.z);
    }

    /**
     * Applies x, y, and z rotations to the matrix on top of the OpenGL matrix
     * stack. The rotations are applied in the order y, x, z.
     *
     * @param angles the angles to rotate by
     */
    public static void rotate(Angles angles) {
        rotateY(angles.yaw);
        rotateX(angles.pitch);
        rotateZ(angles.roll);
    }

    /**
     * Applies a scale to the matrix on top of the OpenGL matrix stack.
     *
     * @param s the scale to use
     */
    public static void scale(Vector3 s) {
        glScalef(s.x, s.y, s.z);
    }

    public static void transform(Matrix4x4 mat) {
        glMultMatrix(mat.getBuffer());
    }

    public static Matrix4x4 modelViewMatrix() {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
        glGetFloat(GL_MODELVIEW_MATRIX, buffer);
        return new Matrix4x4(buffer);
    }

    public static Matrix4x4 projectionMatrix() {
        FloatBuffer mat = BufferUtils.createFloatBuffer(16);
        glGetFloat(GL_PROJECTION_MATRIX, mat);
        return new Matrix4x4(mat);
    }

    public static IntBuffer viewport() {
        IntBuffer buff = BufferUtils.createIntBuffer(16);
        glGetInteger(GL_VIEWPORT, buff);
        return buff;
    }

    /**
     * Draw an Entity at its position and angle, disregarding the current camera
     * position so that the object is drawn relative to the camera.
     *
     * @param ent the Entity to draw
     */
    public static void draw3DAtCamera(Entity ent) {
        loadIdentity();
        ent.render();
        setupCamera();
    }

    /**
     * Draw a 3D ViewModel at the given position and angles, disregarding the
     * current camera position so that the object is drawn relative to the
     * camera.
     *
     * @param mdl the ViewModel to draw
     */
    public static void draw3DAtCamera(ViewModel mdl) {
        loadIdentity();
        mdl.render();
        setupCamera();
    }

    /**
     * Draw a Canvas2D on the screen at the given position. The given point is
     * the lower-left coordinate of the canvas, relative to the lower-left
     * corner of the screen.
     *
     * @param canvas the Canvas2D to draw
     * @param transform the model transform
     */
    public static void draw2D(Canvas canvas, Transform transform) {
        pushMatrix();
        transform.transformModel();
        canvas.getModel().render();
        popMatrix();
    }

    /**
     * Add fog to the world, making objects further away appear less visible.
     * This does not increase the performance, but allows you to avoid drawing
     * objects that will not be visible to the user.
     *
     * @param density the density of the fog
     * @param color the color of the fog
     * @param mode the mode to use for the fog (1 fades slowly, 2 fades quickly)
     * @see #removeFog()
     */
    public static void makeFog(float density, Color color, int mode) {
        glEnable(GL_FOG);

        if (mode == 1) {
            glFogi(GL_FOG_MODE, GL_EXP);
        } else if (mode == 2) {
            glFogi(GL_FOG_MODE, GL_EXP2);
        }

        glFogf(GL_FOG_DENSITY, density);

        FloatBuffer fb = color.getBuffer();

        glFog(GL_FOG_COLOR, fb);
        glHint(GL_FOG_HINT, GL_DONT_CARE);
    }

    /**
     * Set the ambient light of the scene. Pixels will have their color values
     * multiplied by the values of the given Color before being drawn.
     *
     * @param color the light color
     */
    public static void setAmbientLight(Color color) {
        FloatBuffer light = color.getBuffer();

        glLightModel(GL_LIGHT_MODEL_AMBIENT, light);
    }

    public static void setLighting(boolean lighting) {
        if (lighting) {
            glEnable(GL_LIGHTING);
        } else {
            glDisable(GL_LIGHTING);
        }
    }

    /**
     * Remove any fog that has been created by makeFog.
     */
    public static void removeFog() {
        glDisable(GL_FOG);
    }

    /**
     * Set the background color. For the best results, you should make the
     * background the same color as the fog.
     *
     * @param color the color to set the background to
     */
    public static void setBackground(Color color) {
        glClearColor(color.red, color.green, color.blue, color.alpha);
    }

    public static void addSkybox(ViewModel model) {
        skybox = model;
    }

    /**
     * Set the current camera viewpoint to the default camera, which is
     * controlled by the camera functions.
     *
     * @see #setCameraViewpoint(engine.core.CameraViewpoint)
     */
    public static void useDefaultCamera() {
        camera = DEFAULT_CAMERA;
    }

    /**
     * The set of supported render modes.
     */
    public static enum RenderMode {

        PERSPECTIVE, ORTHOGRAPHIC
    }

    public static enum GeometryType {

        POINTS(GL_POINTS),
        LINES(GL_LINES),
        LINE_STRIP(GL_LINE_STRIP),
        LINE_LOOP(GL_LINE_LOOP),
        POLYGON(GL_POLYGON),
        QUADS(GL_QUADS),
        QUAD_STRIP(GL_QUAD_STRIP),
        TRIANGLES(GL_TRIANGLES),
        TRIANGLE_STRIP(GL_TRIANGLE_STRIP),
        TRIANGLE_FAN(GL_TRIANGLE_FAN);

        public final int glEnum;

        GeometryType(int glEnum) {
            this.glEnum = glEnum;
        }
    }
}
TOP

Related Classes of aspect.core.AspectRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.