这章我们来实现用JOGL2制作简单的3D场景,并且第一次使用纹理贴图为图象服务和汉字显示FPS.
程序有点复杂,人懒,不写PPT说明了,直接看图:
图一:我们的摄像机被当作人的双眼放至场景中央.FPS已经被锁定为每秒60帧左右.
图二: 用上下左右控制摄像机移动位置,看到不同的场景效果.飞机的机身和机翼都分别用了不同纹理贴图.
图三:由于是世界杯期间编写的程序,特意添加了足球美女图,纯粹为了学习,大家见凉.
点键盘上空格键可以打开美女图,再点就关闭.
点键盘上WSDA四个键可以移动美女图的位置.
主窗体代码:
package com.gl3dgame.third; //要是想使用默认包,请去掉这行
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;
import javax.media.opengl.awt.GLCanvas;
/**
* @欢迎来到子瑜IT博客空间
* 主程序窗体类<p>
*
*调用GLRender类,定义listener对象
* 定义FPSAnimator动画线程
*
*/
public class ThirdExp extends JFrame {
GLRender listener;
static FPSAnimator animator = null;
float speed = 0.2f;
/**构造方法<p>
*
* 设置窗体大小<p>
* 添加关闭事件<p>
* 构造GLCapabilities类<p>
* 构造GLCanvas类,对象化<p>
* GLCanvas对象添加GLEventListener<p>
* 给窗体添加GLCanvas对象<p>
* 为GLCanvas对象实例化FPSAnimator动画线程<p>
* 居中窗体<p>
*
*/
public ThirdExp() {
super("场景漫游,欢迎登陆我的空间 http://wjyjimy.iteye.com/");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GLCapabilities glcaps = new GLCapabilities(null);
GLCanvas canvas = new GLCanvas(glcaps);
listener = new GLRender();
canvas.addGLEventListener(listener);
//canvas.addMouseListener(listener);
this.addKeyListener(new KeyMonitor());
getContentPane().add(canvas, BorderLayout.CENTER);
this.addMouseListener(new mouseEvent());
animator = new FPSAnimator(canvas, 60, true);
centerWindow(this);
// this.setVisible(true);
// animator.start();
}
/** 居中窗体*/
public 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 ThirdExp app = new ThirdExp();
// 显示窗体
SwingUtilities.invokeLater(new Runnable() {
public void run() {
app.setVisible(true);
}
});
// 动画线程开始
SwingUtilities.invokeLater(new Runnable() {
public void run() {
animator.start();
}
});
}
private class KeyMonitor extends KeyAdapter {
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
// System.out.println(key);
if (key == KeyEvent.VK_RIGHT) {
}
if (key == KeyEvent.VK_LEFT) {
}
if (key == KeyEvent.VK_UP) {
}
if (key == KeyEvent.VK_DOWN) {
}
if (key == KeyEvent.VK_SHIFT) {
speed = 0.2f;
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
// System.out.println(key);
if (key == KeyEvent.VK_RIGHT) {
listener.m_bsipic.g_Angle += speed * 4;
}
if (key == KeyEvent.VK_LEFT) {
listener.m_bsipic.g_Angle -= speed * 4;//左转
}
if (key == KeyEvent.VK_UP) {
double sin = Math.sin(listener.m_bsipic.rad_xz) * speed;
double cos = Math.cos(listener.m_bsipic.rad_xz) * speed;
listener.m_bsipic.g_eye[2] += sin;
listener.m_bsipic.g_eye[0] += cos;
}
if (key == KeyEvent.VK_DOWN) {
double sin = Math.sin(listener.m_bsipic.rad_xz) * speed;
double cos = Math.cos(listener.m_bsipic.rad_xz) * speed;
listener.m_bsipic.g_eye[2] -= sin;
listener.m_bsipic.g_eye[0] -= cos;
}
if (key == KeyEvent.VK_SHIFT) {
speed = speed * 4;
}
if (key == 32) {
if (listener.isspacepress == false) {
listener.isspacepress = true;
listener.m_bsipic.x=0;
listener.m_bsipic.y=0;
} else {
listener.isspacepress = false;
}
}
if (key == 33) {
listener.m_bsipic.g_elev += 0.2f;
}
if (key == 34) {
listener.m_bsipic.g_elev -= 0.2f;
}
//移动美女图
if (key == 87) {
listener.m_bsipic.y += 0.001f;
System.out.println(listener.m_bsipic.y);
}
if (key == 65) {
listener.m_bsipic.x -= 0.001f;
System.out.println(listener.m_bsipic.x);
}
if (key == 83) {
listener.m_bsipic.y -= 0.001f;
System.out.println(listener.m_bsipic.y);
}
if (key == 68) {
listener.m_bsipic.x += 0.001f;
System.out.println(listener.m_bsipic.x);
}
}
}
class mouseEvent implements MouseListener, MouseMotionListener {
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
System.out.println(e);
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
}
}
GL主类代码:
package com.gl3dgame.third;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import common.TextureReader;
import java.io.IOException;
import javax.media.opengl.GL2;
public class GLRender implements GLEventListener{
private float r;
Bsipic m_bsipic;
private FPSCounter fps;
private final float MAP = 40.0f;
boolean isspacepress;
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.3f, 1.0f); // 设置刷新背景色
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);// 刷新背景
gl.glLoadIdentity(); // 重置当前的模型观察矩阵
m_bsipic.DisplayScene();
m_bsipic.DrawGround(); //篮色网格地面线
m_bsipic.airplane(MAP+6, 10.0f, -50.0f); //组合飞机
m_bsipic.picter(MAP + 6, 0f, -MAP); //雷达
m_bsipic.picter(MAP + 10, 0f, -MAP);
m_bsipic.picter(MAP + 14, 0f, -MAP);
m_bsipic.picter(MAP + 6, 0f, -MAP-4);
m_bsipic.picter(MAP + 10, 0f, -MAP-4);
m_bsipic.picter(MAP + 14, 0f, -MAP-4);
m_bsipic.picter(MAP + 6, 0f, -MAP-8);
m_bsipic.picter(MAP + 10, 0f, -MAP-8);
m_bsipic.picter(MAP + 14, 0f, -MAP-8);
m_bsipic.picter(MAP + 6, 0f, -MAP+4);
m_bsipic.picter(MAP + 10, 0f, -MAP+4);
m_bsipic.picter(MAP + 14, 0f, -MAP+4);
m_bsipic.picter(MAP + 6, 0f, -MAP+8);
m_bsipic.picter(MAP + 10, 0f, -MAP+8);
m_bsipic.picter(MAP + 14, 0f, -MAP+8);
m_bsipic.r += 1.0f;
if (m_bsipic.r > 360) {
m_bsipic.r = 0;
}
if(isspacepress)
{
m_bsipic.drawMeinv();
}
fps.draw();
gl.glFlush(); // 更新窗口
}
public void dispose(GLAutoDrawable drawable) {
}
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glViewport(0, 0, 800, 600); // 设置OpenGL视口大小。
gl.glMatrixMode(GL2.GL_PROJECTION); // 设置当前矩阵为投影矩阵。
gl.glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵
glu.gluPerspective // 设置透视图
(54.0f, // 透视角设置为 45 度
(float) 800 / (float) 600, // 窗口的宽与高比
0.1f, // 视野透视深度:近点1.0f
3000.0f // 视野透视深度:始点0.1f远点1000.0f
);
// 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。
gl.glMatrixMode(GL2.GL_MODELVIEW); // 设置当前矩阵为模型视图矩阵
//gl.glLoadIdentity();
m_bsipic = new Bsipic(gl);
m_bsipic.light(0, 10, -20, 128);
fps = new FPSCounter(drawable, 36);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int w,
int h) {
// TODO Auto-generated method stub
}
}
画图控制类代码:
package com.gl3dgame.third;
import com.sun.opengl.util.gl2.GLUT;
import common.TextureReader;
import java.io.IOException;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
//**主图形画图类*/
public class Bsipic {
int[] g_cactus = new int[1];
GLUquadric g_text;
GL2 gl;
float r = 0;
float r2 = 0;
private int[] textureArr;
private int texture;
private String[] filename;
private final float MAP = 40.0f;
double[] g_eye = new double[3];
double[] g_look = new double[3];
float rad_xz; //角度
float g_Angle; //左右转
float g_elev; //仰俯角
boolean iskeydown = false;
GLU glu;
float x=0;
float y=0;
float z=0;
public Bsipic(GL2 gl) {
this.gl = gl;
glu = new GLU();
gl.glShadeModel(GL2.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST); // 真正精细的透视修正
g_eye[0] = MAP; //
g_eye[2] = -MAP; //
g_Angle = 0; //方位角
g_elev = 0; //俯仰角
g_text = glu.gluNewQuadric();
filename = new String[]{
"demos/data/images/cc.bmp",
"demos/data/images/bb.bmp",
"demos/data/images/meinv.bmp"
};
textureArr = new int[filename.length+1];
loadT8(filename, textureArr);
}
boolean DisplayScene() {
if (g_elev < -100) {
g_elev = -100; //仰俯角
}
if (g_elev > 100) {
g_elev = 100; //仰俯角
}
rad_xz = 3.13149f * (float) g_Angle / 180.0f;
if (g_eye[0] < -(MAP * 2 - 20)) {
g_eye[0] = -(MAP * 2 - 20); //视点的X分量限制
}
if (g_eye[0] > (MAP * 2 - 20)) {
g_eye[0] = (MAP * 2 - 20);
}
if (g_eye[2] < -(MAP * 2 - 20)) {
g_eye[2] = -(MAP * 2 - 20); //视点的Z分量限制
}
if (g_eye[2] > (MAP * 2 - 20)) {
g_eye[2] = (MAP * 2 - 20);
}
g_eye[1] = 1.8;//设置摄像机对地位置高
//摄像机的方向
double rad_xz_cos = (double) Math.cos(rad_xz);
double rad_xz_sin = (double) Math.sin(rad_xz);
g_look[0] = g_eye[0] + 100 * (double) Math.cos(rad_xz);
g_look[2] = g_eye[2] + 100 * (double) Math.sin(rad_xz);
g_look[1] = g_eye[1];
//建立modelview矩阵方向
glu.gluLookAt(g_eye[0], g_eye[1], g_eye[2],
g_look[0], g_look[1] + g_elev, g_look[2],
0.0, 1.0, 0.0);
return true;
}
void DrawGround() {
gl.glPushAttrib(GL2.GL_CURRENT_BIT);//保存现有颜色属实性
gl.glEnable(GL.GL_BLEND);//使用纹理
gl.glPushMatrix();
gl.glColor3f(0.5f, 0.7f, 1.0f);//设置蓝色
gl.glTranslatef(0.0f, 0.0f, 0.0f); //平台的定位
int size0 = (int) (MAP * 2);
gl.glLineWidth(1.0f);
gl.glBegin(GL.GL_LINES);//划一界线
for (int x = -size0; x < size0; x += 4) {
gl.glVertex3i(x, 0, -size0);
gl.glVertex3i(x, 0, size0);
}
for (int z = -size0; z < size0; z += 4) {
gl.glVertex3i(-size0, 0, z);
gl.glVertex3i(size0, 0, z);
}
gl.glEnd();
gl.glPopMatrix();
gl.glDisable(GL.GL_BLEND);
gl.glPopAttrib();//恢复前一属性
}
void airplane(float x, float y, float z)//组合飞机
{
glu = new GLU();
gl.glPushMatrix();//压入堆栈
gl.glTranslatef(x, y, z);//飞机的定位
gl.glRotatef(-r2, 0.0f, 1.0f, 0.0f);//飞机的旋转
gl.glTranslatef(30.0f, 0.0f, 0.0f); //飞机的旋转半径
gl.glRotatef(30.0f, 0.0f, 0.0f, 1.0f);//飞机的倾斜
//=============================================
gl.glPushMatrix();//
gl.glRotatef(-r2 * 30.0f, 0.0f, 0.0f, 1.0f);//飞机的旋转
gl.glColor3f(0.0f, 0.0f, 1.0f);
this.box(1.0f, 0.1f, 0.02f); //方,螺旋浆
gl.glPopMatrix();
gl.glColor3f(1.0f, 1.0f, 1.0f); //白色
gl.glEnable(GL.GL_TEXTURE_2D); //使用纹理
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[1]);//
gl.glTranslatef(0.0f, 0.0f, -0.5f); //后移
glu.gluSphere(g_text, 0.4f, 8, 8); //机头园(半径)
//=============================================
gl.glTranslatef(0.0f, -0.0f, -2); //位置调整,与机头对接
glu.gluCylinder(g_text, 0.4, 0.4, 2.0, 8, 4);//机身,园柱(半径、高)
//=====================================================
gl.glRotatef(-180.0f, 1.0f, 0.0f, 0.0f); //角度调整
gl.glTranslatef(0.0f, -0.0f, 0.0f); //位置调整,缩进一点
glu.gluCylinder(g_text, 0.4, 0.1, 1.5, 8, 4);//机尾,园锥(底半径、高)
//======================================================
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[0]);//
gl.glTranslatef(0.0f, -0.8f, 1.2f); //位置调整
this.box(1.0f, 0.05f, 0.3f); //后翼
gl.glTranslatef(0.0f, 0.1f, 0.0f); //位置调整
this.box(0.05f, 0.6f, 0.30f); //后垂翼
//======================================================
gl.glTranslatef(0.0f, 0.7f, -1.9f); //位置调整
this.box(3.0f, 0.05f, 0.5f); //前翼
//======================================================
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glPopMatrix();
r2 += 0.5f;
if (r2 > 360) {
r2 = 0;
}
}
void drawMeinv2() {
gl.glLoadIdentity();
float texMatMix[] = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(
GL.GL_FRONT_AND_BACK,
GL2.GL_AMBIENT_AND_DIFFUSE,
texMatMix, 0);
gl.glEnable(GL.GL_TEXTURE_2D);
// select the texture to work with
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[2]);
// the object to draw the texture on is a quad
gl.glBegin(GL2.GL_QUADS);
//
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-0.05f, -0.03f, -0.1f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(0.00f, -0.03f, -0.1f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(0.00f, 0.03f, -0.1f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-0.05f, 0.03f, -0.1f);
gl.glEnd();
// stop using textures
gl.glDisable(GL.GL_TEXTURE_2D);
}
void drawMeinv3() {
gl.glLoadIdentity();
float texMatMix[] = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(
GL.GL_FRONT_AND_BACK,
GL2.GL_AMBIENT_AND_DIFFUSE,
texMatMix, 0);
gl.glEnable(GL.GL_TEXTURE_2D);
// select the texture to work with
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[2]);
// the object to draw the texture on is a quad
gl.glTranslatef(x, y, -0.1f);
gl.glBegin(GL2.GL_QUADS);
//
gl.glTexCoord2f(0.0f, 0.0f);
//gl.glVertex3f(-0.05f, -0.03f, -0.1f);
gl.glVertex2f(0.00f, -0.03f);
gl.glTexCoord2f(1.0f, 0.0f);
//gl.glVertex3f(0.00f, -0.03f, -0.1f);
gl.glVertex2f(0.05f, -0.03f);
gl.glTexCoord2f(1.0f, 1.0f);
//gl.glVertex3f(0.00f, 0.03f, -0.1f);
gl.glVertex2f(0.05f, 0.03f);
gl.glTexCoord2f(0.0f, 1.0f);
//gl.glVertex3f(-0.05f, 0.03f, -0.1f);
gl.glVertex2f(0.00f, 0.03f);
gl.glEnd();
// stop using textures
gl.glDisable(GL.GL_TEXTURE_2D);
}
void drawMeinv() {
gl.glLoadIdentity();
float texMatMix[] = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(
GL.GL_FRONT_AND_BACK,
GL2.GL_AMBIENT_AND_DIFFUSE,
texMatMix, 0);
gl.glEnable(GL.GL_TEXTURE_2D);
// select the texture to work with
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[2]);
gl.glOrtho(0, 800, 0, 600, 0, 0);
// the object to draw the texture on is a quad
gl.glTranslatef(x, y, -0.1f);
gl.glBegin(GL2.GL_QUADS);
//
gl.glTexCoord2f(0.0f, 0.0f);
//gl.glVertex3f(-0.05f, -0.03f, -0.1f);
gl.glVertex2f(0.00f, -0.03f);
gl.glTexCoord2f(1.0f, 0.0f);
//gl.glVertex3f(0.00f, -0.03f, -0.1f);
gl.glVertex2f(0.05f, -0.03f);
gl.glTexCoord2f(1.0f, 1.0f);
//gl.glVertex3f(0.00f, 0.03f, -0.1f);
gl.glVertex2f(0.05f, 0.03f);
gl.glTexCoord2f(0.0f, 1.0f);
//gl.glVertex3f(-0.05f, 0.03f, -0.1f);
gl.glVertex2f(0.00f, 0.03f);
gl.glEnd();
// stop using textures
gl.glDisable(GL.GL_TEXTURE_2D);
}
void picter(float x, float y, float z) {
GLUT glut = new GLUT();
gl.glPushAttrib(GL2.GL_CURRENT_BIT);//保存现有颜色属实性
gl.glPushMatrix();//平台==============================
gl.glTranslatef(x, y + 0.5f, z); //平台的定位
gl.glColor3f(0.0f, 1.0f, 0.2f); //绿色
glut.glutSolidCube(1.3f); //方台(高)
gl.glTranslatef(0.0f, 0.8f, 0.0f); //架的位置调整,上升0.8
gl.glColor3f(0.0f, 0.0f, 1.0f); //蓝色
glut.glutSolidCube(0.3f); //长方架(宽、高、长)
gl.glPopMatrix();
gl.glPushMatrix();//雷达==============================
gl.glTranslatef(x, y + 2.1f, z); //雷达的定位1
gl.glRotatef(r - 90.0f, 0.0f, 1.0f, 0.0f); //雷达旋转2
//=======================================
gl.glColor3f(1.0f, 1.0f, 1.0f); //白色
gl.glRotatef(50.0f, 1.0f, 0.0f, 0.0f); //盘的角度调整,仰30度
glut.glutWireCone(1.5,0.6,20,20); //线园锥盘(底半径、高)
//=======================================
gl.glRotatef(180.0f, 1.0f, 0.0f, 0.0f); //杆的角度调整,反方向转
gl.glTranslatef(0.0f, 0.0f, -0.7f); //杆的位置调整,缩进一点
glut.glutWireCone(0.2,2.0,20,20); //园锥杆(底半径、高)
gl.glColor3f((float) Math.random(), 0, 0); //随机红色
gl.glTranslatef(0.0f, 0.0f, 2.0f); //杆的位置调整,缩进一点
glut.glutSolidSphere(0.3, 10, 10); //园(半径)
gl.glPopMatrix();
gl.glPushMatrix();//火箭=============================
gl.glTranslatef(x, y + 10.0f, z); //火箭的定位
gl.glRotatef(r, 0.0f, 1.0f, 0.0f); //火箭的旋转
gl.glTranslatef(15.0f, 0.0f, 0.0f); //火箭的定位
//=============================================
gl.glColor3f(1.0f, 0.0f, 0.0f); //红色
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //角度调整,与雷达平行,箭头朝前
glut.glutSolidCone(0.2f, 0.6f, 1, 1); //园锥(底半径、高)
//=============================================
gl.glColor3f(1.0f, 1.0f, 1.0f); //白色
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); //角度调整,与火箭头对接
gl.glTranslatef(0.0f, -1.0f, 0); //位置调整,与火箭头对接
glut.glutSolidCylinder(0.2, 1, 1, 1); //园柱(半径、高)
gl.glRotatef(-270.0f, 1.0f, 0.0f, 0.0f);
gl.glColor3f((float) Math.random() + 0.6f, 0.2f, 0.0f); //随机色
gl.glTranslatef(0.0f, -0.0f, -0.2f); //位置调整,缩进一点
glut.glutSolidCone(0.2, 1.5, 1, 1); //园锥(底半径、高)
gl.glPopMatrix();
gl.glPopAttrib();//恢复前一属性
}
void light(float x, float y, float z, float a) {
float light_position[] = {x, y, z, a};
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, light_position, 0);
float diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse, 0);
float ambient[] = {0.8f, 0.9f, 0.9f, 1.0f};
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, 0);
gl.glEnable(GL2.GL_LIGHTING);
gl.glEnable(GL2.GL_LIGHT0);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glEnable(GL2.GL_COLOR_MATERIAL);
}
private void box(float x, float y, float z) {
gl.glPushMatrix();//压入堆栈
gl.glScalef(x, y, z);
gl.glEnable(GL.GL_TEXTURE_2D); //使用纹理
gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);// 前
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);// 后
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);// 上
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);// 下
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);// 左
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);// 右
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glEnd();
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glPopMatrix();
}
private void makeRGBTexture(GL gl, GLU glu, TextureReader.Texture img, int target, boolean mipmapped) {
if (mipmapped) {
glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img.getPixels());
} else {
/*target为GL_TEXTURE,参数“0”代表图像的详细程度,通常就由它为零去了。参数三是数据的成分数。因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。
img.getWidth() 是纹理的宽度。如果您知道宽度,您可以在这里填入,但计算机
可以很容易的为您指出此值。 img.getHeight() 是纹理的高度。参数零是边框的
值,一般就是“0”。 GL_RGB 告诉OpenGL图像数据由红、绿、蓝三色数据组成。
GL_UNSIGNED_BYTE 意味着组成图像的数据是无符号字节类型的。最后... img.getPixels()
告诉OpenGL纹理数据的来源。*/
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(target, 0,3, img.getWidth(), img.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img.getPixels());
}
}
private boolean loadT8(String[] filenames, int[] textureArr) {
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glGenTextures(filenames.length, textureArr,0); //纹理数目,数组,类型设置0为png,1为bmg
for (int i = 0; i < filenames.length; i++) {
TextureReader.Texture texture1 = null;
try {
texture1 = TextureReader.readTexture(filenames[i]);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
if (texture1 == null) {
return false;
}
gl.glBindTexture(GL.GL_TEXTURE_2D, textureArr[i]);
makeRGBTexture(gl, glu, texture1, GL.GL_TEXTURE_2D, false);;
}
return true;
}
}
我的破电脑1.9G CPU运行的时候使用率达到5%-----20%,估计要是多添加3-4倍的雷达在场景中,CPU就很有可能到达100%,这种情况如果在一个游戏中,是不允许的,所以后面一章我们一定要学习 JOGL显示列表 -- display list.
上面代码各个功能可能稍后章节再作介绍,先发上源码供大家研究玩乐.
分享自己的技术论坛http://www.itneng.com/forum.php