lwjgl 3 engine does not show anything - java

Im coding a Game with lwjgl3. I initially used lwjgl 2. but of major chanllenges, i switched to lwjgl3.
I walked through a couple tutorials and put together a gameloop with a window class and tried to implement the code i already had.
I had to change multiple things, had challenges like the slick util textureloader, but now im stuck:
Basically what i see is the Window, but nothing is displayed on it.
My Engine is fairly big by now, but i will try to implement the important methods. When you need more, i can post more.
I will post the Shaderfiles for entity and skybox (what im trying to display currently) too
And all i see is a Window with nothing displayed
MAIN CLASS
package main;
import static org.lwjgl.glfw.GLFW.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import entities.Camera;
import entities.Light;
import entities.Player;
import graphics.Window;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.renderEngine.Loader;
import graphics.renderEngine.MasterRenderer;
import graphics.renderEngine.OBJLoader;
import graphics.textures.ModelTexture;
import toolbox.Vector3f;
public class Main
{
private GLFWErrorCallback errorCallback = GLFWErrorCallback.createPrint(System.err);
private Window window;
private MasterRenderer renderer;
private Loader loader;
private int Width;
private int Height;
private boolean running = false;
private double delta;
List<Light> lights = new ArrayList<Light>();
Camera camera = null;
private Player player;
public Main()
{
init();
}
private void input()
{
glfwPollEvents();
if(window.shouldClose()) stop();
}
private void update()
{
renderer.setHeight(Height);
renderer.setWidth(Width);
renderer.setDelta(delta);
}
private void render()
{
renderer.processEntity(player);
renderer.render(lights, camera);
window.render();
}
private void run()
{
long lastTime = System.nanoTime();
long currentTime = lastTime;
long diff = 0;
long timer = System.currentTimeMillis();
double ns = 1000000000 / 60.0;
delta = 0.0;
double dfps = 1000000000 / 60.0;
double d = 0.0;
int fps = 0;
int ups = 0;
while(running)
{
currentTime = System.nanoTime();
diff = currentTime - lastTime;
delta += (diff)/ ns;
d += diff/dfps;
lastTime = currentTime;
while(delta >= 1.0)
{
input();
update();
ups++;
delta--;
}
if(d >- 1.0)
{
render();
fps++;
d = 0.0;
}
if(System.currentTimeMillis() > timer + 1000)
{
window.setTitle("Junker.5 | ups: "+ups+"| fps: "+fps+"");
ups = 0;
fps = 0;
timer += 1000;
}
}
cleanUp();
}
public void start()
{
if(running) return;
running = true;
run();
}
public void stop()
{
if(!running) return;
running = false;
}
private void init()
{
Width = 1280;
Height = 720;
glfwSetErrorCallback(errorCallback);
glfwInit();
window = new Window(Width, Height, "Junker.5");
GL.createCapabilities();
loader = new Loader();
renderer = new MasterRenderer(loader);
renderer.setHeight(Height);
renderer.setWidth(Width);
renderer.setDelta(delta);
RawModel playerShip = OBJLoader.loadObjModel("Puddle Jumper", loader);
TexturedModel playership = new TexturedModel(playerShip, ModelTexture.loadTexture("white"));
player = new Player(playership, new Vector3f(0, 0, -50),0,0,0,1);
lights.add(new Light(new Vector3f(0,1000,-5000), new Vector3f(0f,0.4f,5f)));
lights.add(new Light(new Vector3f(0,0,-10), new Vector3f(1,0,1), new Vector3f(1, 0.01f, 0.002f)));
try
{
camera = new Camera(player);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void cleanUp()
{
window.hide();
//guiRenderer.cleanUp();
renderer.cleanUp();
loader.cleanUp();
window.dispose();
}
public static void main(String[] args)
{
Main main = new Main();
main.start();
}
public int getWidth()
{
return window.getWidth();
}
public int getheight()
{
return window.getHeight();
}
public double getDelta()
{
return delta;
}
}
MASTER RENDERER CLASS
package graphics.renderEngine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.lwjgl.opengl.GL11;
import entities.Camera;
import entities.Entity;
import entities.Light;
import entities.Player;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.shaders.StaticShader;
import graphics.shaders.TerrainShader;
import graphics.skybox.SkyboxRenderer;
import graphics.terrains.Terrain;
import graphics.textures.ModelTexture;
import toolbox.Matrix4f;
import toolbox.Vector3f;
public class MasterRenderer
{
private static final float FOV = 70;
private static final float NEAR_PLANE = 0.01f;
private static final float FAR_PLANE = 1000;
public int Width;
public double delta;
public int Height;
private Matrix4f projectionMatrix;
private StaticShader shader = new StaticShader();
private TerrainRenderer terrainRenderer;
private TerrainShader terrainShader = new TerrainShader();
private EntityRenderer renderer;
private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();
private List<Terrain> terrains = new ArrayList<Terrain>();
private SkyboxRenderer skyboxRenderer ;
public MasterRenderer(Loader loader)
{
enableCulling();
createProjectionMatrix();
renderer = new EntityRenderer(shader, projectionMatrix);
terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
skyboxRenderer = new SkyboxRenderer(loader, projectionMatrix);
}
public static void enableCulling()
{
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK);
}
public static void disableCullig()
{
GL11.glDisable(GL11.GL_CULL_FACE);
}
public void render(List<Light> lights, Camera camera)
{
prepare();
shader.start();
shader.loadLights(lights);
shader.loadViewMatrix(camera);
renderer.render(entities);
shader.stop();
terrainShader.start();
terrainShader.loadLights(lights);
terrainShader.loadViewMatrix(camera);
terrainRenderer.render(terrains);
terrainShader.stop();
skyboxRenderer.render(camera);
terrains.clear();
entities.clear();
}
public void processTerrain(Terrain terrain)
{
terrains.add(terrain);
}
public void processEntity(Entity entity)
{
TexturedModel entityModel = entity.getModel();
List<Entity> batch = entities.get(entityModel);
if(batch != null)
{
batch.add(entity);
}
else
{
List<Entity> newBatch = new ArrayList<Entity>();
newBatch.add(entity);
entities.put(entityModel, newBatch);
}
}
private void createProjectionMatrix()
{
float aspectRatio = (float) Width / (float) Height;
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
public void prepare()
{
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(0.03f, 0f, 0.0f, 1);
}
public void cleanUp()
{
shader.cleanUp();
terrainShader.cleanUp();
}
public void setWidth(int width)
{
Width = width;
}
public void setHeight(int height)
{
Height = height;
}
public void setDelta(double delta)
{
this.delta = delta;
}
}
STATIC SHADER CLASS
package graphics.shaders;
import java.util.List;
import entities.Camera;
import entities.Light;
import toolbox.Maths;
import toolbox.Matrix4f;
import toolbox.Vector3f;
public class StaticShader extends ShaderProgram
{
public static final String VERTEX_FILE = "./Ressources/Shaders/VertexShader.shd";
public static final String FRAGMENT_FILE = "./Ressources/Shaders/FragmentShader.shd";
public static final int MAX_LIGHTS = 4;
private int location_transformationMatrix;
private int location_projectionMatrix;
private int location_viewMatrix;
private int location_lightPosition[];
private int location_lightColour[];
private int location_attenuation[];
private int location_shineDamper;
private int location_reflectivity;
private int location_useFakeLighting;
public StaticShader()
{
super(VERTEX_FILE, FRAGMENT_FILE);
}
#Override
protected void bindAttributes()
{
super.bindAttribute(0, "position");
super.bindAttribute(1, "textureCoords");
super.bindAttribute(2, "normal");
}
protected void getAllUniformLocations()
{
location_transformationMatrix = super.getUniformLocation("transformationMatrix");
location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix");
location_shineDamper = super.getUniformLocation("shineDamper");
location_reflectivity = super.getUniformLocation("reflectivity");
location_useFakeLighting = super.getUniformLocation("useFakeLighting");
location_lightPosition = new int[MAX_LIGHTS];
location_attenuation = new int[MAX_LIGHTS];
location_lightColour = new int[MAX_LIGHTS];
for(int i = 0;i<MAX_LIGHTS;i++)
{
location_lightPosition[i] = super.getUniformLocation("lightPosition["+i+"]");
location_lightColour[i] = super.getUniformLocation("lightColour["+i+"]");
location_attenuation[i] = super.getUniformLocation("attenuation["+i+"]");
}
}
public void loadFakeLightingVariable(boolean useFake)
{
super.loadBoolean(location_useFakeLighting, useFake);
}
public void loadShineVariables(float damper, float reflectivity)
{
super.LoadFloat(location_shineDamper, damper);
super.LoadFloat(location_reflectivity, reflectivity);
}
public void loadTreansformationMatrix(Matrix4f matrix)
{
super.loadMatrix(location_transformationMatrix, matrix);
}
public void loadLights(List<Light> lights)
{
for(int i = 0;i<MAX_LIGHTS;i++)
{
if(i<lights.size())
{
super.LoadVector(location_lightPosition[i], lights.get(i).getPosition());
super.LoadVector(location_lightColour[i], lights.get(i).getColour());
super.LoadVector(location_attenuation[i], lights.get(i).getAttenuation());
}
else
{
super.LoadVector(location_lightPosition[i], new Vector3f(0,0,0));
super.LoadVector(location_lightColour[i], new Vector3f(0,0,0));
super.LoadVector(location_attenuation[i], new Vector3f(1,0,0));
}
}
}
public void loadViewMatrix(Camera camera)
{
Matrix4f viewMatrix = Maths.createViewMatrix(camera);
super.loadMatrix(location_viewMatrix, viewMatrix);
}
public void loadProjectionMatrix(Matrix4f projection)
{
super.loadMatrix(location_projectionMatrix, projection);
}
}
SHADERFILES:
FRAGMENT SHADER
#version 400 core
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector[4];
in vec3 toCameraVector;
out vec4 out_Color;
uniform sampler2D textureSampler;
uniform vec3 lightColour[4];
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 attenuation[4];
void main(void)
{
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 totalDiffuse = vec3(0.0);
vec3 totalSpecular = vec3(0.0);
for(int i=0;i<4;i++)
{
float distance = length(toLightVector[i]);
float attFactor = attenuation[i].x + (attenuation[i].y * distance) + (attenuation[i].z * distance * distance);
vec3 unitLightVector = normalize(toLightVector[i]);
float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1,0.0);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor,0.0);
float dampedFactor = pow(specularFactor,shineDamper);
totalSpecular = totalSpecular + (dampedFactor * reflectivity * lightColour[i])/attFactor;
totalDiffuse = totalDiffuse + (brightness * lightColour[i])/attFactor;
}
totalDiffuse = max(totalDiffuse, 0.2);
vec4 textureColour = texture(textureSampler, pass_textureCoords);
if(textureColour.a<0.5)
{
discard;
}
out_Color = vec4(totalDiffuse,1.0) * texture(textureSampler, pass_textureCoords) + vec4(totalSpecular,1.0);
}
VERTEX SHADER
#version 400 core
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector[4];
out vec3 toCameraVector;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[4];
uniform float useFakeLighting;
void main(void)
{
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoords = textureCoords;
vec3 actualNormal = normal;
if(useFakeLighting > 0.5)
{
actualNormal = vec3(0.0,1.0,0.0);
}
surfaceNormal = (transformationMatrix * vec4(actualNormal,0.0)).xyz;
for(int i=0;i<4;i++)
{
toLightVector[i] = lightPosition[i] - worldPosition.xyz;
}
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
}
I have absolutely no idea what im doing wrong. If anyone wants to really help me more personal on this problem, feel free to contact me too.
Thank you soo much!
EDIT:
Yes, the Clearcolor works, thats part of why i am confused.
And before i worked ofer my lwjgl2 code to my new lwjgl3 code, the lwjgl3 window DID display simple graphics such as a 3d cube
Here is my window class
WINDOW
package graphics;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
public class Window
{
private long window;
private int Width;
private int Height;
public Window(int width, int height, String title)
{
this.Width = width;
this.Height = height;
glfwDefaultWindowHints();
glfwWindowHint(GLFW_RESIZABLE, GL11.GL_FALSE);
glfwWindowHint(GLFW_VISIBLE, GL11.GL_TRUE);
//DECORATION
glfwWindowHint(GLFW_DECORATED, GL11.GL_TRUE);
glfwWindowHint(GLFW_FOCUSED, GL11.GL_TRUE);
window = glfwCreateWindow(Width,Height,"Junker.5",NULL,NULL);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(
window,
(vidmode.width() - width) / 2,
(vidmode.height() - height) / 2
);
glfwMakeContextCurrent(window);
}
public void dispose()
{
glfwDestroyWindow(window);
}
public void hide()
{
glfwHideWindow(window);
}
public void render()
{
glfwSwapBuffers(window);
}
public void show()
{
glfwShowWindow(window);
}
public void setTitle(String title)
{
glfwSetWindowTitle(window, title);
}
public boolean shouldClose()
{
if(!glfwWindowShouldClose(window))
{
return false;
}
else
{
return true;
}
}
public int getWidth()
{
return Width;
}
public void setWidth(int width)
{
Width = width;
}
public int getHeight()
{
return Height;
}
public void setHeight(int height)
{
Height = height;
}
public void changecursor()
{
// Create the cursor object
//long cursor = GLFW.glfwCreateCursor(imageBuffer, 0, 0);
/*if (cursor == MemoryUtil.NULL)
throw new RuntimeException("Error creating cursor");
// Set the cursor on a window
GLFW.glfwSetCursor(window, cursor);*/
}
}

I did manage to fix the problem myself, atleast its displaying stuff now :)
I just hardcoded the Width and height right now. The method of doing a setHeight() in the Main class must have angried the gods of my createProjectionMatrix() function. However, id would be awesome to know how to do this dynamic for future purposes

Related

How would I make the camera not rotate as the player rotates?

Right now, whenever my player turns, the camera turns with it. This was intentional, but I changed my mind on that feature when I inputted other camera controls, and right now, I can't seem to disable that functionality without breaking the whole camera system. I'm working with OpenGL and LWJGL, but I don't think knowledge in those will be too necessary for this. I basically want the camera not to turn as the player does. Thank you for your time, and have a
Here is the camera class:
package entities;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector3f;
public class Camera {
private float distanceFromPlayer = 50;
private float angleAroundPlayer = 0;
private Vector3f position = new Vector3f(10,20,10);
private float pitch = 45;
private float yaw;
private float roll;
private Player player;
public Camera(Player player){
this.player = player;
}
public void move(){
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){
angleAroundPlayer -= 1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){
angleAroundPlayer += 1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
pitch += 1;
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
pitch -= 1;
}
float horizontalDistance = calculateHorizontalDistance();
float verticalDistance = calculateVerticalDistance();
calculateCameraPosition(horizontalDistance,verticalDistance);
this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
}
public Vector3f getPosition() {
return position;
}
public float getPitch() {
return pitch;
}
public float getYaw() {
return yaw;
}
public float getRoll() {
return roll;
}
private float calculateHorizontalDistance(){
return (float)(distanceFromPlayer * Math.cos(Math.toRadians(pitch)));
}
private float calculateVerticalDistance(){
return (float)(distanceFromPlayer * Math.sin(Math.toRadians(pitch)));
}
private void calculateCameraPosition(float horizontalDistance, float verticalDistance){
float theta = player.getRotY() + angleAroundPlayer;
float offsetX = (float)(horizontalDistance * Math.sin(Math.toRadians(theta)));
float offsetZ = (float)(horizontalDistance * Math.cos(Math.toRadians(theta)));
position.x = player.getPosition().x - offsetX;
position.z = player.getPosition().z - offsetZ;
position.y = player.getPosition().y + verticalDistance;
}
}
And here is the player class:
package entities;
import models.TexturedModel;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector3f;
import renderEngine.DisplayManager;
public class Player extends Entity{
private static final float RUN_SPEED = 20;
private static final float TURN_SPEED = 180;
private static final float GRAVITY = -50;
private static final float JUMP_POWER = 40;
private static final float TERRAIN_HEIGHT = 0.5f;
private float currentSpeed = 0;
private float currentTurnSpeed = 0;
private float upwardsSpeed = 0;
private boolean isInAir = false;
public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale) {
super(model, position, rotX, rotY, rotZ, scale);
}
public void move(){
checkInputs();super.increaseRotation(0,currentTurnSpeed * DisplayManager.getFrameTimeSeconds(),0);
float distance = currentSpeed * DisplayManager.getFrameTimeSeconds();
float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotY())));
float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotY())));
super.increasePosition(dx,0,dz);
upwardsSpeed += GRAVITY * DisplayManager.getFrameTimeSeconds();
super.increasePosition(0,upwardsSpeed * DisplayManager.getFrameTimeSeconds(),0);
if(super.getPosition().y < TERRAIN_HEIGHT){
upwardsSpeed =0;
isInAir = false;
super.getPosition().y = TERRAIN_HEIGHT;
}
}
private void jump(){
if(!isInAir){
this.upwardsSpeed = JUMP_POWER;
isInAir = true;
}
}
private void checkInputs(){
if(Keyboard.isKeyDown(Keyboard.KEY_W)){
this.currentSpeed = RUN_SPEED;
}
else if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
this.currentSpeed = -RUN_SPEED;
}
else{
this.currentSpeed = 0;
}
if(Keyboard.isKeyDown(Keyboard.KEY_D)){
this.currentTurnSpeed = -TURN_SPEED;
}
else if(Keyboard.isKeyDown(Keyboard.KEY_A)){
this.currentTurnSpeed = TURN_SPEED;
}
else{
this.currentTurnSpeed = 0;
}
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
jump();
}
}
}
And if needed, here is the Entity Class:
package entities;
import models.TexturedModel;
import org.lwjgl.util.vector.Vector3f;
public class Entity {
private TexturedModel model;
private Vector3f position;
private float rotX,rotY,rotZ;
private float scale;
public Entity(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ,float scale){
this.model = model;
this.position = position;
this.rotX = rotX;
this.rotY = rotY;
this.rotZ = rotZ;
this.scale = scale;
}
public void increasePosition(float dx, float dy, float dz){
this.position.x += dx;
this.position.y += dy;
this.position.z += dz;
}
public void increaseRotation(float dx, float dy, float dz){
this.rotX += dx;
this.rotY += dy;
this.rotZ += dz;
}
public TexturedModel getModel() {
return model;
}
public Vector3f getPosition() {
return position;
}
public float getRotX() {
return rotX;
}
public float getRotY() {
return rotY;
}
public float getRotZ() {
return rotZ;
}
public float getScale() {
return scale;
}
public void setModel(TexturedModel model) {
this.model = model;
}
public void setPosition(Vector3f position) {
this.position = position;
}
public void setRotX(float rotX) {
this.rotX = rotX;
}
public void setRotY(float rotY) {
this.rotY = rotY;
}
public void setRotZ(float rotZ) {
this.rotZ = rotZ;
}
public void setScale(float scale) {
this.scale = scale;
}
}

JavaFX Asteroids Game Clone: Having trouble bouncing asteroids off eachother

I am trying to make an Asteroids game clone in JavaFX. So far, I have been able to draw the ship and asteroids onto the screen (where Rectangles represent them, for now). I have also implemented movement for the ship, and randomized movements for the asteroids.
I am having trouble implementing the code needed to bounce the asteroids off each other. The current method that does the collision checking (called checkAsteroidCollisions) is bugged in that all asteroids start stuttering in place. They don't move, but rather oscillate back and forth in place rapidly. Without the call to this method, all asteroids begin moving normally and as expected.
Instead, I want each asteroid to move freely and, when coming into contact with another asteroid, bounce off each other like in the actual Asteroids game.
MainApp.java
import java.util.ArrayList;
import java.util.HashSet;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class MainApp extends Application {
private static final int WIDTH = 700;
private static final int HEIGHT = 900;
private static final int NUM_OF_ASTEROIDS = 12;
private static final Color ASTEROID_COLOR = Color.GRAY;
private static final Color PLAYER_COLOR = Color.BLUE;
private Player player;
private ArrayList<Entity> asteroids;
long lastNanoTime; // For AnimationTimer
HashSet<String> inputs; // For inputs
private static final int MAX_SPEED = 150;
private static final int SPEED = 10;
private static final int ASTEROID_SPEED = 150;
private StackPane background;
/*
* Generates a random number between min and max, inclusive.
*/
private float genRandom(int min, int max) {
return (float) Math.floor(Math.random() * (max - min + 1) + min);
}
/*
* Initializes the asteroids
*/
private void initAsteroids() {
this.asteroids = new ArrayList<Entity>();
for (int i = 0; i < NUM_OF_ASTEROIDS; i++) {
Entity asteroid = new Entity(50, 50, ASTEROID_COLOR, EntityType.ASTEROID);
float px = (float) genRandom(200, WIDTH - 50);
float py = (float) genRandom(200, HEIGHT - 50);
asteroid.setPos(px, py);
// Keep recalculating position until there are no collisions
while (asteroid.intersectsWith(this.asteroids)) {
px = (float) genRandom(200, WIDTH - 50);
py = (float) genRandom(200, HEIGHT - 50);
asteroid.setPos(px, py);
}
// Randomly generate numbers to change velocity by
float dx = this.genRandom(-ASTEROID_SPEED, ASTEROID_SPEED);
float dy = this.genRandom(-ASTEROID_SPEED, ASTEROID_SPEED);
asteroid.changeVelocity(dx, dy);
this.asteroids.add(asteroid);
}
}
/*
* Initializes the player
*/
private void initPlayer() {
this.player = new Player(30, 30, PLAYER_COLOR, EntityType.PLAYER);
this.player.setPos(WIDTH / 2, 50);
}
/*
* Checks collisions with screen boundaries
*/
private void checkOffScreenCollisions(Entity e) {
if (e.getX() < -50)
e.setX(WIDTH);
if (e.getX() > WIDTH)
e.setX(0);
if (e.getY() < -50)
e.setY(HEIGHT);
if (e.getY() > HEIGHT)
e.setY(0);
}
/*
* Controls speed
*/
private void controlSpeed(Entity e) {
if (e.getDx() < -MAX_SPEED)
e.setDx(-MAX_SPEED);
if (e.getDx() > MAX_SPEED)
e.setDx(MAX_SPEED);
if (e.getDy() < -MAX_SPEED)
e.setDy(-MAX_SPEED);
if (e.getDy() > MAX_SPEED)
e.setDy(MAX_SPEED);
}
/*
* Controls each asteroid's speed and collision off screen
*/
private void controlAsteroids(ArrayList<Entity> asteroids) {
for (Entity asteroid : asteroids) {
this.checkOffScreenCollisions(asteroid);
this.controlSpeed(asteroid);
}
}
/*
* Checks an asteroid's collision with another asteroid
*/
private void checkAsteroidCollisions() {
for (int i = 0; i < NUM_OF_ASTEROIDS; i++) {
Entity asteroid = this.asteroids.get(i);
if (asteroid.intersectsWith(this.asteroids)){
float dx = (float) asteroid.getDx();
float dy = (float) asteroid.getDy();
asteroid.setDx(0);
asteroid.setDy(0);
asteroid.changeVelocity(-dx, -dy);
}
}
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Hello World!");
this.initAsteroids();
this.initPlayer();
background = new StackPane();
background.setStyle("-fx-background-color: pink");
this.inputs = new HashSet<String>();
Group root = new Group();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent e) {
String code = e.getCode().toString();
inputs.add(code);
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent e) {
String code = e.getCode().toString();
inputs.remove(code);
}
});
Canvas canvas = new Canvas(WIDTH, HEIGHT);
GraphicsContext gc = canvas.getGraphicsContext2D();
background.getChildren().add(canvas);
root.getChildren().add(background);
lastNanoTime = System.nanoTime();
new AnimationTimer() {
#Override
public void handle(long currentNanoTime) {
float elapsedTime = (float) ((currentNanoTime - lastNanoTime) / 1000000000.0);
lastNanoTime = currentNanoTime;
/* PLAYER */
// Game Logic
if (inputs.contains("A"))
player.changeVelocity(-SPEED, 0);
if (inputs.contains("D"))
player.changeVelocity(SPEED, 0);
if (inputs.contains("W"))
player.changeVelocity(0, -SPEED);
if (inputs.contains("S"))
player.changeVelocity(0, SPEED);
// Collision with edge of map
checkOffScreenCollisions(player);
// Control speed
controlSpeed(player);
player.update(elapsedTime);
/* ASTEROIDS */
gc.setFill(ASTEROID_COLOR);
for(int i = 0; i < NUM_OF_ASTEROIDS; i++) {
checkAsteroidCollisions(i); // BUGGY CODE
}
controlAsteroids(asteroids);
gc.clearRect(0, 0, WIDTH, HEIGHT);
for (Entity asteroid : asteroids) {
asteroid.update(elapsedTime);
asteroid.render(gc);
}
gc.setFill(PLAYER_COLOR);
player.render(gc);
}
}.start();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Entity.java:
import java.util.ArrayList;
import javafx.geometry.Rectangle2D;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
public class Entity {
private Color color;
private double x, y, width, height, dx, dy;
private EntityType entityType; // ID of this Entity
public Entity(float width, float height, Color color, EntityType type) {
this.x = this.dx = 0;
this.y = this.dy = 0;
this.width = width;
this.height = height;
this.color = color;
this.entityType = type;
}
/*
* Getters and setters
*/
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public double getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public double getDx() {
return dx;
}
public void setDx(float dx) {
this.dx = dx;
}
public double getDy() {
return dy;
}
public void setDy(float dy) {
this.dy = dy;
}
public EntityType getEntityType() {
return entityType;
}
/*
* Adds to dx and dy (velocity)
*/
public void changeVelocity(float dx, float dy) {
this.dx += dx;
this.dy += dy;
}
/*
* Sets position
*/
public void setPos(float x, float y) {
this.setX(x);
this.setY(y);
}
/*
* Gets new position of the Entity based on velocity and time
*/
public void update(float time) {
this.x += this.dx * time;
this.y += this.dy * time;
}
/*
* Used for collisions
*/
public Rectangle2D getBoundary() {
return new Rectangle2D(this.x, this.y, this.width, this.height);
}
/*
* Checks for intersections
*/
public boolean intersectsWith(Entity e) {
return e.getBoundary().intersects(this.getBoundary());
}
/*
* If any of the entities in the passed in ArrayList
* intersects with this, then return true;
*/
public boolean intersectsWith(ArrayList<Entity> entities) {
for(Entity e : entities) {
if(e.getBoundary().intersects(this.getBoundary()))
return true;
}
return false;
}
/*
* Draws the shape
*/
public void render(GraphicsContext gc) {
gc.fillRoundRect(x, y, width, height, 10, 10);
}
#Override
public String toString() {
return "Entity [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + ", entityType=" + entityType
+ "]";
}
}
I think you will need to change the position of the two colliding asteroids slightly so their state is not on collision anymore.
What happens right now is that you change their movement after the collision but I guess that your algorithm notices that they are still touching, so it will try to change the movement again with the same result as before.
What you need to implement now is a change in the position of the two asteroids so your collision detection won´t act up again immediately after it´s first call.
I hope I could help you.

How to edit vertex shader in JOGL

So im working on a Java/Jogl application that basically just translates the vertices of a triangle. So far I am able to get the triangle to move left to right, but I cant figure out how to edit the vertex shader so that when I click a button, the triangle begins to move up and down instead of left and right.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.*;
import javax.swing.*;
import static com.jogamp.opengl.GL4.*;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.FPSAnimator;
import graphicslib3D.GLSLUtils;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.Vector;
public class a1 extends JFrame implements GLEventListener
{
private GLCanvas myCanvas;
private int rendering_program;
private int vao[] = new int[1];
private GLSLUtils util = new GLSLUtils();
private Button button1, button2;
private float x = 0.0f;
private float y = 0.0f;
private float inc = 0.01f;
private float incy = 0.01f;
private int click = 1;
public a1()
{ setTitle("Chapter2 - program2");
setSize(600, 400);
myCanvas = new GLCanvas();
myCanvas.addGLEventListener(this);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(myCanvas, BorderLayout.CENTER);
JPanel sidePanel = new JPanel();
sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
button1 = new Button("button");
button2 = new Button("button2");
sidePanel.add(button1);
sidePanel.add(button2);
getContentPane().add(sidePanel, BorderLayout.WEST);
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
click = 1;
}
});
setVisible(true);
FPSAnimator animator = new FPSAnimator(myCanvas, 30);
animator.start();
}
public void display(GLAutoDrawable drawable)
{ GL4 gl = (GL4) GLContext.getCurrentGL();
gl.glUseProgram(rendering_program);
gl.glPointSize(50.0f);
float bkg[] = {0.0f, 0.0f, 0.0f, 1.0f};
FloatBuffer bkgBuffer = Buffers.newDirectFloatBuffer(bkg);
gl.glClearBufferfv(GL_COLOR, 0, bkgBuffer);
x+=inc;
y+=incy;
if(x > 1.0f) inc = -0.01f;
if(x < -1.0f) inc = 0.01f;
if(y > 1.0f) incy = -0.01f;
if(y< -1.0f) incy = 0.01f;
int offset_loc = gl.glGetUniformLocation(rendering_program, "inc");
int offset_y = gl.glGetUniformLocation(rendering_program, "incy");
int flag = gl.glGetUniformLocation(rendering_program, "flag");
gl.glProgramUniform1f(rendering_program, offset_loc, x);
gl.glProgramUniform1f(rendering_program, offset_y, y);
gl.glProgramUniform1f(rendering_program, flag, click);
gl.glDrawArrays(GL_TRIANGLES,0,3);
}
public void init(GLAutoDrawable drawable)
{ GL4 gl = (GL4) GLContext.getCurrentGL();
rendering_program = createShaderProgram();
gl.glGenVertexArrays(vao.length, vao, 0);
gl.glBindVertexArray(vao[0]);
}
private int createShaderProgram()
{
GL4 gl = (GL4) GLContext.getCurrentGL();
int[] vertCompiled = new int[1];
int[] fragCompiled = new int[1];
int[] linked = new int[1];
String vshaderSource[] = readShaderSource("src/vert.shader");
String fshaderSource[] = readShaderSource("src/frag.shader");
int vShader = gl.glCreateShader(GL_VERTEX_SHADER);
gl.glShaderSource(vShader, vshaderSource.length, vshaderSource, null, 0);
gl.glCompileShader(vShader);
util.checkOpenGLError();
gl.glGetShaderiv(vShader, GL_COMPILE_STATUS, vertCompiled, 0);
if(vertCompiled[0] == 1)
{
System.out.println("vertex compilation success");
}else{
System.out.println("vertex compilation failed");
util.printShaderLog(vShader);
}
int fShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
gl.glShaderSource(fShader, fshaderSource.length, fshaderSource, null, 0);
gl.glCompileShader(fShader);
util.checkOpenGLError();
gl.glGetShaderiv(fShader, GL_COMPILE_STATUS, fragCompiled, 0);
if(fragCompiled[0] == 1)
{
System.out.println("fragment compilation success");
}else{
System.out.println("fragment compilation failed");
util.printShaderLog(fShader);
}
int vfprogram = gl.glCreateProgram();
gl.glAttachShader(vfprogram, vShader);
gl.glAttachShader(vfprogram, fShader);
gl.glLinkProgram(vfprogram);
util.checkOpenGLError();
gl.glGetProgramiv(vfprogram, GL_LINK_STATUS, linked, 0);
if(linked[0] == 1)
{
System.out.println("linking succeeded");
}else{
System.out.println("linking failed");
util.printProgramLog(vfprogram);
}
//gl.glDeleteShader(vShader);
//gl.glDeleteShader(fShader);
return vfprogram;
}
public static void main(String[] args) { new a1(); }
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
public void dispose(GLAutoDrawable drawable) {}
private String[] readShaderSource(String filename)
{
Vector<String> lines = new Vector<String>();
Scanner sc;
try
{
sc = new Scanner(new File(filename));
}catch (IOException e)
{
System.err.println("IOException reading file: " + e);
return null;
}
while(sc.hasNext())
{
lines.addElement(sc.nextLine());
}
String[] program = new String[lines.size()];
for(int i=0; i<lines.size(); i++)
{
program[i] = (String) lines.elementAt(i)+ "\n";
}
return program;
}
}
#version 430
uniform float inc;
void main(void)
{
if(gl_VertexID == 0) gl_Position = vec4(0.25, -0.25+inc, 0.0, 1.0);
else if(gl_VertexID == 1) gl_Position = vec4(-0.25, -0.25+inc, 0.0, 1.0);
else gl_Position = vec4(0.25, 0.25+inc, 0.0, 1.0);
}
How do I edit my vertex shader so that when I click on a button the location of the vertices changes and the triangle begins to move up and down instead of left to right?
1) Don't do the update like that
2) Don't use an int array for the OpenGL resources (vao), prefer a direct integer buffer, you can use GLBuffers.newDirectIntBuffer(1); for the vao for example..
3) Don't use an FPSAnimator, use Animator instead
4) Don't inialize a new direct buffer everytime in the display() method (bkgBuffer), do it just once in the variable declaration or in the init(). You should also dispose any direct buffer, since it is not guaranteed that they are gonna be removed by the garbage collector. I have a small class for that here. A better one however is the implementation of Gouessej here.
4) Use a vertex buffer object to declare your vertices attributes (like position)
5) Declare a boolean flag variable update to trigger the update.
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
update = 1;
}
});
public void display(GLAutoDrawable drawable) {
GL4 gl = (GL4) GLContext.getCurrentGL();
if(update) {
update = false;
...
}
}
now you have 2 possibilities:
you update the vertices directly
gl3.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX));
gl3.glBufferSubData(GL_ARRAY_BUFFER, 0, vertexBuffer.capacity(), vertexBuffer);
gl3.glBindBuffer(GL_ARRAY_BUFFER, 0);
and your vertex shader may be something like
#version 430
layout (location = POSITION) in vec2 position;
void main(void)
{
gl_Position = vec4(position, 0, 1);
}
you update only the matrix that is going to multiply the vertices
gl3.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.TRANSFORM));
gl3.glBufferSubData(GL_UNIFORM_BUFFER, 0, Mat4.SIZE, matBuffer);
gl3.glBindBuffer(GL_UNIFORM_BUFFER, 0);
and in this case the vertex may be
#version 430
layout (location = POSITION) in vec2 position;
layout (binding = TRANSFORM) uniform Transform
{
mat4 mat;
};
void main(void)
{
gl_Position = mat * vec4(position, 0, 1);
}
In case you need further assistance, don't hesitate to ask for help.
For inspiration, you can refer to this hello triangle of mine

OpenGL ES 1.0 strange texture behavior

I am learning how to work with OpenGL ES 1.0 (I was told that it is better to start with "1.0"/"1.1").
I am trying to create transperent 3D globe on android device using transparent texture and vertex indexing but having problem which I don't understand and can't find any solution on internet.
The problem is that depending on angle of camera rotation my globe stops rendering "back side" of sphere or sphere back sides texture. On image below you can see what happens if I rotate camera in same direction.
Link to image: CLICK HERE (I have no reputation to add image directly, sorry)
So can you help me? What is my mistake, why "back" is disappearing?
"Sphere" class:
package com.example.OpenGL_Testing.openGl.geometry;
import com.example.OpenGL_Testing.openGl.Texture;
import javax.microedition.khronos.opengles.GL10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
public class Sphere {
float step = 5f; // density of sphere; step in degrees
float[] verArray;
float[] texIndex;
short[] verIndex;
private FloatBuffer vBuff;
private FloatBuffer tBuff;
private ShortBuffer iBuff;
public final float mCenterX, mCenterY, mCenterZ;
public final float mRadius;
private final GL10 mGL;
private int stepsPai, stepsTheta;
private Texture texture;
public Sphere(float mRadius, float mCenterX, float mCenterY, float mCenterZ, GL10 mGL) {
this.mGL = mGL;
// sphere parameters
this.mRadius = mRadius;
this.mCenterX = mCenterX;
this.mCenterY = mCenterY;
this.mCenterZ = mCenterZ;
stepsPai = (int) (180f / step) ; //sphere vertical 'lines'
stepsTheta = (int) (360f / step) + 1; //sphere horizontal 'lines'
// create sphere 'dots'
createVerticesBuff();
createIndexingBuffer();
}
private float[] createVerticesArray() {
float[] vertices = new float[stepsPai * stepsTheta * 3];
int n = 0;
float cRadius, cHeight, co, si;
for (float pai = 180f - step; pai > 0f; pai -= step) {
cRadius = (float) Math.sin((pai + step) * Math.PI / 180f);
cHeight = (float) Math.cos((pai + step) * Math.PI / 180f);
for (float theta = 0.0f; theta <= 360f; theta += step) {
co = (float) Math.cos(theta * Math.PI / 180f);
si = -(float) Math.sin(theta * Math.PI / 180f);
vertices[n * 3] = mRadius * (cRadius * co) + mCenterX;
vertices[n * 3 + 1] = mRadius * (cHeight) + mCenterY;
vertices[n * 3 + 2] = mRadius * (cRadius * si) + mCenterZ;
n ++;
}
}
return vertices;
}
public FloatBuffer createVerticesBuff() {
// create array
verArray = createVerticesArray();
// create buffer
if (vBuff == null) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verArray.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vBuff = byteBuffer.asFloatBuffer();
vBuff.put(verArray);
vBuff.flip();
}
return vBuff;
}
public short[] createIndexingArray() {
short[] indexies = new short[verArray.length*2];
int n=0;
for (int i = 0; i < stepsPai-1; i++) {
for (int j = 0; j < stepsTheta; j++) {
indexies[n] = (short) (i*stepsTheta+j);
indexies[n+1] = (short) ((i+1)*stepsTheta+j);
indexies[n+2] = (short) ((i+1)*stepsTheta+j+1);
indexies[n+3] = indexies[n+2];
indexies[n+4] = (short) (i*stepsTheta+j+1);
indexies[n+5] = indexies[n];
n+=6;
}
}
return indexies;
}
public void createIndexingBuffer(){
// create array
verIndex = createIndexingArray();
//create buffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verIndex.length * 2);
byteBuffer.order(ByteOrder.nativeOrder());
iBuff = byteBuffer.asShortBuffer();
iBuff.put(verIndex);
iBuff.flip();
}
public void draw() {
// setup vertices buffer
mGL.glEnableClientState(GL10.GL_VERTEX_ARRAY);
vBuff.position(0);
mGL.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuff);
// setup texture
if (texture != null) {
mGL.glEnable(GL10.GL_TEXTURE_2D);
mGL.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
tBuff.position(0);
mGL.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tBuff);
}
// display poligons on screen
mGL.glDrawElements(GL10.GL_TRIANGLES, verIndex.length, GL10.GL_UNSIGNED_SHORT, iBuff);
// reset settings
if (texture != null) {
mGL.glDisable(GL10.GL_TEXTURE_2D);
mGL.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
} else {
mGL.glColor4f(1, 1, 1, 1);
}
mGL.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
public void setTexture(Texture texture) {
if (this.texture != null) {
this.texture.dispose();
}
this.texture = texture;
// create array
texIndex = new float[stepsPai * stepsTheta * 2 * 2];
int n = 0;
for (float pai = 0f; pai < 180f; pai += step) {
for (float theta = 0.0f; theta <= 360f; theta += step) {
texIndex[n] = theta / 360f;
texIndex[n + 1] = pai / 180f;
n += 2;
}
}
// create buffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(texIndex.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
tBuff = byteBuffer.asFloatBuffer();
tBuff.put(texIndex);
tBuff.flip();
// bind texture
texture.bind();
}
}
"World" class
package com.example.OpenGL_Testing.openGl;
import android.opengl.GLSurfaceView;
import android.support.v4.view.GestureDetectorCompat;
import android.view.MotionEvent;
import android.view.View;
import com.example.OpenGL_Testing.MyApp;
import com.example.OpenGL_Testing.MyGestureListener;
import com.example.OpenGL_Testing.Screen;
import com.example.OpenGL_Testing.openGl.geometry.Sphere;
import com.example.OpenGL_Testing.openGl.geometry.Sphere2;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by Aleksandr.Tsatski on 11.11.2014.
*/
public class WorldMap implements Screen {
GLSurfaceView glView;
static final int VERTEX_SIZE = (3) * 4;
Sphere sphere;
GL10 gl;
private GestureDetectorCompat mDetector;
final Object stateChanged = new Object();
public WorldMap(final GLSurfaceView glView, final GL10 gl) {
this.glView = glView;
this.gl = gl;
sphere = new Sphere(400, 0, 0, 0, gl);
}
private void setupGestureListener(final GLSurfaceView glView, final GL10 gl) {
final MyGestureListener listener = new MyGestureListener();
listener.setGestureFeedBackListener(new MyGestureListener.Feedback() {
#Override
public void onFeedback(final int event, final float parameter1, final float parameter2) {
glView.queueEvent(new Runnable() {
#Override
public void run() {
switch (event) {
case MyGestureListener.SCROLL:
gl.glRotatef(parameter1/10, 0f, 1f, 0f);
gl.glRotatef(-parameter2/10, 0f, 0f, 1f);
break;
default:
break;
}
}
});
}
});
glView.post(new Runnable() {
#Override
public void run() {
mDetector = new GestureDetectorCompat(MyApp.getAppContext(), listener);
}
});
glView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mDetector.onTouchEvent(motionEvent);
}
});
}
#Override
public void present(float deltaTime) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
sphere.draw();
}
#Override
public void resume() {
gl.glClearColor(1, 0, 0, 1);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
setupGestureListener(glView, gl);
sphere.setTexture(new Texture(gl, "world_map.png"));
}
#Override
public void pause() {
}
#Override
public void dispose() {
}
}

LWJGL glTranslatef not rendering depth

I am render a square with in 3D space. When I use the glTranslatef() method and add a z coordinate the square is no longer visible. When the z coordinate is above 1 or below -1 then square is no longer displayed (I tested it by setting the z coordinate to 1. If and it didn't display).
Main.java
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
initDisplay();
gameLoop();
cleanUp();
}
public static void initDisplay(){
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.setTitle("AWESOMENESS!");
Display.create();
} catch (LWJGLException e) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
}
}
public static void gameLoop(){
Camera cam = new Camera(70, (float)Display.getWidth() / (float)Display.getHeight(), 0.3f, 1000);
while(!Display.isCloseRequested()){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
cam.useView();
glPushMatrix();{
glColor3f(1.0f, 0.5f, 0f);
//This is the problematic line. When the 3rd param goes above 1 or below -1 the
//square disappers.
glTranslatef(0,0,-10);
glBegin(GL_QUADS);{
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glVertex3f(1,1,0);
glVertex3f(1,0,0);
}
glEnd();
}
glPopMatrix();
Display.update();
}
}
public static void cleanUp(){
Display.destroy();
}
}
Camera.java
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;
public class Camera {
//Position
private float x;
private float y;
private float z;
//Rotation
private float rx;
private float ry;
private float rz;
private float fov;
private float aspect;
private float near;
private float far;
public Camera(float fov, float aspect, float near, float far) {
x = 0;
y = 0;
z = 0;
rx = 0;
ry = 0;
rz = 0;
this.fov = fov;
this.aspect = aspect;
this.near = near;
this.far = far;
initProjection();
}
private void initProjection(){
glMatrixMode(GL_PROJECTION_MATRIX);
glLoadIdentity();
gluPerspective(fov, aspect, near, far);
glMatrixMode(GL_MODELVIEW);
}
public void useView(){
glRotatef(rx, 1, 0, 0);
glRotatef(ry, 0, 1, 0);
glRotatef(rz, 0, 0, 1);
glTranslatef(x, y, z);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
public float getRx() {
return rx;
}
public float getRy() {
return ry;
}
public float getRz() {
return rz;
}
public float getFov() {
return fov;
}
public float getAspect() {
return aspect;
}
public float getNear() {
return near;
}
public float getFar() {
return far;
}
public void setX(float x) {
this.x = x;
}
public void setY(float y) {
this.y = y;
}
public void setZ(float z) {
this.z = z;
}
public void setRx(float rx) {
this.rx = rx;
}
public void setRy(float ry) {
this.ry = ry;
}
public void setRz(float rz) {
this.rz = rz;
}
public void setFov(float fov) {
this.fov = fov;
}
public void setAspect(float aspect) {
this.aspect = aspect;
}
public void setNear(float near) {
this.near = near;
}
public void setFar(float far) {
this.far = far;
}
}
glMatrixMode(GL_PROJECTION_MATRIX);
Instead should be:
glMatrixMode(GL_PROJECTION);
GL_PROJECTION_MATRIX does not render the 3rd dimension. There is no further documentation on this matter.

Categories

Resources