JOGL入门例子(十)---------画陀螺和控制其旋转

不知不觉写到了第十篇文章,这次画个陀螺,并且可以用键盘控制它旋转.

 

 

主窗体类,,SWING+keylistener

 

package com.gl3dgame.pegtop;               //要是想使用默认包,请去掉这行

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;

public class PegtopMain extends JFrame {

    GLRender listener = new GLRender();
    static FPSAnimator animator = null;

    public PegtopMain() throws HeadlessException {
        super("画陀螺");
        setSize(600, 480);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GLCapabilities glcaps = new GLCapabilities();
        GLCanvas canvas = new GLCanvas(glcaps);
        canvas.addGLEventListener(listener);
        this.addKeyListener(new keyEventListener());
        //canvas.addMouseListener(listener);
        getContentPane().add(canvas, BorderLayout.CENTER);
        animator = new FPSAnimator(canvas, 60, true);

        centerWindow(this);
    }

    private void centerWindow(Component frame) { // 居中窗体
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = frame.getSize();
        if (frameSize.width > screenSize.width) {
            frameSize.width = screenSize.width;
        }
        if (frameSize.height > screenSize.height) {
            frameSize.height = screenSize.height;
        }
        frame.setLocation((screenSize.width - frameSize.width) >> 1,
                (screenSize.height - frameSize.height) >> 1);

    }

    public static void main(String[] args) {
        final PegtopMain app = new PegtopMain();
        // 显示窗体
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                app.setVisible(true);
            }
        });
        // 动画线程开始
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                animator.start();
            }
        });
    }

    class keyEventListener implements KeyListener {

        public void keyTyped(KeyEvent e) {
        }

        public void keyPressed(KeyEvent e) {

            //处理键盘事件
            System.out.println(e.getKeyCode());
            if (e.getKeyCode() == 38) {
                listener.xRot -= 5.0f;
            }

            if (e.getKeyCode() == 40) {
                listener.xRot += 5.0f;
            }

            if (e.getKeyCode() == 37) {
                listener.yRot -= 5.0f;
            }

            if (e.getKeyCode() == 39) {
                listener.yRot += 5.0f;
            }


        }

        public void keyReleased(KeyEvent e) {
        }
    }
}

 
 GL控制类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gl3dgame.pegtop;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;

/**
 *
 * @author Administrator
 */
public class GLRender implements GLEventListener {

    GL gl;
// 旋转角度
    static float xRot = 0.0f;
    static float yRot = 0.0f;


    boolean iCull = false;
    boolean iOutline = false;
    boolean iDepth = true;
    float x, y, angle;  // 存储为坐标和角度

    float r,g,b;

    public void init(GLAutoDrawable drawable) {
        gl = drawable.getGL();

        // 黑色背景
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        // 设置绘图颜色为绿色
        gl.glColor3f(0.0f, 1.0f, 0.0f);

        // 设置颜色着色模型平面
        gl.glShadeModel(GL.GL_FLAT);

        // Clock wise wound polygons are front facing, this is reversed
        // because we are using triangle fans
        // 设置CW方向为“正面”,CW即ClockWise,顺时针
        gl.glFrontFace(GL.GL_CW);

       
    }

    public void display(GLAutoDrawable drawable) {

        int iPivot = 1;		// Used to flag alternating colors

        // Clear the window and the depth buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // Turn culling on if flag is set
        if (iCull) {
            gl.glEnable(GL.GL_CULL_FACE);  //剔除背面
        } else {
            gl.glDisable(GL.GL_CULL_FACE);
        }

        // Enable depth testing if flag is set
        if (iDepth) {
            gl.glEnable(GL.GL_DEPTH_TEST);
        } else {
            gl.glDisable(GL.GL_DEPTH_TEST);
        }

        // Draw back side as a polygon only, if flag is set
        //背面绘制多边形只有一个,如果标志设置
        if (iOutline) {
            gl.glPolygonMode(GL.GL_BACK, GL.GL_LINE);
        } else {
            gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL);
        }


        // Save matrix state and do the rotation
        //保存矩阵状态,做旋转
        gl.glPushMatrix();
        gl.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(yRot, 0.0f, 1.0f, 0.0f);


        // 开始三角扇形
        gl.glBegin(GL.GL_TRIANGLE_FAN);

        // Pinnacle of cone is shared vertex for fan, moved up Z axis
        // to produce a cone instead of a circle
        gl.glVertex3f(0.0f, 0.0f, 75.0f);

        // Loop around in a circle and specify even points along the circle
        // as the vertices of the triangle fan
        //环周围成一个圆圈,并指定甚至点沿为三角形的顶点圆扇
        for (angle = 0.0f; angle <= (2.0f * Math.PI+1); angle += (Math.PI / 8.0f)) {
            // 计算下一个顶点的x和y位置
            x = (float) (50.0f * Math.sin(angle));
            y = (float) (50.0f * Math.cos(angle));

             //交替颜色红色和绿色
            if ((iPivot % 2) == 0) {
                gl.glColor3f(0.0f, 1.0f, 0.0f);
            } else {
                gl.glColor3f(1.0f, 0.0f, 0.0f);
            }

            //用全随机颜色,不过效果不好看.
            //gl.glColor3f((float)Math.random(), (float)Math.random(), (float)Math.random());



            // Increment pivot to change color next time
            iPivot++;

            // Specify the next vertex for the triangle fan
            gl.glVertex2f(x, y);
        }

        // Done drawing fan for cone
        gl.glEnd();


        // 在底面画三角扇形
        gl.glBegin(GL.GL_TRIANGLE_FAN);

        // Center of fan is at the origin
        gl.glVertex2f(0.0f, 0.0f);
        for (angle = 0.0f; angle <= (2.0f * Math.PI+1); angle += (Math.PI / 8.0f)) {
            // Calculate x and y position of the next vertex
            x = (float) (50.0f * Math.sin(angle));
            y = (float) (50.0f * Math.cos(angle));

            // Alternate color between red and green
            if ((iPivot % 2) == 0) {
                gl.glColor3f(0.0f, 1.0f, 0.0f);
            } else {
                gl.glColor3f(1.0f, 0.0f, 0.0f);
            }
             //gl.glColor3f((float)Math.random(), (float)Math.random(), (float)Math.random());

            // Increment pivot to change color next time
            //增加iPivot,下一次改变颜色
            iPivot++;

            // Specify the next vertex for the triangle fan
            gl.glVertex2f(x, y);
        }

        // Done drawing the fan that covers the bottom
        //完成图纸的风扇,包括底部
        gl.glEnd();

        // Restore transformations
        gl.glPopMatrix();



    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        float nRange = 100.0f;

        // 防止为零
        if (height == 0) {
            height = 1;
        }

        //视口设置为窗口尺寸
        gl.glViewport(0, 0, width, height);

        // Reset projection matrix stack
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();

        //建立剪辑视图,正投影(左,右,底部,顶部,近,远)
        if (width <= height) {
            gl.glOrtho(-nRange, nRange, -nRange * height / width, nRange * height / width, -nRange, nRange);
        } else {
            gl.glOrtho(-nRange * width / height, nRange * width / height, -nRange, nRange, -nRange, nRange);
        }

        // 重置模型观察矩阵堆栈
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }
}

 

大家可以试着修改代码,改改颜色,把陀螺变得像钻石.

分享自己的技术论坛http://www.itneng.com/forum.php

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值