这个比较烦人。我认为它比第 06 课更容易转换,但这可能是因为我至少比第 06 课更习惯了它。我仍然花了整整一夜才让它工作,但我不明白不过,直到早上。
这是我的整个代码。对最烦人的部分进行了注释,并注释了一些代码以显示哪些部分不起作用。放在评论中的任何此类代码都可能非常零散,所以我不确定您是否会理解我想要做什么,但无论如何我还是把它留下了。我遇到的两个地方是有帮助的评论和链接的两个地方。
package LWJGLTest2;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
/**
*
* @author Jay
*/
public class LWJGLTest2 {
public static final int WIDTH = 640;
public static final int HEIGHT = 480;
public static final Logger LOGGER = Logger.getLogger(LWJGLTest2.class.getName());
float xrot;
float yrot;
float xspeed;
float yspeed;
float zpos = -5f;
boolean lp;
boolean fp;
boolean light;
final float[] AMBIENT = {.5f, .5f, .5f, 1f};
final float[] DIFFUSE = {1f, 1f, 1f, 1f};
final float[] LPOSITION = {0f, 0f, 2f, 1f};
int filter;
BufferedImage textureImage;
Texture texture[] = new Texture[3];
static {
try {
LOGGER.addHandler(new FileHandler("errors.log",true));
}
catch(IOException ex) {
LOGGER.log(Level.WARNING,ex.toString(),ex);
}
}
public static void main(String[] args) {
LWJGLTest2 main = null;
try {
main = new LWJGLTest2();
main.create();
main.run();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, ex.toString(), ex);
} finally {
if (main != null) {
main.destroy();
}
}
}
public void create() throws LWJGLException {
// Display
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setFullscreen(false);
Display.setTitle("LWJGL Test");
Display.create();
// Keyboard
Keyboard.create();
// Mouse
Mouse.setGrabbed(false);
Mouse.create();
// OpenGL
initGL();
resizeGL();
}
public void destroy() {
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}
public void initGL() {
try {
loadTextures();
} catch (IOException ex) {
System.err.println(ex); System.exit(0);
}
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0f, 0f, 0f, 0.5f);
glClearDepth(1f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//FloatBuffer scratch = BufferUtils.createFloatBuffer(8); // 4 for the values and 4 for the extra buffer
//scratch.put(AMBIENT);
ByteBuffer scratch = ByteBuffer.allocateDirect(16);
scratch.order(ByteOrder.nativeOrder());
//scratch.put(AMBIENT);
glLight(GL_LIGHT1, GL_AMBIENT, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip()); // 3rd argument used to be only scratch
//scratch = ByteBuffer.allocateDirect(32).asFloatBuffer(); // reset the buffer to prevent an overflow
//scratch.put(DIFFUSE);
glLight(GL_LIGHT1, GL_DIFFUSE, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip());
//scratch = ByteBuffer.allocateDirect(32).asFloatBuffer();
//scratch.put(LPOSITION);
glLight(GL_LIGHT1, GL_POSITION, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip());
glEnable(GL_LIGHT1);
}
public void resizeGL() {
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45f, (float)WIDTH/(float)HEIGHT, 0.1f, 100f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
public void run() {
while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
if (Display.isVisible()) {
checkInput();
render();
Display.update();
}
}
}
public void checkInput() {
if (Keyboard.isKeyDown(Keyboard.KEY_L) && !lp) {
lp = true;
light = !light;
if (light)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
if (!Keyboard.isKeyDown(Keyboard.KEY_L))
lp = false;
if (Keyboard.isKeyDown(Keyboard.KEY_F) && !fp) {
fp = true;
filter = (filter + 1) % 3;
}
if (!Keyboard.isKeyDown(Keyboard.KEY_F))
fp = false;
if (Keyboard.isKeyDown(Keyboard.KEY_PRIOR))
zpos -= 0.02f;
if (Keyboard.isKeyDown(Keyboard.KEY_NEXT))
zpos += 0.02f;
if (Keyboard.isKeyDown(Keyboard.KEY_UP))
xspeed -= 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
xspeed += 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
yspeed -= 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
yspeed += 0.001f;
}
public void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0f, 0f, zpos);
glRotatef(xrot, 1f, 0f, 0f);
glRotatef(yrot, 0f, 1f, 0f);
texture[filter].bind();
glBegin(GL_QUADS);
// Front Face
glNormal3f(0f, 0f, 1f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// Back Face
glNormal3f(0f, 0f, -1f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// Top Face
glNormal3f(0f, 1f, 0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// Bottom Face
glNormal3f(0f, -1f, 0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// Right face
glNormal3f(1f, 0f, 0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// Left Face
glNormal3f(-1f, 0f, 0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd();
xrot += xspeed;
yrot += yspeed;
}
public void loadTextures() throws IOException {
//textureImage = ImageIO.read(this.getClass().getResourceAsStream("Crate.png"));
texture[0] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true, GL_NEAREST);
texture[1] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true, GL_LINEAR);
texture[2] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true);
//ByteBuffer scratch = ByteBuffer.wrap(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData());
//ByteBuffer scratch = ByteBuffer.allocateDirect(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData().length + 3);
/*
* The +3 in the last statement is important! Without it, you get this:
* SEVERE: java.lang.IllegalArgumentException: Number of remaining buffer
* elements is 0, must be at least 3. Because at most 3 elements can be
* returned, a buffer with at least 3 elements is required, regardless of
* actual returned element count
*/
//scratch.put(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData()); // RED
//scratch.rewind(); // NOW IT'S RED.
//for (int i = 0; i < scratch.limit(); ++i)
// System.out.println(scratch);
texture[2].bind();
//ByteBuffer scratch = ByteBuffer.allocateDirect(texture[2].getTextureData().length);
//scratch.order(ByteOrder.nativeOrder());
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
//GLU.gluBuild2DMipmaps(GL_TEXTURE_2D, 3, (int)texture[2].getWidth(), (int)texture[2].getHeight(), GL_RGB, GL_UNSIGNED_BYTE, (ByteBuffer)scratch.put(texture[2].getTextureData()).flip());
org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D); /* http://slick.javaunlimited.net/viewtopic.php?t=2755
* Not sure if this worked properly, but I rather enjoy
* not crying so I'll just smile and nod.
* I went through a LOT of other options before I got this.
* I also tried using the trick I found at
* http://lwjgl.org/forum/index.php?action=printpage;topic=2233.0
* (used above, in initGL) but that didn't work either.
*/
}
}
这段代码已经运行并且终于可以工作了。使用 Slick-Util 压缩了很多。您还会注意到我更改了速度的变化率;0.01f 太快了,所以我把它改成 0.001f。希望这可以帮助!
我的源代码中的链接:
“贴图”
“为什么在lwjgl中添加光这么难?”