Speeding up rotation fluently - java

When I press down 'A' the square is speeding up its own rotation, but when I release 'A' it's rotating fasted than before but looks slower than when pressing 'A'.
package backend;
import java.nio.ByteBuffer;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
public class runGame {
private long window;
private GLFWKeyCallback keyCallback;
private GLFWErrorCallback errorCallback;
public static void main(String[] args) {
new runGame().run();
}
private void run() {
try {
init();
loop();
glfwDestroyWindow(window);
keyCallback.release();
} finally {
glfwTerminate();
}
}
private static final int width = 640;
private static final int height = 480;
private void init() {
glfwSetErrorCallback(errorCallback);
if(glfwInit() != GL11.GL_TRUE) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
//glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(width, height, "mazeRunner Game", 0, 0);
if (window == NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE ) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
if( key == GLFW_KEY_A && action == GLFW_PRESS ) {
speedUp = true;
}
if( key == GLFW_KEY_A && action == GLFW_RELEASE ) {
speedUp = false;
}
}
});
ByteBuffer glfwvidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window,
(GLFWvidmode.width(glfwvidmode)-width)/2,
(GLFWvidmode.height(glfwvidmode)-height)/2);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
GLContext.createFromCurrent();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect_ratio = ((float)height) / width;
glFrustum(.5, -.5, -.5 * aspect_ratio, .5 * aspect_ratio, 1, 50);
glMatrixMode(GL_MODELVIEW);
}
private final double fps = 60.0f;
private double time;
private void loop() {
time = glfwGetTime();
while(glfwWindowShouldClose(window) == GL_FALSE) {
if(glfwGetTime()-time>=1/fps) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
time = glfwGetTime(); draw();
glfwSwapBuffers(window);
glfwPollEvents();
}
}
}
private void draw() {
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
if(speedUp==true) speed = speed+0.9f;
drawSquare(1.0f, 0.0f, 0.0f);
}
boolean speedUp;
private float speed = 20.0f;
private void drawSquare(float red,float green,float blue) {
glRotatef(speed*(float)time, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); // Draw The Cube Using quads
{
glColor3f(red, green, blue);
glVertex2f(0, 0);
glColor3f(red * .8f, green * .8f, blue * .8f);
glVertex2f(0, 1);
glColor3f(red * .5f, green * .5f, blue * .5f);
glVertex2f(1, 1);
glColor3f(red * .8f, green * .8f, blue * .8f);
glVertex2f(1, 0);
}
glEnd(); // End Drawing The Cube
}
}

The problem with different speed is related to the way you are handling the time. The variable 'time' will contain the total time since the program start when you calculate the rotation angle.
glRotatef(speed*(float)time, 0.0f, 0.0f, 1.0f);
This means that the speed difference is applied not just to the current frame but all previous frames since the program start as well. This is the reason why the rotation is faster than expected when pressing 'a' key.
It's easy to verify this. If you press 'a' directly when the program starts and you see that the speed difference is minimal. Now wait a minute or so and press 'a' again. Now the speed difference is much higher since the accumulated time is higher.
To solve the problem you probably should change the rotation calculation so that the frame time is used instead of the total program time. I.e. store the current rotation angle in a variable which you increase each frame based on the speed and frame time.

Related

LWJGL Flickering Output When Attempting to Draw Triangle

I've been trying to get into OpenGL with LWJGL and I've run into an issue that I cannot find a solution to. When trying to draw a triangle with the code below, the window opens correctly and begins flashing a shape that isn't necessarily the intended triangle (sometimes it appears briefly, but often there are rectangles in one of the quadrants of the window).
Part of my hesitation is in how OpenGL, by my reading of various posts and docs online, has changed within recent memory to use a less functional and more an object-oriented approach (VBOs and GLSL?) with GL4. Am I correct in this understanding and what are the preferred resources for learning this newer OpenGL for LWJGL?
Thank you in advance!
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Main {
private long windowID;
private float[] tri = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};
public static void main(String[] args) {
new Main().run();
}
public void run() { // Useful for making an instance class as opposed to a static main class?
init();
loop();
glfwFreeCallbacks(windowID);
glfwDestroyWindow(windowID);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
public void init() { // Initializes all LWJGL components
GLFWErrorCallback.createPrint(System.err).set(); // Create error callback route for GL
if (!glfwInit()) { // Init GLFW
throw new IllegalStateException("Failed to initialize GLFW!");
} else {
System.out.println("GLFW successfully initialized!");
}
windowID = glfwCreateWindow(640, 480, "Creating Window", NULL, NULL);
if (windowID == NULL) { // Verify window creation
throw new IllegalStateException("Failed to create window!");
} else {
System.out.println("Successfully created window!");
}
glfwDefaultWindowHints(); // Set window Proporties
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwSetKeyCallback(windowID, (window, key, scancode, action, mods) -> { // Key callback for closing the window
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, true);
});
try (MemoryStack stack = stackPush()) { // Center the window
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
glfwGetWindowSize(windowID, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos( // Center the window
windowID,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
}
glfwMakeContextCurrent(windowID); // Make the window current
glfwSwapInterval(0); // Sets the min num of pushed frames before buffers are swaped (Likely prevents horizontal tearing)
glfwShowWindow(windowID); // Unhides the window
}
private void loop() {
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // The color to clear the buffers with
while(!glfwWindowShouldClose(windowID)) { // If the window is allowed to live
glClear(GL_COLOR_BUFFER_BIT); // The OR is nessesary for some reason
FloatBuffer vBuff = BufferUtils.createFloatBuffer(6);
vBuff.put(tri);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vBuff);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glfwSwapBuffers(windowID);
glfwPollEvents();
}
}
}
You missed vBuff.flip() after the buffer was crated and filled.
vBuff.put(tri) transfers the the data to the buffer, beginning at the current position (which is the start of the buffer in this case). The buffer position is incremented by the size of the data. So the new buffer position is at the end of the new data.
flip() sets the limit (length) of the buffer to the current position and then the position is set to zero.
Further, it is not necessary to create and fill the buffer continuously in the loop, it would be sufficient to do that once before the loop:
FloatBuffer vBuff = BufferUtils.createFloatBuffer(6);
vBuff.put(tri);
vBuff.flip();
while(!glfwWindowShouldClose(windowID)) {
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vBuff);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glfwSwapBuffers(windowID);
glfwPollEvents();
}

JOGL, Animator, Scaling, Overlay

I have two graphics objects. Each object is made up of tens of thousands of triangle primitives. For the sake of this example, let`s just consider the two objects as triangles - blue triangle and orange triangles.
I want to draw the blue triangle once in the background, and use the animator to over lay the several orange triangles over the blue. Think about the blue triangle as a canvas and the orange triangles are drawn over them in a pattern. Now the canvas and the orange triangles are rotated as a whole. Also, how can I scale the whole set up and rotate them around a different axes?
In this example, I want all the orange triangles to over lay on the blue.
Here is the SSCCE. If you see in the example, the blue triangles over lay on the orange. I want all the orange triangles to be on top of blue.
Also, how do I clear the canvas from an external event like a button click and completely start redrawing the scene?
import java.awt.EventQueue;
import javax.swing.JFrame;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainWin implements GLEventListener {
private JFrame frame;
private int iter = 0;
private float rotAng = 0;
private GLProfile profile;
private GLCapabilities capabilities;
private GLCanvas canvas;
private Animator animator;
private int totIter = 15;
private float scaleFac = 1f;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWin window = new MainWin();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWin() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 600, 450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnZoom = new JButton("Zoom");
btnZoom.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
zoomObj();
}
private void zoomObj() {
canvas.invalidate();
scaleFac -= 0.5f;
}
});
frame.getContentPane().add(btnZoom, BorderLayout.NORTH);
// Initilaize graphics profile, capabilites, canvas and animator
profile = GLProfile.get(GLProfile.GL2);
capabilities = new GLCapabilities(profile);
capabilities.setNumSamples(2);
capabilities.setSampleBuffers(true);
canvas = new GLCanvas(capabilities);
canvas.addGLEventListener(this);
canvas.requestFocusInWindow();
animator = new Animator();
animator.add(canvas);
animator.start();
frame.getContentPane().add(canvas); // add to the frame
}
#Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glRotatef(15, 0, 1, 0); // rotate both blue and orange objects around Y axis
gl.glScalef(scaleFac, scaleFac, scaleFac);
//blue object
gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
gl.glEnable(GL2.GL_MULTISAMPLE);
gl.glPushMatrix();
gl.glCallList(2);
gl.glPopMatrix();
gl.glDisable(GL2.GL_MULTISAMPLE);
// orange object
gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
if (iter < totIter) {
iter++;
rotAng = 5;
gl.glRotatef((float) rotAng, 0, 0, 1); // rotate each iter by 5 aroung Z. Only the orange.
gl.glEnable(GL2.GL_MULTISAMPLE);
gl.glPushMatrix();
gl.glCallList(1);
gl.glPopMatrix();
gl.glDisable(GL2.GL_MULTISAMPLE);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (iter == totIter - 1) {
animator.stop();
}
gl.glFlush();
}
#Override
public void dispose(GLAutoDrawable drawable) {
}
#Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(.0f, .0f, .2f, 0.9f);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
// buffers for multisampling
int buf[] = new int[1];
int sbuf[] = new int[1];
gl.glGetIntegerv(GL2.GL_SAMPLE_BUFFERS, buf, 0);
gl.glGetIntegerv(GL2.GL_SAMPLES, sbuf, 0);
initObj1(gl); // Orange
initObj2(gl); // Blue
}
/**
* Blue triangle. In actual code, this is a complicated 3D object made up of atleast a few tens of thousands of
* primitives in a mesh.
*
* #param gl
*/
private void initObj2(GL2 gl) {
gl.glNewList(2, GL2.GL_COMPILE);
gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_DIFFUSE);
gl.glEnable(GL2.GL_COLOR_MATERIAL);
gl.glBegin(GL2.GL_TRIANGLES);
gl.glColor4f(.2f, .5f, 0.8f, 0.5f);
gl.glVertex3f(-0.5f, 0, 0);
gl.glVertex3f(0.5f, 0, 0);
gl.glVertex3f(0, 0.5f, 0);
gl.glEnd();
gl.glEndList();
}
/**
* Orange Triangle. In actual code, this is a complicated 3D object made up of atleast a few tens of thousands of
* primitives in a mesh.
*
* #param gl
*/
private void initObj1(GL2 gl) {
gl.glNewList(1, GL2.GL_COMPILE);
gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_DIFFUSE);
gl.glEnable(GL2.GL_COLOR_MATERIAL);
gl.glBegin(GL2.GL_TRIANGLES);
gl.glColor4f(.95f, .45f, 0.15f, 0.5f);
gl.glVertex3f(-1, 0, 0);
gl.glVertex3f(1, 0, 0);
gl.glVertex3f(0, 1, 0);
gl.glEnd();
gl.glEndList();
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
}
}

Making a triangle rotate in LWJGL3 with keycallback

So, how do I rotate a triangle by pressing Up, Down, Left or Right. I have a Keyboard class which can read keys and create events. But I don't know the function for rotating in LWJGL 3. I think I'm familiar with the classic gl.h way of rotating, but since LWJGL 3 is pretty new there aren't alot of information on this. Here is code for Display class and KeyboardHandler class.
Display
public class Driver implements Runnable{
private GLFWKeyCallback keyCallback;
private Thread thread = new Thread();
private boolean running = false;
public long window;
private static final int WIDTH = 600;
private static final int HEIGHT = WIDTH / 12 * 9;
public Driver(){
}
private synchronized void start(){
thread.start();
running = true;
}
private synchronized void stop(){
try {
thread.join();
running = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run(){
init();
while(running){
render();
update();
if(glfwWindowShouldClose(window) == GL_TRUE){
running = false;
keyCallback.release();
}
}
}
public void init() {
if(glfwInit() != GL_TRUE){
System.err.println("Failed to initilaize OpenGL");
}
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(WIDTH, HEIGHT, "Endless", NULL, NULL);
if(window == NULL){
System.err.println("Could not create window. ");
}
glfwSetKeyCallback(window, keyCallback = new KeyboardHandler());
ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, 100, 100);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
}
public void update() {
if(KeyboardHandler.isKeyDown(GLFW_KEY_LEFT)){
//event who'll start rotation
}
glfwPollEvents();
}
public void render() {
GLContext.createFromCurrent();
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(-1.0f / 2, -1.0f / 2);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.0f / 2, 1.0f / 2);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(1.0f / 2, -1.0f / 2);
glEnd();
//rotation of triangle
glfwSwapBuffers(window);
}
public static void main(String[] args) {
Driver game = new Driver();
game.start();
game.run();
}
}
And KeyboardHandler
public class KeyboardHandler extends GLFWKeyCallback{
private static boolean keys[] = new boolean[65536];
public void invoke(long window, int key, int scancode, int action, int mods)
{
keys[key] = action != GLFW_RELEASE;
}
public static boolean isKeyDown(int keycode){
return keys[keycode];
}
}
I guess the rotation itself should happen in render() while the keycallback who triggers it should be in update()
With the introduction of LWJGL 3, you must use shaders to rotate, scale, and transform your objects. You can find many resources on the internet that show you how to do this, one of them being the OpenGL programming WikiBook. Specifically, in tutorial four, which deals with rotating objects in modern OpenGL

Issue with OpenGL textures facing wrong direction

I've got a test texture in a new game that I'm creating, and for some reason, when I implement it into the game, the texture is flipped horizontally, instead of vertically. Why does this happen?
Here's a photo of the app.
As you can see, the little guy is flipped horizontally, almost as if he is sleeping. He should be facing vertically. Why is this happening, and how do I prevent it? I'll post both classes involved.
Player class:
import java.io.IOException;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
public class Player {
public Texture playerTexture;
// Positions & speed
public float xPos = 20.0f; // This is initial
public float yPos = 450.0f; // Same as above.
private float velocity = 20;
public float gravityForce = 6;
public float jumpVelocity = 25;
private static int moveSpeed = 30 / 2;
public boolean isSupported = false; // Once again, initial value.
boolean canJump = true;
// movement methods
public Texture grabTexture() {
try {
playerTexture = TextureLoader.
getTexture("PNG", ResourceLoader
.getResourceAsStream
("resources/test_char.png"));
} catch (IOException e) {
e.printStackTrace();
}
return playerTexture;
}
public void applyGravity() {
}
private void printPos(String moveMethod) {
System.out.println(moveMethod + " X: "
+ xPos + " Y: " + yPos);
}
public void moveRight() {
xPos += moveSpeed;
printPos("Moving right!");
}
public void moveLeft() {
xPos -= moveSpeed;
printPos("Moving left!");
}
public void jump() {
if (!isSupported) {
}
}
public void shoot() {
// do shooty stuff here
}
}
Main (Launcher) class:
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class Main {
private void display() {
try {
Display.setDisplayMode(new DisplayMode(1000, 550));
Display.setTitle("Unnamed Platformer Game");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// OpenGL
while (!Display.isCloseRequested()) {
initGL();
player.applyGravity();
Display.update();
Display.sync(60); // sync to 60 fps
if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
player.moveRight();
} else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
player.moveLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
player.jump();
}
}
Display.destroy();
}
private void initGL() {
// initial OpenGL items for 2D rendering
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 1000, 550, 0, 1, -1);
// start rendering player image
player.grabTexture().bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(player.xPos, player.yPos);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(player.xPos + 100, player.yPos);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(player.xPos + 100, player.yPos + 100);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(player.xPos, player.yPos + 100);
GL11.glTexCoord2f(0, 1);
GL11.glEnd(); // stop rendering this image
}
Player player = new Player();
public static void main(String[] args) {
Main main = new Main();
main.display();
}
}
GL11.glVertex2f(player.xPos, player.yPos);
GL11.glTexCoord2f(0, 0);
The issue is you're calling these functions out of order. Whenever you call glVertex2f, OpenGL will grab whatever attributes are currently set and use that for the vertex. In this case, you're setting up the texture coordinate after setting the vertex, so the coords are "delayed" by one vertex. If you swap every pair of these calls, it should work.
Also, your call to glOrtho has the top and bottom parameters swapped. The bottom value is what the y value is supposed to be at the bottom of the screen (in this case, 0). Likewise for the top value.

opengl textures not rendering correctly

The problem i am encountering is that i cannot get my texture to render in the correct proportions and for some reason the texture is also repeating itself with a space inbetween.
this is the texture im using(i am trzing to fill the screen with this texture):
When rendered it looks like this(red outline is the entire screen and texture is rendered with a 1 px border):
and here is the code:
package game;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Timer;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.TextureLoader;
public class WarZone {
private boolean done = false;
private String windowTitle = "War Zone";
private DisplayMode displayMode;
private Timer timer;
private float dt;
public static void main(String[] args) {
new WarZone().run(false);
}
public void run(boolean fullscreen) {
try {
init();
switchToOrtho();
while (!done) {
timer.tick();
update();
render();
Display.update();
}
cleanup();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
private void update() {
// Exit if Escape is pressed or window is closed
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Display.isCloseRequested()) {
done = true;
return;
}
}
private boolean render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer
GL11.glLoadIdentity(); // Reset the current modelview matrix
int w = displayMode.getWidth();
int h = displayMode.getHeight();
GL11.glColor3f(1, 0, 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(0, 0);
GL11.glVertex2i(w, 0);
GL11.glVertex2i(w, h);
GL11.glVertex2i(0, h);
GL11.glEnd();
//if(true)return false;
GL11.glColor3f(0, 1, 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(1, 1);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2i(w - 1, 1);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2i(w - 1, h - 1);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2i(1, h - 1);
GL11.glEnd();
return true; // Rendered correctly
}
public static void switchToOrtho() {
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glOrtho(0, Display.getDisplayMode().getWidth(), 0, Display.getDisplayMode().getHeight(), -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}
public static void switchToFrustum() {
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
private void init() throws Exception {
createWindow();
initGL();
load();
}
private void load() throws FileNotFoundException, IOException {
TextureLoader.getTexture("BMP", new FileInputStream("res/temp/Main_Menu_Play_Button.bmp"), true).getTextureID();
}
private void createWindow() throws Exception {
DisplayMode availibleDisplayModes[] = Display.getAvailableDisplayModes();
for (DisplayMode d:availibleDisplayModes) {
if (d.getWidth() == 640 && d.getHeight() == 480 && d.getBitsPerPixel() == 32) {
displayMode = d;
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle(windowTitle);
Display.create();
}
private void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable texture mapping
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable smooth shading
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black background
GL11.glClearDepth(1.0f); // Depth buffer setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables depth testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // Type of depth testing
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select projection matrix
GL11.glLoadIdentity(); // Reset the projection matrix
// Calculate the aspect ratio of the window
GLU.gluPerspective(45.0f, (float)displayMode.getWidth() / (float)displayMode.getHeight(), 0.1f, 100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);// Select the modelview matrix
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);// Most precise perspective calculations
}
public void requestFinish() {
done = true;
}
private void cleanup() {
Display.destroy();
}
}
I would reallz appreciate it if someone could tell me what i had done wrong.
First, I don't know what TextureLoader or newdawn.slick.opengl are, so there is only limited information I can give about this.
However, it is very possible that your texture loading code does not know how to handle non-power-of-two textures. Which means it is likely padding the texture's size out to the nearest power of two.
More importantly is this:
GL11.glColor3f(0, 1, 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(1, 1);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2i(w - 1, 1);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2i(w - 1, h - 1);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2i(1, h - 1);
GL11.glEnd();
This will draw a screen-sized quad (assuming that w and h are screen sizes). This quad maps the entire area of the texture to this quad. OpenGL is only doing what you told it to do: take the texture and map it to the quad.
If you want to draw a texture with pixel accuracy (1:1 texel to pixel), then you need to provide a width and height to the vertex positions that is equal to the texture's size, not the screen size.
Also, you set the color to (0, 1, 1). The default texture environment will multiply the per-vertex color by the texel values fetched from the texture. So you should either set the color to white, or change the texture environment.
OpenGL Doesn't like textures that are not powers of two if I recall. Is your texture a power of 2 for both height and width?
http://www.gamedev.net/topic/466904-opengl-textures-only-power-of-two/

Categories

Resources