I believe it has something to do with draw order, but I've just given up at this point.
Basically, the Quads are drawing, but they're not in the right order, and backface culling is enabled but doesn't help.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.DoubleBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
public class Main {
public Main() {
this.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640,640));
Display.setTitle("FPSTest");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(-5, 5, -5, 5, -1, 5);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
int x=0;
while (!Display.isCloseRequested()) {
Display.sync(60);
//poll for keypresses first, default key is 'forward'
//if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD8));
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT|GL11.GL_COLOR_BUFFER_BIT);
GL11.glEnable(GL11.GL_CULL_FACE|GL11.GL_DEPTH_TEST);
GL11.glColor3f(1, 0, 0);
GL11.glRotatef(x++, 1, 1, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
GL11.glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
GL11.glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
GL11.glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)
GL11.glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
GL11.glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
GL11.glEnd();
GL11.glLoadIdentity();
Display.update();
}
Display.destroy();
}
public static void main(String[] argv) {
new Main();
}
}
GL11.glEnable(GL11.GL_CULL_FACE|GL11.GL_DEPTH_TEST);
You can't do this. You have to give each glEnable as a separate command. Try this instead and see if it helps you.
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_DEPTH_TEST);
Also use glGetError!
Related
I was doing and creating a triangle in the lwjgl openGL but it doesnt display the square and the triangle that I specify. I am stuck and I cant seemingly make it work, I am new to openGL lwjgl. why is it not drawing on the screen?
public Cube3D() {
try {
Display.setDisplayMode(new DisplayMode(640,480));
Display.setTitle("Gaming");
Display.create();
} catch (LWJGLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//initiallized code OPENGL
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(!Display.isCloseRequested()) { //Reset The View
glTranslatef(-1.5f,0.0f,-8.0f); // Move Left 1.5 Units And Into
// The Screen 8 (not 6.0 like
// VC../ not sure why)
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
glBegin(GL_QUADS); // Draw A Quad
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glEnd();
Display.update();
Display.sync(60);
}
Display.destroy();
}
}
It took a little bit of time but I manage to find the problem. The first is how you initialize the opengl.
Replace:
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
with:
glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45.0f, ((float) 800) / ((float) 600), 0.1f, 100.0f);
glMatrixMode(GL11.GL_MODELVIEW);
glLoadIdentity();
glEnable(GL11.GL_DEPTH_TEST);
replacing 800 with the width of the window and 600 with the height should you change the resolution.
and in your while loop put these two lines at the beginning:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
If I switch GL_QUADS to GL_TRIANGLES and remove the last point, the triangle renders fine.
However, changing it back to GL_QUADS and adding another point just leaves me with a black screen. So what do I do?
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
public class Main {
public Main() {
this.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640,640));
Display.setTitle("FPSTest");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(-10, 10, -10, 10, -1000, 1000);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested()) {
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT|GL11.GL_COLOR_BUFFER_BIT);
GL11.glRotatef(0, 1, 1, 1);
GL11.glBegin(GL11.GL_QUADS);
// GL11.glBegin(GL11.GL_TRIANGLES);
{
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glVertex3f(0.0f, 3.0f, 0.0f);
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(0.0f, 0.0f, -3.0f);
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glVertex3f(3.0f, 0.0f, 0.0f);
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(0.0f, 0.0f, 3.0f);
}
GL11.glEnd();
GL11.glLoadIdentity();
Display.update();
}
Display.destroy();
}
public static void main(String[] argv) {
new Main();
}
}
As mgibsonbr mentioned, the vertices are non-coplanar. He posted a nice tool to help you as well.
This may also help you.
If four vertices, with components; 1 <= n <= 4 are coplanar then the determinant of the matrix:
|x1 y1 z1 1|
|x2 y2 z2 1|
|x3 y3 z3 1|
|x4 y4 z4 1|
will be 0.
The vertices of a quad must be coplanar. The four vertices you specified are not, and according to this, the results are undefined in this case (which is probably the reason for the blank screen).
Here's a tool to help you find the plane equation, so you can choose a coplanar 4th point. Your first 3 points form the equation -9x -9y +9z + 27 = 0, so one example of a suitable point is:
GL11.glVertex3f(2.0f, 2.0f, 1.0f);
You can also use glBegin(GL_TRIANGLE_STRIP), all triangles are coplanar ;)
I'm trying to learn how to use LWJGL libraries. Took me forever to find lessons. I eventually stumbled upon the NEHE lessons that teach OpenGL across many programming languages. I downloaded the LWJGL version of Lesson07 and noticed it was using DevIL for the images.
I asked a question on here earlier on what i should use instead of DevIL, and an informative user suggested that i go with Slick instead. I got past Lesson06 after tweaking it for a while, but now i am seriously stuck on Lesson07.
Specifically HERE:
private int[] loadTexture(String path) {
IntBuffer image = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
IL.ilGenImages(1, image);
IL.ilBindImage(image.get(0));
IL.ilLoadImage(path);
IL.ilConvertImage(IL.IL_RGB, IL.IL_BYTE);
ByteBuffer scratch = ByteBuffer.allocateDirect(IL.ilGetInteger(IL.IL_IMAGE_WIDTH) * IL.ilGetInteger(IL.IL_IMAGE_HEIGHT) * 3);
IL.ilCopyPixels(0, 0, 0, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 1, IL.IL_RGB, IL.IL_BYTE, scratch);
// Create A IntBuffer For Image Address In Memory
IntBuffer buf = ByteBuffer.allocateDirect(12).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
// Create Nearest Filtered Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
// Create Linear Filtered Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(1));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
// Create MipMapped Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(2));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 3, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
return new int[]{ buf.get(0), buf.get(1), buf.get(2) }; // Return Image Addresses In Memory
}
I've tried to get it working, tried substituting Slick stuff in, yet all i have tried has either crashed or led to a black screen.
What is the best way to do this with Slick?
This one was rather annoying. I think it was easier to convert than Lesson 06, but that could be because I was at least a little more used to it than I was in 06. It still took me all night to get this to work and I didn't figure it out until morning, though.
Here's my entire code. Lines are commented on the most annoying parts, along with some CODE commented to show what DIDN'T work. Any such code that was put in a comment is probably very fragmented so I'm not sure if you'll understand what I was trying to do, but I left it in anyway. The two places that I got stuck at are the two places with helpful comments and links.
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.
*/
}
}
This code has been run and FINALLY works. Using Slick-Util compresses it a LOT. You'll also notice that I changed the rate of change for the speeds; 0.01f was way too fast, so I put it to 0.001f instead. Hope this helps!
Links from my source code:
"Mipmapping"
"Why is adding of the light in lwjgl so difficult?"
You'll probably need to adapt the code to use the standard LWJGL image / texture loading features, at least up to the point of the glBindTexture() call. After that point I think you should be OK, it's all pretty standard OpenGL from that point.
There is some pretty decent example code here that demonstrates what you need to do:
http://lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_1_-_Loading_Images_for_LWJGL
I think the key lines of code you need are:
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
...
Texture texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/image.png"));
...
GL11.glBind(texture.getTextureID());
In other words, I think it's actually a bit simpler than using DevIL.
Seriously I'm getting mad with this code, because don't work:
switch(particle) {
case 0:
glBegin(GL_TRIANGLE_STRIP); // STONE
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2d(1, 1); glVertex3f(x+size, y+size, 0.0f); // Top Right
glTexCoord2d(0.5, 1); glVertex3f(x-size, y+size, 0.0f); // Top Left
glTexCoord2d(1, 0.5); glVertex3f(x+size, y-size, 0.0f); // Bottom Right
glTexCoord2d(0.5, 0.5); glVertex3f(x-size, y-size, 0.0f); // Bottom Left
glEnd();
break;
case 1:
glBegin(GL_TRIANGLE_STRIP); // EARTH
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2d(0.5, 0.5); glVertex3f(x+size, y+size, 0.0f); // Top Right
glTexCoord2d(0, 0.5); glVertex3f(x-size, y+size, 0.0f); // Top Left
glTexCoord2d(0.5, 0); glVertex3f(x+size, y-size, 0.0f); // Bottom Right
glTexCoord2d(0, 0); glVertex3f(x-size, y-size, 0.0f); // Bottom Left
glEnd();
break;
}
The case 0 works fine, but the case 1 doesn't and I don't know why...
This is the image (32x32 with two 16x16 sub-textures):
Give that case 0 apparently works fine, your texture coordinates for case 1 are wrong. They should be:
glBegin(GL_TRIANGLE_STRIP); // EARTH
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2d(0.5, 1.0); glVertex3f(x+size, y+size, 0.0f); // Top Right
glTexCoord2d(0, 1.0); glVertex3f(x-size, y+size, 0.0f); // Top Left
glTexCoord2d(0.5, 0.5); glVertex3f(x+size, y-size, 0.0f); // Bottom Right
glTexCoord2d(0, 0.5); glVertex3f(x-size, y-size, 0.0f); // Bottom Left
glEnd();
I'm trying to get a spotlight working but it's not showing up could someone have a look and see where I've went wrong?
package water3;
import Common.TextureReader;
import com.sun.opengl.util.BufferUtil;
import java.io.IOException;
import javax.media.opengl.glu.GLUquadric;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.media.opengl.glu.GLU;
class Renderer implements GLEventListener {
private GLUquadric quadric;
private Object3D object3D;
private float[] LightPos = {0.0f, 5.0f, -4.0f, 1.0f}; // Light Position
private boolean LightUp, LightDown, LightLeft, LightRight, LightForward, LightBackward;
private int[] textures = new int[3]; // Storage For 3 Textures
double aNum = 1;
private boolean aDown =false;
private boolean up =false;
private GLU glu = new GLU();
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
try {
loadGLTextures(drawable);
} catch (IOException e) {
System.out.println("Couldn't load model/Texture");
throw new RuntimeException(e);
}
/*
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.glClearStencil(0); // Stencil 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
/* gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, LightPos, 0); // Set Light1 Position
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, LightAmb, 0); // Set Light1 Ambience
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, LightDif, 0); // Set Light1 Diffuse
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, LightSpc, 0); // Set Light1 Specular
gl.glEnable(GL.GL_LIGHT1);
*/// Enable Light1
// Enable Lighting
/*
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, MatAmb, 0); // Set Material Ambience
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, MatDif, 0); // Set Material Diffuse
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, MatSpc, 0); // Set Material Specular
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, MatShn, 0); // Set Material Shininess
*/
gl.glClearColor(0,0,0,1);
gl.glEnable(GL.GL_LIGHT0);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glShadeModel(GL.GL_SMOOTH);
gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE);
gl.glCullFace(GL.GL_BACK); // Set Culling Face To Back Face
gl.glEnable(GL.GL_CULL_FACE); // Enable Culling
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set Clear Color (Greenish Color)
quadric = glu.gluNewQuadric(); // Initialize Quadratic
glu.gluQuadricNormals(quadric, GL.GL_SMOOTH); // Enable Smooth Normal Generation
glu.gluQuadricTexture(quadric, false);
}
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
// Clear Color Buffer, Depth Buffer, Stencil Buffer
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
gl.glLoadIdentity();
SetSpotlight(gl);
SetFloorMaterial(gl);
gl.glPushMatrix();
// Reset Modelview Matrix
gl.glTranslatef(0.0f, 0.0f, -20.0f); // Zoom Into The Screen 20 Units
gl.glEnable(GL.GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
drawRoom(gl); // Draw The Room
gl.glPopMatrix();
gl.glFlush(); // Flush The OpenGL Pipeline
}
private void drawRoom(GL gl) { // Draw The Room (Box)
gl.glBegin(GL.GL_QUADS); // Begin Drawing Quads
// Floor
gl.glNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
gl.glVertex3f(-20.0f, -20.0f, -40.0f); // Back Left
gl.glVertex3f(-20.0f, -20.0f, 40.0f); // Front Left
gl.glVertex3f(20.0f, -20.0f, 40.0f); // Front Right
gl.glVertex3f(20.0f, -20.0f, -40.0f); // Back Right
// Ceiling
gl.glNormal3f(0.0f, -1.0f, 0.0f); // Normal Point Down
gl.glVertex3f(-10.0f, 10.0f, 20.0f); // Front Left
gl.glVertex3f(-10.0f, 10.0f, -20.0f); // Back Left
gl.glVertex3f(10.0f, 10.0f, -20.0f); // Back Right
gl.glVertex3f(10.0f, 10.0f, 20.0f); // Front Right
// Back Wall
gl.glNormal3f(0.0f, 0.0f, -1.0f); // Normal Pointing Towards Viewer
gl.glVertex3f(20.0f, 20.0f, 30.0f); // Top Right
gl.glVertex3f(20.0f, -20.0f, 30.0f); // Bottom Right
gl.glVertex3f(-20.0f, -20.0f, 30.0f); // Bottom Left
gl.glVertex3f(-20.0f, 20.0f, 30.0f); // Top Left
// Left Wall
gl.glNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
gl.glVertex3f(-20.0f, 20.0f, 30.0f); // Top Front
gl.glVertex3f(-20.0f, -20.0f, 30.0f); // Bottom Front
gl.glVertex3f(-20.0f, -20.0f, -30.0f); // Bottom Back
gl.glVertex3f(-20.0f, 20.0f, -30.0f); // Top Back
// Right Wall
gl.glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
gl.glVertex3f(20.0f, 20.0f, -30.0f); // Top Back
gl.glVertex3f(20.0f, -20.0f, -30.0f); // Bottom Back
gl.glVertex3f(20.0f, -20.0f, 30.0f); // Bottom Front
gl.glVertex3f(20.0f, 20.0f, 30.0f); // Top Front
gl.glPushMatrix();
// Front Wall
gl.glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Away From Viewer
gl.glTexCoord2f(1,1);
gl.glVertex3f(-20.0f, 20.0f, -30.0f); // Top Left
gl.glTexCoord2f(1,0);
gl.glVertex3f(-20.0f, -20.0f, -30.0f); // Bottom Left
gl.glTexCoord2f(0,0);
gl.glVertex3f(20.0f, -20.0f, -30.0f); // Bottom Right
gl.glTexCoord2f(0,1);
gl.glVertex3f(20.0f, 20.0f, -30.0f); // Top Right
gl.glPopMatrix();
gl.glEnd(); // Done Drawing Quads
}
public void reshape(GLAutoDrawable drawable,int xstart,int ystart,int width,int height) {
GL gl = drawable.getGL();
height = (height == 0) ? 1 : height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glRotatef(90, 0.0f, 0.0f, 1.0f);
glu.gluPerspective(60, (float) width / height, 1, 1000);
glu.gluLookAt(1.0f,0.0f,25.0f,
0.0f,0.0f,0.0f,
0.0f,0.0f,1.0f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,boolean deviceChanged) { }
private void loadGLTextures(GLAutoDrawable gldrawable) throws IOException {
TextureReader.Texture texture = null;
texture = TextureReader.readTexture("data/images/04.bmp");
GL gl = gldrawable.getGL();
//Create Nearest Filtered Texture
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
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,
3,
texture.getWidth(),
texture.getHeight(),
0,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
texture.getPixels());
}
public void SetSpotlight(GL gl){
gl.glDisable(GL.GL_LIGHTING);
// prepare spotlight
float spot_ambient[] = {50.2f,0.0f,0.0f,1.0f };//white ={10.2f,10.2f,10.2f,1.0f };
float spot_diffuse[] = {50.8f,0.0f,0.0f,1.0f };
float spot_specular[] = {50.8f,0.0f,0.0f,1.0f };
// set colors here and do the geometry in draw
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, spot_ambient,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, spot_diffuse,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, spot_specular,0);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);
// set light position
// since ligth follows the model when mousing
// spotlight as it moves with the scene
float spot_position[] = {0.0f,60.0f,-30.0f,1.0f};
float spot_direction[] = {0.0f,0.0f,-1.0f};
float spot_angle = 10.0f;
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, spot_position,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION,spot_direction,0);
gl.glLightf(GL.GL_LIGHT0, GL.GL_SPOT_CUTOFF,(float)spot_angle);
// "smoothing" the border of the lightcone
// change this for effect
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, new float[] {0.7f,0.7f,1}, 0 );
gl.glLighti(GL.GL_LIGHT0, GL.GL_SPOT_EXPONENT, 20);
gl.glEnable(GL.GL_LIGHTING);
}
public void SetFloorMaterial(GL gl){
float amb[]={0.3f,0.3f,0.0f,1.0f};
float diff[]={1.0f,1.0f,0.5f,1.0f};
float spec[]={0.6f,0.6f,0.5f,1.0f};
float shine=0.25f;
gl.glMaterialfv(GL.GL_FRONT,GL.GL_AMBIENT,amb,0);
gl.glMaterialfv(GL.GL_FRONT,GL.GL_DIFFUSE,diff,0);
gl.glMaterialfv(GL.GL_FRONT,GL.GL_SPECULAR,spec,0);
gl.glMaterialf(GL.GL_FRONT,GL.GL_SHININESS,shine*128.0f);
}
}
OpenGL's fixed function pipeline does illumination only at vertices and then just interpolates. Since the walls of your rooms are just very large quads, every wall has only 4 vertices, so only 4 lighting calculations happen. For a spotlight effect you'd need a lot more lighting calculations. So you've to refine (i.e. tesselate) the walls' meshes, or use per pixel lighting (i.e. do lighting calculations on the fragment level – this is done using shaders).