OpenlGL游戏编程-简单的机器人制作(二)

OpenlGL游戏编程-简单的机器人制作(二)


!注意本教程是基于java的,我会在这里从创建java项目一步一步的写。(java版本为java8)


开场

上节课我们学习了怎么创建swing和OpenGL结合的窗口,那么这节课,我们将学习如何将一个机器人显示到屏幕上


首先,我们需要创建GameRobot类,具体定义如下:

package main;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;

public class GameRobot{
    GLAutoDrawable glad;
    GL2 gl;
    public GameRobot(GLAutoDrawable glad) {
        this.glad = glad;
        gl = glad.getGL().getGL2();
    }

    private void drawHead(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(1f, 1f, 1f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(2f, 2f, 2f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawBody(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(0f, 1f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(3f, 5f, 2f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawLeg(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(1f, 1f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(1f, 5f, 1f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawArm(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(1f, 0f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(1f, 4f, 1f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawEar(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(0.5f, 0.5f, 0.5f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(0.25f, 0.25f, 0.25f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawMouth(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glColor3f(1f, 0f, 1f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(0.75f, 0.25f, 0.25f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

    private void drawCube(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();

        gl.glTranslated(xPos, yPos, zPos);

        gl.glBegin(GL2.GL_QUADS);

        //上面
        gl.glVertex3f(0f, 0f, -1f);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(1f, 0f, 0f);
        gl.glVertex3f(1f, 0f, -1f);
        //下面
        gl.glVertex3f(0f, -1f, -1f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, -1f, -1f);
        //正面
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, 0f, 0f);
        //背面
        gl.glVertex3f(0f, 0f, -1f);
        gl.glVertex3f(0f, -1f, -1f);
        gl.glVertex3f(1f, -1f, -1f);
        gl.glVertex3f(1f, 0f, -1f);
        //左面
        gl.glVertex3f(0f, 0f, -1);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(0f, -1f, -1f);
        //右面
        gl.glVertex3f(1f, 0f, -1);
        gl.glVertex3f(1f, 0f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, -1f, -1f);

        gl.glEnd();

        gl.glPopMatrix();
    }

    public void drawRobet(float xPos, float yPos, float zPos) {
        //开始绘制机器人
        gl.glPushMatrix();

        gl.glTranslated(xPos, yPos, zPos);

        //头绘制
        drawHead(2f, 2f, 0f);
        //身躯绘制
        drawBody(1.5f, 0f, 0f);
        //绘制嘴巴
        drawMouth(2.625f,0.35f,0.25f);
        //绘制二只耳朵
        drawEar(1.75f,1.0f,-0.825f);
        drawEar(3.75f,1.0f,-0.825f);
        //绘制二只胳膊
        drawArm(4.5f, -0.5f, -0.5f);
        drawArm(0.5f, -0.5f, -0.5f);
        //绘制二条腿
        drawLeg(4.5f, -4.5f, -0.5f);
        drawLeg(0.5f, -4.5f, -0.5f);

        gl.glPopMatrix();
        //机器人绘制完毕
    }
}
  1. drawCube(float xPos, float yPos, float zPos)这个函数是画一个1*1的单位矩形,机器人的部件就是在此基础上修改的
  2. gl.glPushMatrix()这个函数是将当前的矩阵堆栈复制,压入一个堆栈里,配合gl.glPopMatrix()这个函数用,那这么做有什么用呢?我们这么用的话,我们相当于无论怎么样操作坐标系,移动,旋转,缩放等,都不影响上一层的矩阵堆栈,这样就可以非常简单方便的绘制有趣的东西,不然坐标的来回转换谁受得了。
  3. 至于像这些gl.glVertex3f(1f, -1f, -1f),gl.glTranslated(xPos, yPos, zPos)等等的函数,我就不在这里介绍了,具体的看这里JOGL基础教程

接下来,让我们回到GameGLEventListener类,其定义如下:

package main;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;

public class GameGLEventListener implements GLEventListener {

    GLU glu = new GLU();
    GameRobot robot;

    @Override
    public void init(GLAutoDrawable glad) {
        robot = new GameRobot(glad);
        GL2 gl = glad.getGL().getGL2();
        gl.glShadeModel(GL2.GL_SMOOTH);
        gl.glClearDepth(1.0f);// 设置深度缓存   
        gl.glEnable(GL2.GL_DEPTH_TEST);// 启用深度测试   
        gl.glDepthFunc(GL2.GL_LEQUAL);// 所作深度测试的类型  
        gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
    }

    @Override
    public void dispose(GLAutoDrawable glad) {

    }

    @Override
    public void display(GLAutoDrawable glad) {
        GL2 gl = glad.getGL().getGL2();
        //设置清除颜色为黑色,并清除颜色缓存和深度缓存
        gl.glClearColor(0f, 0f, 0f, 1f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        //重置坐标系
        gl.glLoadIdentity();
        //开始绘制机器人(正面)
        gl.glPushMatrix();
        gl.glTranslated(0f, 0f, -30f);
        gl.glRotatef(0f, 0f, 1f, 0f);
        robot.drawRobet(0f, 0f, 0f);
        gl.glPopMatrix();
        //机器人绘制完毕
    }

    @Override
    public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
        GL2 gl = glad.getGL().getGL2();
        if (height <= 0) {
            height = 1;
        }
        h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45f, h, 0.1f, 100f);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

}

init(GLAutoDrawable glad)reshape(GLAutoDrawable glad, int x, int y, int width, int height)的内容具体的请看Opengl教程


那么主函数的定义呢?还是跟上节课一样,不需要改动,我在这在贴一个主函数:

package main;

public class Main {

    public static void main(String[] args) {
        GameJFrame frame = new GameJFrame("Opengl游戏编程",0,0,500,500);
        frame.start();
    }

}

收场

执行成功后,效果如下:
执行成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值