1
\$\begingroup\$

How can I texture a cube that is able to rotate in x,y and z direction in pure Java?
Here is what i have tried:

package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class Cube extends JFrame {

// 8 Vertices 1-8
double p[][] = new double[9][4];

int x=1, y=2, z=3;

boolean xRotUp = false;
boolean yRotRight = false;
boolean xRotDown = false;
boolean yRotLeft = false;
boolean zRotLeft = false;
boolean zRotRight = false;
boolean moveLeft = false;
boolean moveRight = false;
boolean moveUp = false;
boolean moveDown = false;

Image tex = Textures.getTexture("dirt_side");


double px, py, pz;

double angle_x = 0.002;
double angle_y = 0.00150;
double angle_z = 0.0010; 


public Wuerfel() {
    setSize(500,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {
            switch (e.getKeyCode()) {
            //ROTATION
            case 37:
                yRotLeft = false;
                break;
            case 38:
                xRotUp = false;
                break;
            case 39:
                yRotRight = false;
                break;
            case 40:
                xRotDown = false;
                break;
            case KeyEvent.VK_W:
                moveUp = false;
                break;
            case KeyEvent.VK_S:
                moveDown = false;
                break;
            case KeyEvent.VK_A:
                moveLeft = false;
                break;
            case KeyEvent.VK_D:
                moveRight = false;
                break;
            case KeyEvent.VK_Q:
                zRotLeft = false;
                break;
            case KeyEvent.VK_E:
                zRotRight = false;
                break;
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) {
                //ROTATION
                case 37:
                    if (!yRotRight) {
                    yRotLeft = true;
                    } else {
                        yRotRight = false;
                    }
                    break;
                case 38:
                    if (!xRotDown) {
                    xRotUp = true;
                    } else {
                        xRotDown = false;
                    }
                    break;
                case 39:
                    if (!yRotLeft) {
                    yRotRight = true;
                    } else {
                        yRotLeft = false;
                    }
                    break;
                case 40:
                    if (!xRotUp) {
                    xRotDown = true;
                    } else {
                        xRotUp = false;
                    }
                    break;
                    //MOVE
                case KeyEvent.VK_W:
                    moveUp = true;
                    break;
                case KeyEvent.VK_S:
                    moveDown = true;
                    break;
                case KeyEvent.VK_A:
                    moveLeft = true;
                    break;
                case KeyEvent.VK_D:
                    moveRight = true;
                    break;
                case KeyEvent.VK_Q:
                    zRotLeft = true;
                    break;
                case KeyEvent.VK_E:
                    zRotRight = true;
                    break;
            }
        }
    });
}

public void move() {
    for (int i=1; i<9;i++) {
        px = p[i][x];
        py = p[i][y];
        pz = p[i][z];
        if (moveUp) {
            p[i][y]-=0.1;
        }

        if (moveDown) {
            p[i][y]+=0.1;
        }

        if (moveLeft) {
            p[i][x]-=0.1;
            p[i][z]-=0.1;
        } 
        if (moveRight) {
            p[i][x]+=0.1;
            p[i][z]+=0.1;
        }

    }
}

public void rotate() {
    for (int i=0; i<9;i++) {
        px = p[i][x];
        py = p[i][y];
        pz = p[i][z];
        if (xRotUp) {
            p[i][y] = py*Math.cos(angle_x)-pz*Math.sin(angle_x);
            p[i][z] = py*Math.sin(angle_x)+pz*Math.cos(angle_x);

            py = p[i][y];
            pz = p[i][z];
        }

        if (xRotDown) {
             p[i][y] = py*Math.cos(-angle_x)-pz*Math.sin(-angle_x);
                p[i][z] = py*Math.sin(-angle_x)+pz*Math.cos(-angle_x);

                py = p[i][y];
                pz = p[i][z];
        }

        if (yRotRight) {
            p[i][x] = px*Math.cos(angle_y)+pz*Math.sin(angle_y);
            p[i][z] =-px*Math.sin(angle_y)+pz*Math.cos(angle_y);

            px = p[i][x];
        }

        if (yRotLeft) {
            p[i][x] = px*Math.cos(-angle_y)+pz*Math.sin(-angle_y);
            p[i][z] =-px*Math.sin(-angle_y)+pz*Math.cos(-angle_y);

            px = p[i][x];
        }

        if (zRotRight) {
            p[i][x] = px*Math.cos(angle_z)-py*Math.sin(angle_z);
            p[i][y] = py*Math.cos(angle_z)+px*Math.sin(angle_z);
        }
        if (zRotLeft) {
            p[i][x] = px*Math.cos(-angle_z)-py*Math.sin(-angle_z);
            p[i][y] = py*Math.cos(-angle_z)+px*Math.sin(-angle_z);
        }
    }
}

public void init() {
    setBackground(new Color(0,0,0));

    // 8 vertices in local matrix
    p[1][x] = -100; p[1][y] = -100; p[1][z] = -100;
    p[2][x] = +100; p[2][y] = -100; p[2][z] = -100;
    p[3][x] = +100; p[3][y] = -100; p[3][z] = +100;
    p[4][x] = -100; p[4][y] = -100; p[4][z] = +100;
    p[5][x] = -100; p[5][y] = +100; p[5][z] = -100;
    p[6][x] = +100; p[6][y] = +100; p[6][z] = -100;
    p[7][x] = +100; p[7][y] = +100; p[7][z] = +100;
    p[8][x] = -100; p[8][y] = +100; p[8][z] = +100;

    //       8 - - - - - 7
    //     / |         / |
    //    5 - - - - - 6  |
    //    |  |        |  |
    //    |  4 - - - -|- 3
    //    | /         | /
    //    1 - - - - - 2
}

Image buffer;
Graphics2D gBuffer;

double Frames = 0;
double FPS = 0.0;
double Starttime = 0;

public void paint(Graphics g) {
    // Double-Buffering
    if (buffer==null) {
        buffer=createImage(this.getSize().width, this.getSize().height);
        gBuffer=(Graphics2D)buffer.getGraphics();
    }
    gBuffer.setColor(Color.BLACK);
    gBuffer.clearRect(0,0,this.getSize().width, this.getSize().height);

    //FPS
    if (System.currentTimeMillis()-Starttime>=1000) {
        Starttime = System.currentTimeMillis();
        FPS = Frames;
        Frames = 0;
    } else {
        Frames++;
    }

    // Antialiasing
    gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    // Local cube vertices in global matrix +200
    gBuffer.setColor(Color.BLUE);

    /*
    gBuffer.fillPolygon(new int[] {
            (int)p[1][x]+200,
            (int)p[2][x]+200,
            (int)p[6][x]+200,
            (int)p[5][x]+200},
                new int[] {
            (int)p[1][y]+200,
            (int)p[2][y]+200,
            (int)p[6][y]+200,
            (int)p[5][y]+200
                } , 4);
                */

    // texturing THE PART THAT DOES NOT WORK
    Polygon polygon = new Polygon();
    polygon.addPoint((int)p[1][x]+200, (int)p[1][y]+200);
    polygon.addPoint((int)p[2][x]+200, (int)p[2][y]+200);
    polygon.addPoint((int)p[6][x]+200, (int)p[6][y]+200);
    polygon.addPoint((int)p[5][x]+200, (int)p[5][y]+200);

    gBuffer.setClip(polygon);
    gBuffer.drawImage(tex, (int)p[1][x]+200, (int)p[1][y]+200, null);
    gBuffer.setClip(new Rectangle(0, 0, this.getWidth(), this.getHeight()));


    //Wireframe
    gBuffer.setColor(Color.CYAN);
    gBuffer.drawLine((int)(p[1][x])+200,(int)(p[1][y])+200,(int)(p[2][x])+200,(int)(p[2][y])+200);
    gBuffer.drawLine((int)(p[2][x])+200,(int)(p[2][y])+200,(int)(p[3][x])+200,(int)(p[3][y])+200);
    gBuffer.drawLine((int)(p[3][x])+200,(int)(p[3][y])+200,(int)(p[4][x])+200,(int)(p[4][y])+200);
    gBuffer.drawLine((int)(p[4][x])+200,(int)(p[4][y])+200,(int)(p[1][x])+200,(int)(p[1][y])+200);
    gBuffer.drawLine((int)(p[5][x])+200,(int)(p[5][y])+200,(int)(p[6][x])+200,(int)(p[6][y])+200);
    gBuffer.drawLine((int)(p[6][x])+200,(int)(p[6][y])+200,(int)(p[7][x])+200,(int)(p[7][y])+200);
    gBuffer.setColor(Color.LIGHT_GRAY);
    gBuffer.drawLine((int)(p[7][x])+200,(int)(p[7][y])+200,(int)(p[8][x])+200,(int)(p[8][y])+200);
    gBuffer.setColor(Color.CYAN);
    gBuffer.drawLine((int)(p[8][x])+200,(int)(p[8][y])+200,(int)(p[5][x])+200,(int)(p[5][y])+200);
    gBuffer.drawLine((int)(p[1][x])+200,(int)(p[1][y])+200,(int)(p[5][x])+200,(int)(p[5][y])+200);
    gBuffer.drawLine((int)(p[2][x])+200,(int)(p[2][y])+200,(int)(p[6][x])+200,(int)(p[6][y])+200);
    gBuffer.drawLine((int)(p[3][x])+200,(int)(p[3][y])+200,(int)(p[7][x])+200,(int)(p[7][y])+200);
    gBuffer.setColor(Color.DARK_GRAY);
    gBuffer.drawLine((int)(p[4][x])+200,(int)(p[4][y])+200,(int)(p[8][x])+200,(int)(p[8][y])+200);


    g.drawImage (buffer, 0, 0, this);







    rotate();
    move();

    repaint();
}


public void update(Graphics g) {paint(g);}
}

And here are the results: https://www.youtube.com/watch?v=lKwdHAzGReo&list=PLibL_cUAIdkBcCkFWe0qsEcPKhxxnaxdL

okay...i know I've done some things in this code which I should have done differently but this class is for test purposes only.

\$\endgroup\$
  • \$\begingroup\$ A little confused - you say cube & tagged this as 3D, but your code looks to be 2D. This post covers setting the Texture/background Image for polygon if that's what you're after; if not, you'll need to edit/clarify your question. \$\endgroup\$ – Pikalek Mar 30 '16 at 2:53
  • \$\begingroup\$ @Pikalek ok here is my whole cube class;i hope this helps \$\endgroup\$ – Clyme Mar 30 '16 at 14:05
  • 1
    \$\begingroup\$ "I already tried something but it doesn't really work" This question would be clearer if you summarised what you've already tried and in what ways it's failing to achieve your goals. Right now a user would have to read your whole source code and run it in their head to be able to guess what your problem is, and that presents a significant barrier which is likely to limit the number & quality of answers you get. Make it as easy as possible for someone to get your problem (pictures/videos often help!) and you'll get better answers, faster. \$\endgroup\$ – DMGregory Mar 30 '16 at 14:11
  • \$\begingroup\$ @Clyme If you want to create 3d graphics you might want to consider using a 3d graphics API. \$\endgroup\$ – Philipp Mar 30 '16 at 16:38
  • \$\begingroup\$ @Philipp I know, it would be easier and probably faster but like I already said in my question i want to do it in pure Java.I think it's far more fun to do everything on my own instead of using pre-coded APIs. \$\endgroup\$ – Clyme Mar 30 '16 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.