📄 renderer.java
字号:
package demos.nehe.lesson22;
import demos.common.TextureReader;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import java.awt.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.sun.opengl.util.BufferUtil;
class Renderer implements GLEventListener {
private boolean multitextureSupported; // Flag Indicating Whether Multitexturing Is Supported
private boolean multitextureEnabled = true; // Use It If It Is Supported?
private boolean __ARB_ENABLE = true; // Used To Disable ARB Extensions Entirely
private boolean embossEnabled = false; // Emboss Only, No Basetexture?
private boolean bumpsEnabled = true; // Do Bumpmapping?
private int[] maxTexelUnits = new int[1]; // Number Of Texel-Pipelines. This Is At Least 1.
private int[] multiLogo = new int[1]; // Handle For Multitexture-Enabled-Logo
private int[] invbump = new int[3]; // Inverted Bumpmap
private int[] textures = new int[3]; // Storage For 3 Textures
private int[] glLogo = new int[1]; // Handle For OpenGL-Logo
private int filter = 1; // Which Filter To Use
private int[] bump = new int[3]; // Our Bumpmappings
private float[] lightPosition = {0.0f, 0.0f, 2.0f}; // Position is somewhat in front of screen
private float[] lightAmbient = {0.2f, 0.2f, 0.2f}; // Ambient Light is 20% white
private float[] lightDiffuse = {1.0f, 1.0f, 1.0f}; // Diffuse Light is white
private float MAX_EMBOSS = 8e-3f; // Maximum Emboss-Translate. Increase To Get Higher Immersion
// At A Cost Of Lower Quality (More Artifacts Will Occur!)
private float[] gray = Color.gray.getRGBComponents(null); // Gray Color
// Data Contains The Faces For The Cube In Format 2xTexCoord, 3xVertex;
// Note That The Tesselation Of The Cube Is Only Absolute Minimum.
private float[] data = {0f, 0f, -1f, -1f, 1f, // FRONT FACE
1f, 0f, 1f, -1f, 1f,
1f, 1f, 1f, 1f, 1f,
0f, 1f, -1f, 1f, 1f,
1f, 0f, -1f, -1f, -1f, // BACK FACE
1f, 1f, -1f, 1f, -1f,
0f, 1f, 1f, 1f, -1f,
0f, 0f, 1f, -1f, -1f,
0f, 1f, -1f, 1f, -1f, // Top Face
0f, 0f, -1f, 1f, 1f,
1f, 0f, 1f, 1f, 1f,
1f, 1f, 1f, 1f, -1f,
1f, 1f, -1f, -1f, -1f, // Bottom Face
0f, 1f, 1f, -1f, -1f,
0f, 0f, 1f, -1f, 1f,
1f, 0f, -1f, -1f, 1f,
1f, 0f, 1f, -1f, -1f, // Right Face
1f, 1f, 1f, 1f, -1f,
0f, 1f, 1f, 1f, 1f,
0f, 0f, 1f, -1f, 1f,
0f, 0f, -1f, -1f, -1f, // Left Face
1f, 0f, -1f, -1f, 1f,
1f, 1f, -1f, 1f, 1f,
0f, 1f, -1f, 1f, -1f};
private float yspeed; // Y Rotation Speed
private boolean increaseY;
private boolean decreaseY;
private float xspeed; // X Rotation Speed
private boolean increaseX;
private boolean decreaseX;
private float xrot; // X Rotation
private float yrot; // Y Rotation
private float z = -5; // Depth Into The Screen
private boolean zoomIn;
private boolean zoomOut;
private GLU glu = new GLU();
public void increaseXspeed(boolean increase) {
increaseX = increase;
}
public void decreaseXspeed(boolean decrease) {
decreaseX = decrease;
}
public void increaseYspeed(boolean increase) {
increaseY = increase;
}
public void decreaseYspeed(boolean decrease) {
decreaseY = decrease;
}
public void zoomOut(boolean zoom) {
zoomOut = zoom;
}
public void zoomIn(boolean zoom) {
zoomIn = zoom;
}
public void switchFilter() {
filter = (filter + 1) % 2;
}
public void toggleMultitexture() {
this.multitextureEnabled = !multitextureEnabled && multitextureSupported;
}
public void toggleEmboss() {
this.embossEnabled = !embossEnabled;
}
public void toggleBumps() {
bumpsEnabled = !bumpsEnabled;
}
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glEnable(GL.GL_TEXTURE_2D); // Enable Texture Mapping
gl.glShadeModel(GL.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(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations
multitextureSupported = initMultitexture(gl);
try {
loadGLTextures(gl, glu);
} catch (IOException e) {
throw new RuntimeException(e);
}
initLights(gl); // Initialize OpenGL Light
}
// isMultitextureSupported() Checks At Run-Time If Multitexturing Is Supported
private boolean initMultitexture(GL gl) {
String extensions;
extensions = gl.glGetString(GL.GL_EXTENSIONS); // Fetch Extension String
int multiTextureAvailable = extensions.indexOf("GL_ARB_multitexture");
int textureEnvCombineAvailable = extensions.indexOf("GL_ARB_texture_env_combine");
if (multiTextureAvailable != -1 // Is Multitexturing Supported?
&& __ARB_ENABLE // Override-Flag
&& textureEnvCombineAvailable != -1) {// Is texture_env_combining Supported?
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_UNITS, maxTexelUnits, 0);
return true;
}
multitextureEnabled = false; // We Can't Use It If It Isn't Supported!
return false;
}
private void loadGLTextures(GL gl, GLU glu) throws IOException { // Load PNGs And Convert To Textures
TextureReader.Texture texture = TextureReader.readTexture("demos/data/images/base.bmp");
gl.glGenTextures(3, textures, 0); // Create Three Textures
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]); // Create Nearest Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
// ========
// Use GL_RGB8 Instead Of "3" In glTexImage2D. Also Defined By GL: GL_RGBA8 Etc.
// NEW: Now Creating GL_RGBA8 Textures, Alpha Is 1.0f Where Not Specified By Format.
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[1]); // Create Linear Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[2]); // Create MipMapped Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
texture = TextureReader.readTexture("demos/data/images/Bump.bmp"); // Load The Bumpmaps
gl.glPixelTransferf(GL.GL_RED_SCALE, 0.5f); // Scale RGB By 50%, So That We Have Only
gl.glPixelTransferf(GL.GL_GREEN_SCALE, 0.5f); // Half Intenstity
gl.glPixelTransferf(GL.GL_BLUE_SCALE, 0.5f);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP); // No Wrapping, Please!
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameterfv(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_BORDER_COLOR, gray, 0);
gl.glGenTextures(3, bump, 0); // Create Three Textures
gl.glBindTexture(GL.GL_TEXTURE_2D, bump[0]); // Create Nearest Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glBindTexture(GL.GL_TEXTURE_2D, bump[1]); // Create Linear Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glBindTexture(GL.GL_TEXTURE_2D, bump[2]); // Create MipMapped Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
ByteBuffer pixels = texture.getPixels();
for (int i = 0; i < pixels.limit(); i++) // Invert The Bumpmap
pixels.put(i, (byte) (255 - pixels.get(i)));
gl.glGenTextures(3, invbump, 0); // Create Three Textures
gl.glBindTexture(GL.GL_TEXTURE_2D, invbump[0]); // Create Nearest Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glBindTexture(GL.GL_TEXTURE_2D, invbump[1]); // Create Linear Filtered Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glBindTexture(GL.GL_TEXTURE_2D, invbump[2]); // Create MipMapped Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels());
gl.glPixelTransferf(GL.GL_RED_SCALE, 1.0f); // Scale RGB Back To 100% Again
gl.glPixelTransferf(GL.GL_GREEN_SCALE, 1.0f);
gl.glPixelTransferf(GL.GL_BLUE_SCALE, 1.0f);
texture = TextureReader.readTexture("demos/data/images/opengl_alpha.bmp", true); // Load The Logo-Pngs
ByteBuffer alpha = BufferUtil.newByteBuffer(texture.getPixels().limit()); // Create Memory For RGBA8-Texture
for (int a = 0; a < alpha.capacity(); a += 4)
alpha.put(a + 3, texture.getPixels().get(a)); // Pick Only Red Value As Alpha!
texture = TextureReader.readTexture("demos/data/images/opengl.bmp", true);
for (int a = 0; a < texture.getPixels().limit(); a += 4) {
alpha.put(a, texture.getPixels().get(a)); // R
alpha.put(a + 1, texture.getPixels().get(a + 1)); // G
alpha.put(a + 2, texture.getPixels().get(a + 2)); // B
}
alpha.position(0);
alpha.limit(alpha.capacity());
gl.glGenTextures(1, glLogo, 0); // Create One Textures
gl.glBindTexture(GL.GL_TEXTURE_2D, glLogo[0]); // Create Linear Filtered RGBA8-Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, alpha);
texture = TextureReader.readTexture("demos/data/images/multi_on_alpha.bmp", true);// Load The "Extension Enabled"-Logo
alpha = BufferUtil.newByteBuffer(texture.getPixels().limit()); // Create Memory For RGBA8-Texture
for (int a = 0; a < alpha.capacity(); a += 4)
alpha.put(a + 3, texture.getPixels().get(a)); // Pick Only Red Value As Alpha!
texture = TextureReader.readTexture("demos/data/images/multi_on.bmp", true);
for (int a = 0; a < texture.getPixels().limit(); a += 4) {
alpha.put(a, texture.getPixels().get(a)); // R
alpha.put(a + 1, texture.getPixels().get(a + 1)); // G
alpha.put(a + 2, texture.getPixels().get(a + 2)); // B
}
alpha.position(0);
alpha.limit(alpha.capacity());
gl.glGenTextures(1, multiLogo, 0); // Create One Textures
gl.glBindTexture(GL.GL_TEXTURE_2D, multiLogo[0]); // Create Linear Filtered RGBA8-Texture
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, alpha);
}
private void initLights(GL gl) {
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightAmbient, 0); // Load Light-Parameters Into GL_LIGHT1
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, lightDiffuse, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPosition, 0);
gl.glEnable(GL.GL_LIGHT1);
}
void doCube(GL gl) {
int i;
gl.glBegin(GL.GL_QUADS);
// Front Face
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -