Was talking on irc and have this bug...
Mazon, "99% sure you're passing an invalid constant for a method"
Output
/home/kevarh/lwjgl_env/workspace/thingy/com/kevarh/testers/see-hear-speak-trans-center.gif
true
1
nullInvalid value (1281)
org.lwjgl.opengl.OpenGLException: Invalid value (1281)
at org.lwjgl.opengl.Util.checkGLError(Unknown Source)
at org.lwjgl.opengl.Display.update(Unknown Source)
at com.kevarh.testers.Game.run(Game.java:180)
at com.kevarh.testers.Game.main(Game.java:109)
Source
package com.kevarh.testers;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.openal.AL;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class Game {
/** Game title */
public static final String GAME_TITLE = "My Game";
/** Desired frame time */
private static final int FRAMERATE = 60;
/** Exit the game */
private static boolean finished;
/** A rotating square! */
private static float angle;
private static float angle2;
private static int image;
/**
* No constructor needed - this class is static
*/
private Game() {
}
/**
* Application init
*
* @param args
* Commandline args
*/
public static void main(String[] args) {
try {
init();
Thread.sleep(1000);
run();
} catch (Exception e) {
System.err.println(e.getCause() + e.getMessage());
e.printStackTrace(System.err);
Sys.alert(GAME_TITLE, "An error occured and the game will exit.");
} finally {
cleanup();
}
}
/**
* Initialise the game
*
* @throws Exception
* if init fails
*/
private static void init() throws Exception {
// Create a fullscreen window with 1:1 orthographic 2D projection, and
// with
// mouse, keyboard, and gamepad inputs.
Display.setTitle(GAME_TITLE);
Display.setFullscreen(false);
// Enable vsync if we can
Display.setVSyncEnabled(true);
Display.setDisplayMode(new DisplayMode(640, 480));
Display.create();
//GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
//GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
//GL11.glEnable(GL11.GL_);
// Start up the sound system
AL.create();
// TODO: Load in your textures etc here
System.out.println(Game.class.getClassLoader().getResource(
"com/kevarh/testers/" + "see-hear-speak-trans-center.gif")
.getPath());
try {
image = loadTexture(Game.class.getClassLoader().getResource(
"com/kevarh/testers/" + "see-hear-speak-trans-center.gif")
.getPath());
File f = new File(Game.class.getClassLoader().getResource(
"com/kevarh/testers/" + "see-hear-speak-trans-center.gif")
.getPath());
System.out.println(f.exists());
System.out.println(image);
} catch (Exception e) {
System.err.println(e.getCause() + e.getMessage());
e.printStackTrace();
}
}
/**
* Runs the game (the "main loop")
*/
private static void run() {
while (!finished) {
// Always call Window.update(), all the time
Display.update();
if (Display.isCloseRequested()) {
// Check for O/S close requests
finished = true;
} else if (Display.isActive()) {
// The window is in the foreground, so we should play the game
logic();
render();
Display.sync(FRAMERATE);
} else {
// The window is not in the foreground, so we can allow other
// stuff to run and
// infrequently update
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
logic();
if (Display.isVisible() || Display.isDirty()) {
// Only bother rendering if the window is visible or dirty
render();
}
}
}
}
/**
* Do any game-specific cleanup
*/
private static void cleanup() {
// TODO: save anything you want to disk here
// Stop the sound
AL.destroy();
// Close the window
Display.destroy();
}
/**
* Do all calculations, handle input, etc.
*/
private static void logic() {
// Example input handler: we'll check for the ESC key and finish the
// game instantly when it's pressed
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
finished = true;
}
// TODO: all your game logic goes here.
angle += 2.0f % 360;
angle2 -= 2.0f % 360;
}
/**
* Render the current frame
*/
private static void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
// TODO: all your rendering goes here
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glTranslatef(Display.getDisplayMode().getWidth() / 2, Display
.getDisplayMode().getHeight() / 2, 0.0f);
GL11.glRotatef(angle, 0, 0, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(-50, -50);
GL11.glVertex2i(50, -50);
GL11.glVertex2i(50, 50);
GL11.glVertex2i(-50, 50);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslatef(100, 100, 0.0f);
GL11.glRotatef(angle2, 0, 0, 1.0f);
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(-50, -50);
GL11.glVertex2i(50, -50);
GL11.glVertex2i(50, 50);
GL11.glVertex2i(-50, 50);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glColor3f(1.0f, 1.0f, 1.0f);
}
private static final int loadTexture(String path) {
Image image = (new javax.swing.ImageIcon(path)).getImage();
// Exctract The Image
BufferedImage tex = new BufferedImage(image.getWidth(null), image
.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = (Graphics2D) tex.getGraphics();
g.drawImage(image, null, null);
g.dispose();
// Flip Image
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -image.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
tex = op.filter(tex, null);
// Put Image In Memory
ByteBuffer scratch = ByteBuffer.allocateDirect(4 * tex.getWidth()
* tex.getHeight());
byte data[] = (byte[]) tex.getRaster().getDataElements(0, 0,
tex.getWidth(), tex.getHeight(), null);
scratch.clear();
scratch.put(data);
scratch.rewind();
// Create A IntBuffer For Image Address In Memory
IntBuffer buf = ByteBuffer.allocateDirect(4).order(
ByteOrder.nativeOrder()).asIntBuffer();
GL11.glGenTextures(buf); // Create Texture In OpenGL
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
// Typical Texture Generation Using Data From The Image
// Linear Filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
GL11.GL_LINEAR);
// Linear Filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
GL11.GL_LINEAR);
// Generate The Texture
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tex.getWidth(),
tex.getHeight(), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tex
.getWidth(), tex.getHeight(), 0, GL11.GL_RGB,
GL11.GL_UNSIGNED_BYTE, scratch);
return buf.get(0); // Return Image Address In Memory
}
}
Forgot to add, If I comment out the second to the last line in loadImage it does not bard.
I couldn't spot your problem, but I have a few (unrelated) suggestions:
1. You're clearing the color buffer twice. The second glClear is unnecessary.
2. Try using ImageIO for reading the image from disk.
3. Use 3 *, not 4, when creating the scratch buffer.
4. Why are you sending the texture data twice? The call you mention is useless, although it shouldn't "bard" :wink:.
I'm stuck in that position as well.
What are the possible causes of such an exception being thrown?
Whenever you do any opengl errors, they will be caught on a Display.update() (doing error checks each gl call would be too expensive.)
The error typically happens because you supply an invalid enum or perform some stuff without enabling the feature.
Quote from: "K.I.L.E.R"I'm stuck in that position as well.
What are the possible causes of such an exception being thrown?
The most probable is what Matzon said, usage of a wrong GL constant on a GL method. Try putting checkGLError around the code you suspect, until you spot the exact method that's producing the error.
Javapunk, try using GL11.GL_RGB8 for the texture's internal format, just in case...
The last "GL11.glTexImage2D..." is actually commented out in my version of the source, and yes that is the offending code. If I put checkGLError before and after that code and it return 0 before and 1280 after. Changing it to GL11.GL_RGB8 does not change a thing, any more ideas?
Bad drivers maybe?
Have you checked that your texture image has power of 2 dimensions?
- elias
Po2 dimensions is usually what trips me up.
Cas :)