Hello Guest

Drawing graphics and OpenGL

  • 3 Replies
  • 5702 Views
Drawing graphics and OpenGL
« on: January 17, 2014, 16:45:22 »
Hey, I'm currently developing a similiar game to minecraft to learn more about 3D graphics and OpenGL.

I've been looking around for some tutorials and some guides onto gettings started and so far I've got a a working camera that moves as I please and displays 2 objects. However I've got some questions and some things that I'm not 100% sure of. Since you're API is completely empty of actual information I'm posting here in hope to find my answers.

1. What does "GL11.glLoadIdentity();" actual do? from my understanding it just resets your position to the origin?.
But if you look at my code here:
Code: [Select]
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class Camera {
public static void main(String[] args) {
Camera cam = new Camera(0.0f, 0.0f, 0.0f);

cam.createWindow();
cam.initGL();

float dx;
float dy;
float dt;
float time;
float lastTime = 0.0f;

float mouseSensitivity = 0.15f;
float movementSpeed = 10.0f;

Mouse.setGrabbed(true);
while(!closeRequest) {
cam.renderGL();
Display.update();

time = Sys.getTime();
dt = (time - lastTime)/1000.0f;
lastTime = time;

dx = Mouse.getDX();
dy = Mouse.getDY();

cam.yaw(dx * mouseSensitivity);
cam.pitch(dy * mouseSensitivity);

//Movement
if(Keyboard.isKeyDown(Keyboard.KEY_W)) {
cam.moveForward(dt * movementSpeed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_D)) {
cam.moveRight(dt * movementSpeed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_A)) {
cam.moveLeft(dt * movementSpeed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_S)) {
cam.moveBackwards(dt * movementSpeed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
cam.moveUp(dt * movementSpeed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_X)) {
cam.moveDown(dt * movementSpeed);
}
cam.pollInput();

GL11.glLoadIdentity();
cam.lookThrough();
}

cam.cleanUp();
}
// STATIC Variables

// STATIC Methods

// Variables
public static boolean closeRequest = false;

private float x = 0;
private float y = 0;
private float z = 0;

private float yaw = 0;
private float pitch = 0;

// Constructors
public Camera(float x, float y, float z) {
move(x, y, z);
}
private void initGL() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(45.0f,(1280.0f)/((float)720.0f),0.1f,100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1.0f);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
}

// Setters
public void yaw(float amount) {
yaw += amount;
}
public void pitch(float amount) {
pitch -= amount;
}

public void move(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public void moveForward(float distance) {
            x -= distance * (float) Math.sin(Math.toRadians(yaw));
            z += distance * (float) Math.cos(Math.toRadians(yaw));
}
public void moveRight(float distance) {
            x -= distance * (float) Math.sin(Math.toRadians(yaw+90));
            z += distance * (float) Math.cos(Math.toRadians(yaw+90));
}
public void moveLeft(float distance) {
            x -= distance * (float) Math.sin(Math.toRadians(yaw-90));
            z += distance * (float) Math.cos(Math.toRadians(yaw-90));
}
public void moveBackwards(float distance) {
            x += distance * (float) Math.sin(Math.toRadians(yaw));
            z -= distance * (float) Math.cos(Math.toRadians(yaw));
}
public void moveUp(float distance) {
y -= distance;
}
public void moveDown(float distance) {
y += distance;
}

// Getters

// Adders

// Removers

// Others Methods
public void lookThrough() {
        GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
        GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
        GL11.glTranslatef(x, y, z);
}

// Implementation Methods

// Internal Classes

public void pollInput() {
while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {

}
}
}
}

public void renderGL() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

GL11.glTranslatef(-1.5f, 0.0f, -6.0f); // Move Left And Into The Screen
GL11.glRotatef(0.0f, 0.0f, 1.0f, 0.0f); // Rotate The Pyramid On It's Y Axis

GL11.glBegin(GL11.GL_TRIANGLES); // Start Drawing The Pyramid
GL11.glColor3f(1.0f, 0.0f, 0.0f); // Red
GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Left Of Triangle (Front)
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Right Of Triangle (Front)

GL11.glColor3f(1.0f, 0.0f, 0.0f); // Red
GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Left Of Triangle (Right)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Right Of Triangle (Right)

GL11.glColor3f(1.0f, 0.0f, 0.0f); // Red
GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Left Of Triangle (Back)
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Right Of Triangle (Back)

GL11.glColor3f(1.0f, 0.0f, 0.0f); // Red
GL11.glVertex3f(0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Left Of Triangle (Left)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Right Of Triangle (Left)
GL11.glEnd();

GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(1.0f, -1.0f, 1.0f); // Top Right Of The Quad (Bottom)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(-1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Bottom)
GL11.glColor3f(0.0f, 0.0f, 1.0f); // Blue
GL11.glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Bottom)
GL11.glColor3f(0.0f, 1.0f, 0.0f); // Green
GL11.glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Bottom)

GL11.glEnd(); // Done Drawing The Pyramid

//GL11.glLoadIdentity(); //If this is enabled the Cube is stays static to the camera.
GL11.glTranslatef(1.5f, 0.0f, -6.0f); // Move Right And Into The Screen
GL11.glRotatef(0.0f, 1.0f, 1.0f, 1.0f); // Rotate The Cube On X, Y & Z

GL11.glBegin(GL11.GL_QUADS); // Start Drawing The Cube
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(); // Done Drawing The Quad
}
public void createWindow() {
try {
DisplayMode[] modes = Display.getAvailableDisplayModes();

for (DisplayMode displayMode : modes) {
if(displayMode.getWidth() == 1280 && displayMode.getHeight() == 720) {
Display.setDisplayMode(displayMode);
Display.setFullscreen(false);
Display.setTitle("What's up!");
Display.create();
break;
}
}
} catch (LWJGLException e) {
Sys.alert("Error", "Initialization failed!\n\n" + e.getMessage());
System.exit(0);
}
}
public void cleanUp() {
Display.destroy();
System.exit(0);
}

}

At line 213 where I run this command. However when I run it, the cube gets stuck to the camera, in front of me weather how I move. If I don't have that line of code, everything is good. So I'm abit confused?

2. Since I'm developing something similiar to minecraft I'm going to draw ALOT of cubes, now that would require alot of proccessing so I'd like to only draw the ones that are actually visible right?. So I don't wanna draw cubes behind me, or to far away from me, or if they're just simply out of my view. I thought OpenGL handled all those things itself, but from my experience I've been losing FPS when drawing alot of cubes weather I'm looking at them or not, weather I'm a mile away or not. Suggesting OpenGL does NOT handle this, is this correct or have I got it wrong?.

Thanks in advance, and please use a fairly simple and not to complex english. Thank you.

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Drawing graphics and OpenGL
« Reply #1 on: January 17, 2014, 23:44:38 »
1) The reason the javadocs have no descriptions of those functions is that they are simply bindings to OpenGL functions. Putting in the documentation for all of those functions would be a lot of work (although that is exactly what is happening when LWJGL 3.0 is finished). You can read up on the individual OpenGL functions here: http://www.opengl.org/sdk/docs/man4/. Bookmark that, you will find it hugely useful.

What glLoadIdentity() actually does: you are essentially right. It's a little more complicated in reality but the outcome should be just that. The code sections here don't have line numbers and I'm afraid I'm not going to count 200 lines into it so I can't say specifically why it isn't doing what you expected at line 213.

2) OpenGL does handle this in the sense that you can't see the cubes that are behind you or too far away. But the act of testing whether or not to draw these cubes still takes up time. If OpenGL was to actually draw them then it would take even longer but it must still process the information to work out whether or not it should. To implement this test yourself (and you should see performance increases) look into "frustum culling."

Hope I've helped. Also hope I haven't used too complex English but as a native speaker I'm not entirely sure what a non-native speaker would consider more complex. But I tried.

Re: Drawing graphics and OpenGL
« Reply #2 on: January 18, 2014, 11:13:50 »
Thank you,

I'll sum it up, I make a display, I initGL etc, then I renderGL, I lookThrough the camera and I Display.update();
During this time I only run GL11.glLoadIdentity(); once, and that's inside the lookThrough method, If I run this anywhere in the renderGL(); everything rendered after taht will be stuck to my screen/camera.

2. If openGL does this themselves, should I bother trying to figure out myself which cubes are displaying and which are not or should I just let openGL do it?.
3. Does openGL also handle things like, Backface culling? or do I have to do that myself too?.

Thank you again, and no you're english is just fine :)

*

Offline Cornix

  • *****
  • 488
Re: Drawing graphics and OpenGL
« Reply #3 on: January 18, 2014, 12:15:39 »
1) LoadIdentity loads a matrix with only 1's into the matrix that is currently active. If you use that matrix to represent your camera then it will "reset" your camera if you want to call it that.
But the matrix can be used for almost anything; its completely up to you how to use it.
In modern openGL the loadIdentity function is deprecated as it still assumes fixed functionality pipeline. Nowadays you are supposed to define your own matrices and change their data on your own.

2) OpenGL has some functionality to discard rendering data. First of all you can define face culling and cull the back faces of your geometry. This would cut down rasterization by a good portion.
Then you can define scissor / stencil tests to not draw certain fragments on screen. If used correctly this could also cut down the performance needed for rendering.
And lastly you can always try to clip some of the blocks yourself and put some more work on the CPU instead of on the GPU. Whether this is worth it or not is to be decided by you.


The bad performance probably comes from drawing everything with immediate mode. That is glBegin(...); glEnd();
This is a very old technique that is a real performance killer and not supported on almost any hardware anymore. If you want to improve performance greatly (about 500 times on my computer) you should learn how to use VBO's, especially for static data that changes only rarely.