Java LWJGL rendering .obj correctly - java

Below of my main class I am trying to render a obj from a blender .obj file after reformatting it to (supposedly) work for my rendering it gives the error. How can I fix this?
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at flow_control.MainLoop.render(MainLoop.java:85)
at flow_control.MainLoop.main(MainLoop.java:45)
Main class:
package flow_control;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
import static org.lwjgl.opengl.GL11.*;
public class MainLoop {
MainLoop(){
camera = new Camera(this);
loadTextures();
}
private static final int WIDTH = 1280
private static final int HEIGHT = 700;
boolean[] keys = new boolean[256];
Camera camera;
Texture TexFloor;
Texture TexWhite;
Model m = null;
public static void main(String[] args) {
System.out.println("S");
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
MainLoop game = new MainLoop();
game.load();
game.loadTextures();
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
game.update();
game.render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void loadTextures(){
try{
TexFloor = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/floor.jpg"));
}catch(FileNotFoundException e) {
System.err.println("Could not find textures");
e.printStackTrace();
}catch(IOException e){
System.err.println("IO problem");
e.printStackTrace();
}
}
public void render() {
clearScreen();
camera.translatePostion();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0, 0, 0);
glTexCoord2f(128/8, 0);
glVertex3f(500, 0, 0);
glTexCoord2f(128/8, 128/8);
glVertex3f(500, 0, 500);
glTexCoord2f(0, 128/8);
glVertex3f(0, 0, 500);
glEnd();
glBegin(GL_TRIANGLES);
for (Faces face : m.faces) {
//error occurs on the line below
Vector3f n1 = m.normals.get((int) face.normals.x - 1);
glNormal3f(n1.x, n1.y, n1.z);
Vector3f v1 = m.vertices.get((int) face.Vertex.x - 1);
glNormal3f(v1.x, v1.y, v1.z);
Vector3f n2 = m.normals.get((int) face.normals.y - 1);
glNormal3f(n2.x, n2.y, n2.z);
Vector3f v2 = m.vertices.get((int) face.Vertex.y - 1);
glNormal3f(v2.x, v2.y, v2.z);
Vector3f n3 = m.normals.get((int) face.normals.z - 1);
glNormal3f(n3.x, n3.y, n3.z);
Vector3f v3 = m.vertices.get((int) face.Vertex.z - 1);
glNormal3f(v3.x, v3.y, v3.z);
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
TexFloor.bind();
}
public void load() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective((float) 100, WIDTH/HEIGHT, 0.001f, 1000);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
try{
m = OBJLoader.loadModel(new File("res/tree.obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void clearScreen() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
public void update() {
mapKeys();
camera.update();
}
private void mapKeys(){
for(int i=0;i<keys.length; i++) {
keys[i] = Keyboard.isKeyDown(i);
}
}
}
Class OBJLoader:
package flow_control;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.lwjgl.util.vector.Vector3f;
public class OBJLoader {
public static Model loadModel(File f) throws FileNotFoundException, IOException {
BufferedReader reader = new BufferedReader(new FileReader(f));
Model m = new Model();
String line;
while((line = reader.readLine()) != null){
//parse object
if (line.startsWith("v ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.vertices.add(new Vector3f(x,y,z));
} else if (line.startsWith("vn ")) {
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.normals.add(new Vector3f(x,y,z));
} else if (line.startsWith("f ")) {
Vector3f vertexIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]),Float.valueOf(line.split(" ")[2].split("/")[0]),Float.valueOf(line.split(" ")[3].split("/")[0]));
Vector3f normalIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[2]),Float.valueOf(line.split(" ")[2].split("/")[2]),Float.valueOf(line.split(" ")[3].split("/")[2]));
m.faces.add(new Faces(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
Class Model:
package flow_control;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
public class Model {
public List<Vector3f> vertices = new ArrayList<Vector3f>();
public List<Vector3f> normals = new ArrayList<Vector3f>();
public List<Faces> faces = new ArrayList<Faces>();
public Model(){
}
}
Class Faces:
package flow_control;
import org.lwjgl.util.vector.Vector3f;
public class Faces {
public Vector3f Vertex = new Vector3f();
public Vector3f normals = new Vector3f();
public Faces(Vector3f vertex, Vector3f normal) {
this.Vertex = vertex;
this.normals = normals;
}
}
Sorry if some of this is excessive I know the errors coming from line 85 but I can't seem to figure out how to fix it.
OBJ file example (slimmed down):
# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib tree.mtl
o Mesh_default
v -0.163260 2.023340 -0.247879
v 0.163260 2.023340 -0.247878
v 0.163260 2.023340 0.247879
f 35//34 39//40 36//35
f 36//35 40//39 37//36
f 38//37 34//41 41//38
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600

You made a couple of typo's in your program.
First off, in your OBJLoader class
else if (line.startsWith("vm "))
Its looking for lines in the OBJ file that start with "vm " but your obj files uses "vn ". Simply change this and the array won't be empty anymore.
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600
Secondly, in the Faces class
public Faces(Vector3f vertex, Vector3f normal)
{
this.Vertex = vertex;
this.normals = normals;
}
You are setting the "normals" variable equal to itself rather then the Vector3f in the constructor, change it to this.
this.normals = normal;

Related

What is the right way to create 2D isometric view?

I want to create isometric 2D game. I use modern LWJGL (vertex arrays, shaders etc.) I found true isometric projection with opengl and: I tried to rotate my projection matrix, but it created black triangles on corners of screen. I tried to rotate model matrix, but I found that I can't rotate x and y on ortho matrix (because it's 2D), it does
but I need to rotate x and y axis to get isometric matrix. Then I found this https://www.gamedev.net/blog/33/entry-2250273-isometric-map-in-sfml/ and it says that I only need place tiles on right spots. Who is right? And why in first link they rotate model matrix in old OpenGL even though it's 2D projection matrix and I can't rotate it on modern OpenGL? (Sorry for my bad English)
Edit: How I create model matrix (I use joml for them):
public Matrix4f getModel(GameItem item){
Vector3f rot = item.getRotation();
return new Matrix4f().translate(item.getPosition()).rotateX((float)Math.toRadians(-rot.x)).rotateY((float)Math.toRadians(-rot.y)).rotateZ((float)Math.toRadians(-rot.z)).scale(item.getScale());
}
How I create projection matrix:
public void updateProjectionMatrix(Window window){
projectionMatrix2D.identity().ortho2D(-window.getWidth(), window.getWidth(), -window.getHeight(), window.getHeight());
}
If I rotate matrix before ortho2D() everything is rotated correctly, however there are black triangles on two of screen's corners. If I rotate it after ortho2D() it does exactly like rotating model matrix (shrinks object). In render() I pass matrixes to vertex shader:
#version 330
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
out vec2 outTexCoord;
uniform mat4 projectionMatrix;
uniform mat4 model;
void main()
{
gl_Position = projectionMatrix* model * vec4(position, 1.0);
outTexCoord = texCoord;
}
Edit 2:
Creating view matrix works:
However it does exactly like rotating projection matrix before ortho2D() - it creates black (because that's my clear color) triangles on two of screen's corners:
and there:
How do I get rid of them?
Edit 3:
I rewrote my code, but nothing has changed.
To run my code, you should add to project LWJGL library, LWJGL-GLFW, LWJGL-STB, LWJGL-OpenGl and JOML library (it's not downloaded with LWJGL). You will also need a random .png image.
Main class:
import Core.Engine;
public class Main {
public static void main(String[] args){
try{
//Is vsync enabled?
boolean vsync = true;
Engine engine = new Engine("GAME", vsync);
//Start program
engine.start();
}
catch(Exception ex){
ex.printStackTrace();
System.exit(-1);
}
}
}
Engine class:
package Core;
public class Engine implements Runnable{
public static final int TARGET_FPS = 60;
public static final int TARGET_UPS = 30;
private final Window window;
//Program thread
private final Thread gameLoopThread;
//Timer for gameLoop
private final Timer timer;
//Creates everything that is on screen
private final Logic logic;
public Engine(String windowTitle, boolean vSync) throws Exception {
gameLoopThread = new Thread(this, "GAME_LOOP_THREAD");
window = new Window(windowTitle, vSync);
logic = new Logic();
timer = new Timer();
}
public void start() {
String osName = System.getProperty("os.name");
if ( osName.contains("Mac") ) {
gameLoopThread.run();
} else {
gameLoopThread.start();
}
}
#Override
public void run() {
try {
init();
gameLoop();
} catch (Exception excp) {
excp.printStackTrace();
}
}
protected void init() throws Exception {
window.init();
timer.init();
logic.init(this.window);
}
protected void gameLoop() {
float elapsedTime;
float accumulator = 0f;
float interval = 1f / TARGET_UPS;
boolean running = true;
while (running && !window.shouldClose()) {
elapsedTime = timer.getElapsedTime();
accumulator += elapsedTime;
input();
while (accumulator >= interval) {
update(interval);
accumulator -= interval;
}
render();
if (!window.isVsync()) {
sync();
}
}
}
private void sync() {
float loopSlot = 1f / TARGET_FPS;
double endTime = timer.getLastLoopTime() + loopSlot;
while (Timer.getTime() < endTime) {
try {
Thread.sleep(1);
} catch (InterruptedException ie) {
}
}
}
protected void input() {
logic.input(window);
}
protected void update(float interval) {
logic.update(interval,window);
}
protected void render() {
logic.render(window);
window.update();
}
}
Timer class:
package Core;
public class Timer {
private double lastLoopTime;
public void init(){
lastLoopTime = getTime();
}
public static double getTime(){
return (double)((double)System.nanoTime() / (double)1000_000_000L);
}
public float getElapsedTime(){
double time = getTime();
float elapsedTime =(float) (time-lastLoopTime);
lastLoopTime = time;
return elapsedTime;
}
public double getLastLoopTime(){
return lastLoopTime;
}
}
Window class:
package Core;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
public class Window {
private long window;
private int width, height;
private boolean vsync;
private String title;
public Window(String title,boolean vsync){
this.title = title;
this.vsync = vsync;
}
public long getInstance(){
return window;
}
public void init(){
GLFWErrorCallback.createPrint(System.err).set();
if(!glfwInit()){
// Throw an error.
throw new IllegalStateException("GLFW initialization failed!");
}
glfwWindowHint(GLFW_VISIBLE, GL_TRUE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // the window will not be resizable
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
width = vidmode.width();
height = vidmode.height() -30;
System.out.println(width + " "+ height);
window = GLFW.glfwCreateWindow(width,height, title,NULL, NULL);
if(window == NULL){
throw new RuntimeException("ERROR with Window");
}
GLFW.glfwSetWindowPos(window, 0, 29);
glfwMakeContextCurrent(window);
if(vsync)
GLFW.glfwSwapInterval(1);
glfwShowWindow(window);
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
public boolean isKeyPressed(int keyCode) {
return GLFW.glfwGetKey(window, keyCode) == GLFW.GLFW_PRESS;
}
public void setClearColor(float r, float g, float b, float alpha) {
glClearColor(r, g, b, alpha);
}
public boolean shouldClose(){
return glfwWindowShouldClose(window);
}
public void update(){
glfwSwapBuffers(window);
glfwPollEvents();
}
public void setVsync(boolean aflag){
this.vsync = aflag;
}
public boolean isVsync(){
return vsync;
}
public int getWidth(){
return width;
}
public int getHeight(){
return height;
}
}
Logic class:
package Core;
import org.joml.Vector3f;
import org.lwjgl.glfw.GLFW;
public class Logic {
private Renderer render;
private GameItem item;
public void init(Window window) throws Exception {
//create object
float[] positions = new float[]{
-600, 600, 0f,//0
-600, -600, 0f,//1
600, -600, 0,//2
600, 600, 0f//3
};
float[] texCoords = new float[]{
0,0,//0
0,1,//1
1,1,//2
1,0 //3
};
int[] indices = new int[]{
0, 1, 3, 3, 1, 2,
};
render = new Renderer();
render.init(window);
Texture texture = new Texture("Textures/image.png");
Mesh mesh = new Mesh(positions,texCoords,indices,texture);
item = new GameItem(mesh);
item.setPosition(-100, 0, 0);
}
public void input(Window window) {
//move
Vector3f s = item.getPosition();
if(window.isKeyPressed(GLFW.GLFW_KEY_W)){
item.setPosition(s.x, s.y+5, s.z);
}
else if(window.isKeyPressed(GLFW.GLFW_KEY_S)){
item.setPosition(s.x, s.y-5, s.z);
}
else if(window.isKeyPressed(GLFW.GLFW_KEY_A)){
item.setPosition(s.x-5, s.y, s.z);
}
else if(window.isKeyPressed(GLFW.GLFW_KEY_D)){
item.setPosition(s.x+5, s.y, s.z);
}
}
public void update(float interval, Window window) {
}
public void render(Window window) {
render.render(window,item);
}
public void cleanup() {
render.cleanup();
}
}
Renderer class:
package Core;
import static org.lwjgl.opengl.GL11.*;
import org.joml.Matrix4f;
import org.joml.Vector3f;
public class Renderer {
private Matrix4f projectionMatrix2D;
private Matrix4f view;
private ShaderProgram shaderProgram;
public Renderer() {
projectionMatrix2D= new Matrix4f();
}
public void init(Window window) throws Exception {
shaderProgram = new ShaderProgram();
shaderProgram.createVertexShader(Utils.load("Shaders/vertex.vs"));
shaderProgram.createFragmentShader(Utils.load("Shaders/fragment.fs"));
shaderProgram.link();
shaderProgram.createUniform("projectionMatrix");
shaderProgram.createUniform("model");
shaderProgram.createUniform("texture_sampler");
shaderProgram.createUniform("view");
view = new Matrix4f().lookAt(new Vector3f(1,1,1), new Vector3f(0), new Vector3f(0,1,0));
updateProjectionMatrix(window);
}
public void clear() {
glClear(GL_COLOR_BUFFER_BIT);
}
public void render(Window window,GameItem item) {
clear();
updateProjectionMatrix(window);
shaderProgram.bind();
shaderProgram.setUniform("projectionMatrix", projectionMatrix2D);
shaderProgram.setUniform("view", view);
shaderProgram.setUniform("texture_sampler", 0);
Vector3f rot = item.getRotation();
Matrix4f model = new Matrix4f().translate(item.getPosition()).rotateX((float)Math.toRadians(-rot.x))
.rotateY((float)Math.toRadians(-rot.y))
.rotateZ((float)Math.toRadians(-rot.z))
.scale(item.getScale());
shaderProgram.setUniform("model", model);
item.getMesh().render();
shaderProgram.unbind();
}
public void updateProjectionMatrix(Window window){
projectionMatrix2D.identity().ortho2D(-window.getWidth(), window.getWidth(), -window.getHeight(), window.getHeight());
//it creates weird triangle on right screen corner
// projectionMatrix2D.identity().ortho2D(-1, 1, -1, 1);
}
public void cleanup() {
if (shaderProgram != null) {
shaderProgram.cleanup();
}
}
}
ShaderProgram class:
package Core;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryStack;
public class ShaderProgram {
private final int programId;
private int vertexShaderId;
private int fragmentShaderId;
private final Map<String, Integer> uniforms;
public ShaderProgram() throws Exception {
programId = glCreateProgram();
if (programId == 0) {
throw new Exception("Could not create Shader");
}
uniforms = new HashMap<>();
}
public void createUniform(String uniformName) throws Exception {
int uniformLocation = glGetUniformLocation(programId, uniformName);
if (uniformLocation < 0) {
throw new Exception("Could not find uniform:" + uniformName);
}
uniforms.put(uniformName, uniformLocation);
}
public void setUniform(String uniformName, Matrix4f value) {
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer fb = stack.mallocFloat(16);
value.get(fb);
glUniformMatrix4fv(uniforms.get(uniformName), false, fb);
}
}
public void setUniform(String uniformName, int value) {
glUniform1i(uniforms.get(uniformName), value);
}
public void setUniform(String uniformName, float value) {
glUniform1f(uniforms.get(uniformName), value);
}
public void setUniform(String uniformName, Vector3f value) {
glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
}
public void setUniform(String uniformName, org.joml.Vector4f value) {
glUniform4f(uniforms.get(uniformName), value.x, value.y, value.z, value.w);
}
public void setUniform(String uniformName, Vector2f vector2f) {
glUniform2f(uniforms.get(uniformName),vector2f.x,vector2f.y);
}
public void createVertexShader(String shaderCode) throws Exception {
vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER);
}
public void createFragmentShader(String shaderCode) throws Exception {
fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER);
}
protected int createShader(String shaderCode, int shaderType) throws Exception {
int shaderId = glCreateShader(shaderType);
if (shaderId == 0) {
throw new Exception("Error creating shader. Type: " + shaderType);
}
glShaderSource(shaderId, shaderCode);
glCompileShader(shaderId);
if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
}
glAttachShader(programId, shaderId);
return shaderId;
}
public void link() throws Exception {
glLinkProgram(programId);
if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
throw new Exception("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
}
if (vertexShaderId != 0) {
glDetachShader(programId, vertexShaderId);
}
if (fragmentShaderId != 0) {
glDetachShader(programId, fragmentShaderId);
}
glValidateProgram(programId);
if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
}
}
public void bind() {
glUseProgram(programId);
}
public void unbind() {
glUseProgram(0);
}
public void cleanup() {
unbind();
if (programId != 0) {
glDeleteProgram(programId);
}
}
}
GameItem class:
package Core;
import org.joml.Vector3f;
public class GameItem {
//Mesh for this gameItem
private Mesh mesh;
private final Vector3f position;
private float scale = 1;
private final Vector3f rotation;
public GameItem() {
position = new Vector3f(0, 0, 0);
scale = 1;
rotation = new Vector3f(0, 0, 0);
}
public GameItem(Mesh mesh) {
this();
this.mesh = mesh;
}
public GameItem(GameItem item){
this();
position.set(item.position);
scale =1;
rotation.set(item.rotation);
this.mesh = item.mesh;
}
public Vector3f getPosition() {
return position;
}
public void setPosition(float x, float y, float z) {
this.position.x = x;
this.position.y = y;
this.position.z = z;
}
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public Vector3f getRotation() {
return rotation;
}
public void setRotation(float x, float y, float z) {
this.rotation.x = x;
this.rotation.y = y;
this.rotation.z = z;
}
public Mesh getMesh() {
return mesh;
}
public void setMesh(Mesh mesh){
this.mesh = mesh;
}
}
Utils class:
package Core;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Utils {
//Load strings
public static String load(String path){
StringBuilder builder = new StringBuilder();
try (InputStream in = new FileInputStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line;
while ((line = reader.readLine()) != null) {
builder.append(line).append("\n");
}
} catch (IOException ex) {
throw new RuntimeException("Failed to load a shader file!"
+ System.lineSeparator() + ex.getMessage());
}
String source = builder.toString();
return source;
}
}
Mesh class:
package Core;
import java.util.List;
import org.lwjgl.system.MemoryUtil;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
public class Mesh{
private final int vaoId;
private final List<Integer> vboIdList;
private final int vertexCount;
private Texture texture;
public Mesh(float[] positions, float[] textCoords, int[] indices,Texture texture) {
this.texture = texture;
FloatBuffer posBuffer = null;
FloatBuffer textCoordsBuffer = null;
IntBuffer indicesBuffer = null;
try {
vertexCount = indices.length;
vboIdList = new ArrayList<>();
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
// Position
int vboId = glGenBuffers();
vboIdList.add(vboId);
posBuffer = MemoryUtil.memAllocFloat(positions.length);
posBuffer.put(positions).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
// Texture coordinates
vboId = glGenBuffers();
vboIdList.add(vboId);
textCoordsBuffer = MemoryUtil.memAllocFloat(textCoords.length);
textCoordsBuffer.put(textCoords).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, textCoordsBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
// Index
vboId = glGenBuffers();
vboIdList.add(vboId);
indicesBuffer = MemoryUtil.memAllocInt(indices.length);
indicesBuffer.put(indices).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
} finally {
if (posBuffer != null) {
MemoryUtil.memFree(posBuffer);
}
if (textCoordsBuffer != null) {
MemoryUtil.memFree(textCoordsBuffer);
}
if (indicesBuffer != null) {
MemoryUtil.memFree(indicesBuffer);
}
}
}
public Texture getTexture() {
return texture;
}
public void setTexture(Texture texture) {
this.texture = texture;
}
public int getVaoId() {
return vaoId;
}
public int getVertexCount() {
return vertexCount;
}
public void cleanUp() {
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
for (int vboId : vboIdList) {
glDeleteBuffers(vboId);
}
texture.cleanup();
glBindVertexArray(0);
glDeleteVertexArrays(vaoId);
}
public void render(){
glBindVertexArray(getVaoId());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0);
}
}
Texture class:
package Core;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.system.MemoryStack;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
import static org.lwjgl.stb.STBImage.*;
public class Texture {
private final int id;
public Texture(String fileName) throws Exception {
this(loadTexture(fileName));
}
public Texture(int id) {
this.id = id;
}
public void bind() {
glBindTexture(GL_TEXTURE_2D, id);
}
public int getId() {
return id;
}
private static int loadTexture(String fileName) throws Exception {
int width;
int height;
ByteBuffer buf;
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
buf = stbi_load(fileName, w, h, channels, 4);
if (buf == null) {
throw new Exception("Image file " + fileName + " not loaded: " + stbi_failure_reason());
}
width = w.get();
height = h.get();
}
int textureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, buf);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(buf);
return textureId;
}
public void cleanup() {
glDeleteTextures(id);
}
}
Vertex shader:
#version 330
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
out vec2 outTexCoord;
uniform mat4 projectionMatrix;
uniform mat4 model;
uniform mat4 view;
void main()
{
gl_Position = projectionMatrix * view * model * vec4(position, 1.0); // if view is after vec4 it creates actually object, but it creates black triangles as well. Without view matrix it is just a normal square
outTexCoord = texCoord;
}
Fragment shader:
#version 330
in vec2 outTexCoord;
out vec4 fragColor;
uniform sampler2D texture_sampler;
void main()
{
fragColor = texture(texture_sampler,outTexCoord);
}

Shaders don't work properly in OpenGL in Java

The problem is that i am trying to create a 3D Cube via using the shaders, but the problem is that, it doesn't read the file correctly.
Here are the shaders that I have created, the problem is that it reads not correctly the sharders and give the error
I also get just a black screen as a result
My Shaders
Vertex shader
// vertex.glsl
#version 430
layout (location = 0) in vec3 position;
uniform mat4 proj_matrix;
uniform mat4 mv_matrix;
void main(void) {
gl_Position = proj_matrix * mv_matrix * vec4(position, 1.0);
}
Fragemtn shader
// fragment.glsl
#version 430
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void) {
color = vec4(1.0, 0.0, 0.0, 1.0);
}
main code
// my main code
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.math.Matrix4;
import com.jogamp.opengl.math.Quaternion;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.*;
public class GOVNO extends JFrame implements GLEventListener {
private GLCanvas myCanvas;
private int rendering_program;
private int vbo[] = new int[2];
private int mTrans;
public GOVNO() {
setTitle("Chapter2 - program1");
setSize(600, 400);
setLocation(200, 200);
GLProfile profile = GLProfile.getDefault();
GLCapabilities capabilities = new GLCapabilities(profile);
myCanvas = new GLCanvas(capabilities);
myCanvas.addGLEventListener(this);
this.add(myCanvas);
setVisible(true);
}
public void display(GLAutoDrawable drawable) {
GL2 gl = (GL2) GLContext.getCurrentGL();
gl.glUseProgram(rendering_program);
float a = 0;
//Matrix4 mTransMatrix = new Matrix4();
float mTransMatrix[] = {
(float) Math.cos(a), (float) -Math.sin(a), 0, 0,
(float) Math.sin(a), (float) Math.cos(a), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
gl.glUniformMatrix4fv(mTrans, 1, false, mTransMatrix, 0);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[0]);
gl.glVertexAttribPointer(0, 2, GL3.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(0);
gl.glDrawArrays(GL3.GL_TRIANGLES, 0, 6);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[1]);
gl.glVertexAttribPointer(0, 2, GL3.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(0);
gl.glDrawArrays(GL3.GL_QUADS, 0, 8);
}
public void init(GLAutoDrawable drawable) {
GL2 gl = (GL2) GLContext.getCurrentGL();
rendering_program = createShaderProgram();
// generating location for transformation matrix
mTrans = gl.glGetUniformLocation(rendering_program, "trans");
float[] vertex_positions = { -0.5f, -1.0f, 0.0f, -0.5f, 0.5f, -1.0f, };
gl.glGenBuffers(vbo.length, vbo, 0);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[0]);
FloatBuffer vertBuf Buffers.newDirectFloatBuffer(vertex_positions);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL3.GL_STATIC_DRAW);
float[] vertex_positions2 = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f };
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[1]);
FloatBuffer vertBuf2 = Buffers.newDirectFloatBuffer(vertex_positions2);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, vertBuf2.limit() * 4, vertBuf2, GL3.GL_STATIC_DRAW);
}
private int createShaderProgram() {
GL2 gl = (GL2) GLContext.getCurrentGL();
String vshaderSource[] = readShaderSource("src/vertex.glsl");
String fshaderSource[] = readShaderSource("src/fragment.glsl");
int vShader = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
gl.glShaderSource(vShader, vshaderSource.length, vshaderSource, null, 0);
gl.glCompileShader(vShader);
printShaderLog(vShader);
int fShader = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);
gl.glShaderSource(fShader, fshaderSource.length, fshaderSource, null, 0);
gl.glCompileShader(fShader);
printShaderLog(fShader);
int vfprogram = gl.glCreateProgram();
gl.glAttachShader(vfprogram, vShader);
gl.glAttachShader(vfprogram, fShader);
gl.glLinkProgram(vfprogram);
gl.glDeleteShader(vShader);
gl.glDeleteShader(fShader);
printProgramLog(vfprogram);
return vfprogram;
}
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";
System.out.print(program[i]);
}
return program;
}
private void printShaderLog(int shader) {
GL2 gl = (GL2) GLContext.getCurrentGL();
int[] len = new int[1];
int[] chWrittn = new int[1];
byte[] log = null;
// determine the length of the shader compilation log
gl.glGetShaderiv(shader, GL3.GL_INFO_LOG_LENGTH, len, 0);
if (len[0] > 0) {
log = new byte[len[0]];
gl.glGetShaderInfoLog(shader, len[0], chWrittn, 0, log, 0);
System.out.println("Shader Info Log: ");
for (int i = 0; i < log.length; i++) {
System.out.print((char) log[i]);
}
}
}
void printProgramLog(int prog) {
GL2 gl = (GL2) GLContext.getCurrentGL();
int[] len = new int[1];
int[] chWrittn = new int[1];
byte[] log = null;
// determine the length of the program linking log
gl.glGetProgramiv(prog, GL3.GL_INFO_LOG_LENGTH, len, 0);
if (len[0] > 0) {
log = new byte[len[0]];
gl.glGetProgramInfoLog(prog, len[0], chWrittn, 0, log, 0);
System.out.println("Program Info Log: ");
for (int i = 0; i < log.length; i++) {
System.out.print((char) log[i]);
}
}
}
public static void main(String[] args) {
System.out.println("Working Directory = " + System.getProperty("user.dir"));
new GOVNO();
}
}

LWJGL Tilerenderer only renders one type of tile/one texture

I'm learning LWJGL and OpenGL by following this tutorial i found, i tried my best to change the code to be compatible with the never versions and hadnt a problem with it so far. But now my Tilerenderer wont render more than one type of tile/one texture for the VBO's and i tried to fix it now since 3 days (in the beginning it didn't render anything at all) but couldn't find anything that fixes this problem.
I'm using Java 9.0.4 and LWJGL 3.2.1 build 12 with JOML 1.9.13, GLFW, OpenGL and stb.
So far i tried changing the entire code involved in this problem and changing different variables for shaders but nothing seemed to work so far.
Here are all classes i figured might have something to do with the problem.
The Main class
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL;
public class Main {
public static void main(String[] args) {
int speed = 5;
Window.setCallbacks();
if (!glfwInit()) {
throw new IllegalStateException("Failed to init GLFW");
}
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
Window window = new Window();
window.setSize(640, 480);
window.setFullscreen(false);
window.createWindow("GAME");
GL.createCapabilities();
Camera camera = new Camera(window.getWidth(), window.getHeight());
glEnable(GL_TEXTURE_2D);
TileRenderer tiles = new TileRenderer();
Shader shader = new Shader("shader");
World world = new World();
world.setTile(Tile.test_tile, 0, 0);
double frameCap = 1.0 / 60.0;
double frameTime = 0;
double time = Timer.getTime();
double unprocessed = 0;
int frames = 0;
while(!window.shouldClose()) {
boolean canRender = false;
double time2 = Timer.getTime();
double passed = time2 - time;
unprocessed+=passed;
frameTime += passed;
time = time2;
while (unprocessed >= frameCap) {
canRender = true;
unprocessed-=frameCap;
if(window.getInput().isMouseButtonDown(0)) {
glfwSetWindowShouldClose(window.getWindow(), true);
}
if (window.getInput().isKeyPressed(GLFW_KEY_ESCAPE)) {
glfwSetWindowShouldClose(window.getWindow(), true);
}
if(window.getInput().isKeyDown(GLFW_KEY_W)) {
camera.addPosition(new Vector3f(0, -speed, 0));
}
if(window.getInput().isKeyDown(GLFW_KEY_A)) {
camera.addPosition(new Vector3f(speed, 0, 0));
}
if(window.getInput().isKeyDown(GLFW_KEY_S)) {
camera.addPosition(new Vector3f(0, speed, 0));
}
if(window.getInput().isKeyDown(GLFW_KEY_D)) {
camera.addPosition(new Vector3f(-speed, 0, 0));
}
if(window.getInput().isKeyDown(GLFW_KEY_O)) {
speed = 5;
}
if(window.getInput().isKeyDown(GLFW_KEY_P)) {
speed = 25;
}
window.update();
if (frameTime >= 1.0) {
frameTime = 0;
System.out.println("FPS:" + frames);
frames = 0;
}
}
if (canRender) {
glClear(GL_COLOR_BUFFER_BIT);
world.render(tiles, shader, camera);
window.swapBuffers();
frames++;
}
}
glfwTerminate();
}
}
The World class
import org.joml.Matrix4f;
import org.joml.Vector3f;
public class World {
private byte[] tiles;
private int width;
private int height;
private Matrix4f world;
public World () {
width = 16;
height = 16;
tiles = new byte [width * height];
world = new Matrix4f().setTranslation(new Vector3f(0));
world.scale(32);
}
public void render(TileRenderer renderer, Shader shader, Camera camera) {
for (int x = 0; x < height; x++) {
for (int y = 0; y < width; y++) {
renderer.renderTile(tiles[x + y * width], y, -x, shader, world, camera);
}
}
}
public void setTile (Tile tile, int x, int y) {
System.err.println(tile.getId());
tiles[x + y * width] = tile.getId();
}
}
The Tilerenderer class
import java.util.HashMap;
import org.joml.Matrix4f;
import org.joml.Vector3f;
public class TileRenderer {
private HashMap<String, Texture> tileTextures;
private Model tileModel;
public TileRenderer() {
tileTextures = new HashMap<>();
float[] vertices = new float[]{
-1f, 1f, 0, // TOP LEFT 0
1f, 1f, 0, // TOP RIGHT 1
1f, -1f, 0, // BOTTOM RIGHT 2
-1f, -1f, 0,// BOTTOM LEFT 3
};
float[] texture = new float[]{0, 0, 1, 0, 1, 1, 0, 1,};
int[] indices = new int[]{0, 1, 2, 2, 3, 0};
tileModel = new Model(vertices, texture, indices);
for (int i = 0; i < Tile.tiles.length; i++) {
if (Tile.tiles[i] != null) {
if (!tileTextures.containsKey(Tile.tiles[i].getTexture())) {
String tex = Tile.tiles[i].getTexture();
tileTextures.put(tex, new Texture(tex + ".png"));
}
}
}
}
public void renderTile (byte id, int x, int y, Shader shader, Matrix4f world, Camera camera) {
shader.bind();
if (tileTextures.containsKey(Tile.tiles[id].getTexture())) {
tileTextures.get(Tile.tiles[id].getTexture()).bind(0);
}
Matrix4f tilePos = new Matrix4f().translate(new Vector3f(x*2, y*2, 0));
Matrix4f target = new Matrix4f();
camera.getProjection().mul(world, target);
target.mul(tilePos);
shader.setUniform("sampler", 0);
shader.setUniform("projection", target);
tileModel.render();
}
}
The Tile class
public class Tile {
public static Tile tiles[] = new Tile[16];
public static final Tile testTile = new Tile((byte)0, "Test");
public static final Tile testTile2 = new Tile((byte)1, "Test2");
private byte id;
private String texture;
public Tile(byte id, String texture) {
this.id = id;
this.texture = texture;
if (tiles[id] != null) {
throw new IllegalStateException("Tiles at: [" + id + "] is already being used!");
}
tiles[id] = this;
}
public byte getId () {return id;}
public String getTexture () {return texture;}
}
The Model class
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
public class Model {
private int draw_count;
private int v_id;
private int t_id;
private int i_id;
public Model (float[] vertices, float[] tex_coords, int[] indices) {
draw_count = indices.length;
IntBuffer buffer = BufferUtils.createIntBuffer(indices.length);
buffer.put(indices);
buffer.flip();
v_id = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, v_id);
glBufferData(GL_ARRAY_BUFFER, createBuffer(vertices), GL_STATIC_DRAW);
t_id = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, t_id);
glBufferData(GL_ARRAY_BUFFER, createBuffer(tex_coords), GL_STATIC_DRAW);
i_id = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
public void render() {
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, v_id);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, t_id);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_id);
glDrawElements(GL_TRIANGLES, draw_count, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
private FloatBuffer createBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
The Texture class
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.stb.STBImage.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL13.*;
import org.lwjgl.BufferUtils;
public class Texture {
private int id;
private int width;
private int heigth;
public Texture (String filename) {
IntBuffer width = BufferUtils.createIntBuffer(1);
IntBuffer heigth = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer data = stbi_load("./res/" + filename, width, heigth, comp, 4);
this.width = width.get();
this.heigth = heigth.get();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.heigth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
public void bind (int sampler) {
if (sampler >= 0 && sampler <= 31) {
glActiveTexture(GL_TEXTURE0 + sampler);
glBindTexture(GL_TEXTURE_2D, sampler);
}
}
}
The Shader class
import static org.lwjgl.opengl.GL20.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.FloatBuffer;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
public class Shader {
private int program;
private int vs;
private int fs;
public Shader (String filename) {
program = glCreateProgram();
vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, readFile(filename + ".vs"));
glCompileShader(vs);
if (glGetShaderi(vs, GL_COMPILE_STATUS) != 1) {
System.err.println(glGetShaderInfoLog(vs));
System.exit(1);
}
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, readFile(filename + ".fs"));
glCompileShader(fs);
if (glGetShaderi(fs, GL_COMPILE_STATUS) != 1) {
System.err.println(glGetShaderInfoLog(fs));
System.exit(1);
}
glAttachShader(program, vs);
glAttachShader(program, fs);
glBindAttribLocation(program, 0, "vertices");
glBindAttribLocation(program, 1, "textures");
glLinkProgram(program);
if (glGetProgrami(program, GL_LINK_STATUS) != 1) {
System.err.println(glGetProgramInfoLog(program));
System.exit(1);
}
glValidateProgram(program);
if (glGetProgrami(program, GL_VALIDATE_STATUS) != 1) {
System.err.println(glGetProgramInfoLog(program));
System.exit(1);
}
}
public void bind () {
glUseProgram(program);
}
private String readFile (String filename) {
StringBuilder string = new StringBuilder();
BufferedReader br;
try {
br = new BufferedReader(new FileReader(new File("./shaders/" + filename)));
String line;
while((line = br.readLine()) != null) {
string.append(line);
string.append("\n");
}
} catch (IOException e ) {e.printStackTrace();}
return string.toString();
}
public void setUniform (String name, int value) {
int location = glGetUniformLocation(program, name);
if (location != -1) {
glUniform1i(location, value);
}
}
public void setUniform (String name, Matrix4f value) {
int location = glGetUniformLocation(program, name);
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
value.get(buffer);
if (location != -1) {
glUniformMatrix4fv(location, false, buffer);
}
}
}
The Fragment Shader
#version 120
uniform sampler2D sampler;
varying vec2 tex_coords;
void main () {
gl_FragColor = texture2D(sampler, tex_coords);
}
The Vertex Shader
#version 120
attribute vec3 vertices;
attribute vec2 textures;
varying vec2 tex_coords;
uniform mat4 projection;
void main() {
tex_coords = textures;
gl_Position = projection*vec4(vertices, 1);
}
So far I'm creating 16x16 tiles all with the same texture but it is supposed to change the tile at 0, 0 (top left corner) to have a different texture
There is a basic misunderstanding, about how texturing works in OpenGL.
You have to create a separate texture object for each texture by glGenTextures. (See also Java Code Examples for org.lwjgl.opengl.GL11.glTexImage2D()).
int textureObject = glGenTextures();
This texture object has to be bound before loading the texture and before rendering the mesh. The texture is bound to the active texture unit, which is set by glActiveTexture.
int textureUnitIndex = 0; // e.g
glActiveTexture(GL_TEXTURE0 + textureUnitIndex);
glBindTexture(GL_TEXTURE_2D, textureObject);
The texture unit is a binding point for the shader program. The texture sampler in the shader program has to be associated to the same binding point. This can be done by glUniform1i:
GLSL:
uniform sampler2D sampler;
Java:
int location = glGetUniformLocation(program, "sampler");
glUniform1i(location, textureUnitIndex);
Sidenote: since GLSL version 4.2 this can be done in the fragment shader by specifying binding points - See OpenGL Shading Language 4.20 Specification - 4.4.4 Opaque-Uniform Layout Qualifiers; page 60:
#version 420
layout (binding = 0) uniform sampler2D sampler;
In your code never a texture object is generated. So the default texture object 0 is used for all textures. This causes that you code doesn't work.
Change the class Texture, somehow as follows, to solve the issue:
public class Texture {
private int textureObject;
private int width;
private int heigth;
public Texture (String filename) {
IntBuffer width = BufferUtils.createIntBuffer(1);
IntBuffer heigth = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer data = stbi_load("./res/" + filename, width, heigth, comp, 4);
this.width = width.get();
this.heigth = heigth.get();
textureObject = glGenTextures(); // generate texture name
glBindTexture(GL_TEXTURE_2D, textureObject);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.heigth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
public void bind (int sampler) {
if (sampler >= 0 && sampler <= 31) {
glActiveTexture(GL_TEXTURE0 + sampler);
glBindTexture(GL_TEXTURE_2D, textureObject); // bind texture object
}
}
}

Fixing Incompatibility Between LWJGL 3 and Slick-Util

What I am trying to do is map a texture to an OpenGL model within LWJGL. I know that LWJGL 3 and slick-util sometimes work together and sometimes don't. In my case, it works a little and then tries to access a method in OpenGL that doesn't exist anymore for LWJGL 3. My posting this isn't necessarily trying to fix this error, but to find a way to circumvent it. I have tried downgrading to/running LWJGL 2 instead of/with LWJGL 3 and that went terribly, and I've also tried my hand at a couple of different PNG decoders to get what I want, but I can't figure them out. Also, I have went and gotten the "LWJGL 3 Compatible slick-util" but it doesn't have any classes/methods in it that I need. If anyone can fix my code for me or tell me how to fix it myself, that'd be lovely.
Here's the error:
Mon Feb 15 18:38:13 EST 2016 INFO:Use Java PNG Loader = true
Exception in thread "main" java.lang.NoSuchMethodError: org.lwjgl.opengl.GL11.glGetInteger(ILjava/nio/IntBuffer;)V
at org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer.glGetInteger(ImmediateModeOGLRenderer.java:194)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:317)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:254)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:200)
at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:64)
at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:24)
at Graphics.Loader.loadTexture(Loader.java:37)
at Graphics.LaunchWindow.loop(LaunchWindow.java:116)
at Graphics.LaunchWindow.run(LaunchWindow.java:43)
at Graphics.LaunchWindow.main(LaunchWindow.java:155)
Here's the LaunchWindow class:
package Graphics;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.util.Display;
import Controls.KeyParser;
import Controls.KeyboardInput;
import Controls.MouseInput;
import Controls.MouseParser;
import Graphics.Shaders.StaticShader;
import Controls.Cursor;
import Models.Model1;
import Models.RawModel;
import Models.TexturedModel;
import Textures.ModelTexture;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.nio.ByteBuffer;
#SuppressWarnings("unused")
public class LaunchWindow {
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
private GLFWMouseButtonCallback mouseButtonCallback;
private GLFWCursorPosCallback cursorPosCallback;
public int width = 1024;
public int height = 600;
public String title = "Duplicity";
public long fullscreen = NULL;
public long window;
private Cursor cursor;
public void run() {
try {
init();
loop();
glfwDestroyWindow(window);
keyCallback.release();
} finally {
glfwTerminate();
errorCallback.release();
}
}
private void init() {
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
KeyboardInput.initiate();
MouseInput.initiateMouse();
if ( glfwInit() != GLFW_TRUE )
throw new IllegalStateException("Unable to initialize GLFW");
if(fullscreen == NULL){
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
}
window = glfwCreateWindow(width, height, title, fullscreen, NULL);
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, GLFW_TRUE);
}
});
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
keyCallback = GLFWKeyCallback.create(KeyboardInput::glfw_key_callback);
keyCallback.set(window);
mouseButtonCallback = GLFWMouseButtonCallback.create(MouseInput::glfw_mouse_button_callback);
mouseButtonCallback.set(window);
cursorPosCallback = GLFWCursorPosCallback.create(MouseInput::glfw_cursor_pos_callback);
cursorPosCallback.set(window);
cursor = new Cursor(Cursor.Standard.ARROW);
glfwSetCursor(window, cursor.getCursor());
GL.createCapabilities();
}
public void updateInput() {
KeyboardInput.update();
MouseInput.update();
glfwPollEvents();
}
public void loop() {
Loader loader = new Loader();
Render render = new Render();
Model1 model1 = new Model1();
Display display = new Display();
StaticShader shader = new StaticShader();
RawModel model = loader.loadToVAO(model1.Model1Vertices(), model1.Model1Indices());
ModelTexture texture = new ModelTexture(loader.loadTexture("marble"));
TexturedModel texturedModel = new TexturedModel(model, texture);
GL.createCapabilities();
//glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
if(width != 1024 && height != 600){
System.out.println("resized");
}
while ( glfwWindowShouldClose(window) == GLFW_FALSE ) {
render.prepare();
shader.start();
render.render(texturedModel);
shader.stop();
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
try {
new KeyParser().checkKeyState();
new MouseParser().checkMouseState();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
shader.cleanUp();
loader.cleanUp();
}
public void setCursor(Cursor cursor) {
this.cursor = cursor;
glfwSetCursor(window, cursor.getCursor());
}
public Cursor getCursor() {
return cursor;
}
public static void main(String[] args) {
new LaunchWindow().run();
}
}
And here's Loader:
package Graphics;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import Models.RawModel;
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
private List<Integer> textures = new ArrayList<Integer>();
public RawModel loadToVAO(float[] positions, int[] indices){
int vaoID = createVAO();
bindIndicesBuffer(indices);
storeDataInAttributeList(0, positions);
unbindVAO();
return new RawModel(vaoID, indices.length);
}
public int loadTexture(String fileName){
Texture texture = null;
try {
texture = TextureLoader.getTexture("PNG", new FileInputStream("res/" + fileName + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
int textureID = texture.getTextureID();
textures.add(textureID);
return textureID;
}
public void cleanUp(){
for(int vao:vaos){
GL30.glDeleteVertexArrays(vao);
}
for(int vbo:vbos){
GL15.glDeleteBuffers(vbo);
}
for(int texture:textures){
GL11.glDeleteTextures(texture);
}
}
private int createVAO(){
int vaoID = GL30.glGenVertexArrays();
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
private void storeDataInAttributeList(int attNumber, float[] data){
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_DYNAMIC_DRAW); //change to static if static model
GL20.glVertexAttribPointer(attNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbindVAO(){
GL30.glBindVertexArray(0);
}
private void bindIndicesBuffer(int[] indices){
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDataInIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_DYNAMIC_DRAW); //change to static of static model
}
private IntBuffer storeDataInIntBuffer(int[] data){
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
private FloatBuffer storeDataInFloatBuffer(float[] data){
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
You can download slick util compatible to lwjgl3 here: *click*

Third Person Camera using JBullet and lwjgl

I am developing a race game in java using jbullet and lwjgl.I am currently having trouble in making my camera follow the vehicle.Here is my code.It follows the car until it rotates.Here is the code.Can someone tell me what i am doing wrong ?!
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FRONT_AND_BACK;
import static org.lwjgl.opengl.GL11.GL_LINE;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glPolygonMode;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslated;
import static org.lwjgl.opengl.GL11.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;
import model.Vehicle;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import utility.LWJGLTimer;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import utility.TerrainLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
import com.bulletphysics.collision.dispatch.CollisionConfiguration;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.CollisionWorld;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.collision.shapes.StaticPlaneShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
public class PlanoFight {
private static LookAtCamera camera;
Vector3f position = new Vector3f(0, 0, 0);
private DynamicsWorld dynamicsWorld = null;
public PlanoFight() {
setUpDisplay();
setUpCamera();
setUpDisplayLists();
setUpPhysics();
initializeGL();
startGameLoop();
}
private void setUpDisplayLists() {
}
Vehicle vehicle;
private void startGameLoop() {
LWJGLTimer timer = new LWJGLTimer();
double delta = 0;
timer.initialize();
while (!Display.isCloseRequested()) {
timer.update();
delta = timer.getElapsedTime();
dynamicsWorld.stepSimulation(1f / 60f, 10);
checkInput();
update(delta);
render();
Display.update();
Display.sync(60);
}
cleanup();
Display.destroy();
System.exit(0);
}
private void cleanup() {
}
private void initializeGL() {
}
private void setUpDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(0);
}
}
private void update(double delta) {
vehicle.update();
}
private void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
vehicle.updateCamera(camera);
camera.setMatrices();
vehicle.render();
}
public static void main(String ar[]) {
new PlanoFight();
}
private static void setUpCamera() {
camera = new LookAtCamera(67, 100f, 0.1f, (float) (Display.getWidth() / Display.getHeight()));
camera.setPosition(new Vector3f(0,5,0));
}
private void checkInput() {
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
vehicle.deacelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
vehicle.accelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
vehicle.steerLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
vehicle.steerRight();
}
}
private void setUpPhysics() {
BroadphaseInterface bInterface = new DbvtBroadphase();
CollisionConfiguration configuration = new DefaultCollisionConfiguration();
CollisionDispatcher dispather = new CollisionDispatcher(configuration);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
dynamicsWorld = new DiscreteDynamicsWorld(dispather, bInterface, solver, configuration);
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
vehicle=new Vehicle(dynamicsWorld);
}
}
package model;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glMultMatrix;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glRotated;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertex3f;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import javax.vecmath.Vector3f;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.glu.Cylinder;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.CompoundShape;
import com.bulletphysics.collision.shapes.TriangleIndexVertexArray;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.ConstraintSolver;
import com.bulletphysics.dynamics.vehicle.DefaultVehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.RaycastVehicle;
import com.bulletphysics.dynamics.vehicle.VehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.VehicleTuning;
import com.bulletphysics.dynamics.vehicle.WheelInfo;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.util.ObjectArrayList;
public class Vehicle {
private static final int rightIndex = 0;
private static final int upIndex = 1;
private static final int forwardIndex = 2;
private static final Vector3f wheelDirectionCS0 = new Vector3f(0, -1, 0);
private static final Vector3f wheelAxleCS = new Vector3f(-1, 0, 0);
private static float gEngineForce = 0.f;
private static float gBreakingForce = 0.f;
private static float maxEngineForce = 1000.f;// this should be
// engine/velocity dependent
private static float maxBreakingForce = 100.f;
private static float gVehicleSteering = 0.f;
private static float steeringIncrement = 0.04f;
private static float steeringClamp = 0.3f;
private static float wheelRadius = 0.5f;
private static float wheelWidth = 0.4f;
private static float wheelFriction = 1000;// 1e30f;
private static float suspensionStiffness = 20.f;
private static float suspensionDamping = 2.3f;
private static float suspensionCompression = 4.4f;
private static float rollInfluence = 0.1f;// 1.0f;
private static final float suspensionRestLength = 0.6f;
private static final int CUBE_HALF_EXTENTS = 1;
public RigidBody carChassis;
public ObjectArrayList<CollisionShape> collisionShapes = new ObjectArrayList<CollisionShape>();
public BroadphaseInterface overlappingPairCache;
public CollisionDispatcher dispatcher;
public ConstraintSolver constraintSolver;
public DefaultCollisionConfiguration collisionConfiguration;
public TriangleIndexVertexArray indexVertexArrays;
public ByteBuffer vertices;
public VehicleTuning tuning = new VehicleTuning();
public VehicleRaycaster vehicleRayCaster;
public RaycastVehicle vehicle;
public float cameraHeight;
public float minCameraDistance;
public float maxCameraDistance;
private DynamicsWorld dynamicsWorld;
private Cylinder cylinder;
private int carChassisHandle;
Vector3f direction;
public Vehicle(DynamicsWorld world) {
this.dynamicsWorld = world;
carChassis = null;
cameraHeight = 4f;
minCameraDistance = 3f;
maxCameraDistance = 10f;
indexVertexArrays = null;
vertices = null;
vehicle = null;
cylinder = new Cylinder();
direction = new Vector3f(0, 0, -1);
initPhysics();
try {
Model model = OBJLoader.loadModel(new File("res/chassis.obj"));
carChassisHandle = OBJLoader.createDisplayList(model);
} catch (IOException e) {
e.printStackTrace();
}
}
public void initPhysics() {
CollisionShape groundShape = new BoxShape(new Vector3f(50, 3, 50));
collisionShapes.add(groundShape);
Transform tr = new Transform();
tr.setIdentity();
tr.origin.set(0, -4.5f, 0);
localCreateRigidBody(0, tr, groundShape);
CollisionShape chassisShape = new BoxShape(new Vector3f(1.0f, 0.5f, 2.0f));
collisionShapes.add(chassisShape);
CompoundShape compound = new CompoundShape();
collisionShapes.add(compound);
Transform localTrans = new Transform();
localTrans.setIdentity();
localTrans.origin.set(0, 1, 0);
compound.addChildShape(localTrans, chassisShape);
tr.origin.set(0, 0, 0);
carChassis = localCreateRigidBody(800, tr, compound);
Transform t = new Transform();
carChassis.getWorldTransform(t);
Vector3f forward = new Vector3f();
t.basis.getRow(0, forward);
System.out.println("0 " + forward);
t.basis.getRow(1, forward);
System.out.println("1 " + forward);
t.basis.getRow(2, forward);
System.out.println("2 " + forward);
clientResetScene();
// create vehicle
{
vehicleRayCaster = new DefaultVehicleRaycaster(dynamicsWorld);
vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster);
// never deactivate the vehicle
carChassis.setActivationState(CollisionObject.DISABLE_DEACTIVATION);
dynamicsWorld.addVehicle(vehicle);
float connectionHeight = 1.2f;
boolean isFrontWheel = true;
vehicle.setCoordinateSystem(rightIndex, upIndex, forwardIndex);
Vector3f connectionPointCS0 = new Vector3f(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
isFrontWheel = false;
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
for (int i = 0; i < vehicle.getNumWheels(); i++) {
WheelInfo wheel = vehicle.getWheelInfo(i);
wheel.suspensionStiffness = suspensionStiffness;
wheel.wheelsDampingRelaxation = suspensionDamping;
wheel.wheelsDampingCompression = suspensionCompression;
wheel.frictionSlip = wheelFriction;
wheel.rollInfluence = rollInfluence;
}
}
}
public void render() {
float matrix[] = new float[16];
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3f(100, -4.5f, 100);
glVertex3f(100, -4.5f, -100);
glVertex3f(-100, -4.5f, -100);
glVertex3f(-100, -4.5f, 100);
glEnd();
FloatBuffer buffer;
Transform chassisTr = new Transform();
carChassis.getMotionState().getWorldTransform(chassisTr);
CollisionShape chassisShape = carChassis.getCollisionShape();
if (chassisShape instanceof CompoundShape) {
CollisionShape childShape = ((CompoundShape) chassisShape).getChildShape(0);
if (childShape instanceof BoxShape) {
Vector3f size = new Vector3f();
((BoxShape) childShape).getHalfExtentsWithoutMargin(size);
System.out.println(size.x + " " + size.y + " " + size.z);
System.out.println(chassisTr.origin.x + " " + chassisTr.origin.y + " " + chassisTr.origin.z);
}
}
chassisTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(0, 1, 0);
glPushMatrix();
glMultMatrix(buffer);
glTranslatef(0, 1f, 0);
glCallList(carChassisHandle);
glPopMatrix();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
Transform wheelTr = vehicle.getWheelInfo(i).worldTransform;
wheelTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(1, 0, 0);
glPushMatrix();
glMultMatrix(buffer);
glRotated(90, 0, 1, 0);
cylinder.draw(wheelRadius, wheelRadius, wheelWidth, 10, 10);
glPopMatrix();
}
}
public void update() {
int wheelIndex = 2;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 3;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 0;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
wheelIndex = 1;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
}
public void clientResetScene() {
gVehicleSteering = 0f;
Transform tr = new Transform();
tr.setIdentity();
carChassis.setCenterOfMassTransform(tr);
carChassis.setLinearVelocity(new Vector3f(0, 0, 0));
carChassis.setAngularVelocity(new Vector3f(0, 0, 0));
dynamicsWorld.getBroadphase().getOverlappingPairCache().cleanProxyFromPairs(carChassis.getBroadphaseHandle(), dynamicsWorld.getDispatcher());
if (vehicle != null) {
vehicle.resetSuspension();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
}
}
}
public void steerLeft() {
System.out.println("steer left");
gVehicleSteering += steeringIncrement;
if (gVehicleSteering > steeringIncrement) {
gVehicleSteering = steeringClamp;
}
}
public void steerRight() {
gVehicleSteering -= steeringIncrement;
if (gVehicleSteering < -steeringClamp)
gVehicleSteering = -steeringClamp;
}
public void accelerate() {
gEngineForce = maxEngineForce;
gBreakingForce = 0.0f;
}
public void deacelerate() {
gBreakingForce = maxBreakingForce;
gEngineForce = 0.0f;
}
public void updateCamera(LookAtCamera camera) {
Transform chassisWorldTrans = new Transform();
carChassis.getMotionState().getWorldTransform(chassisWorldTrans);
Transform characterWorldTrans = chassisWorldTrans;
Vector3f up = new Vector3f();
characterWorldTrans.basis.getRow(1, up);
Vector3f backward = new Vector3f();
characterWorldTrans.basis.getRow(2, backward);
backward.scale(-1);
up.normalize();
backward.normalize();
camera.lookAtVector.set(characterWorldTrans.origin);
Vector3f cameraPosition = new Vector3f(camera.lookAtVector.x,camera.lookAtVector.y,camera.lookAtVector.z);
up.scale(4);
cameraPosition.add(up);
backward.scale(8);
cameraPosition.add(backward);
// System.out.println("lookat" + camera.lookAtVector);
// System.out.println("position " + cameraPosition + " angle " + cameraPosition.angle(camera.lookAtVector));
// System.out.println(" " + backward + " " + up);
camera.position.set(cameraPosition);
}
public RigidBody localCreateRigidBody(float mass, Transform startTransform, CollisionShape shape) {
boolean isDynamic = (mass != 0f);
Vector3f localInertia = new Vector3f(0f, 0f, 0f);
if (isDynamic) {
shape.calculateLocalInertia(mass, localInertia);
}
DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
RigidBody body = new RigidBody(cInfo);
dynamicsWorld.addRigidBody(body);
return body;
}
public void printVector(Vector3f origin) {
System.out.println(origin.x + " " + origin.y + " " + origin.z);
}
}

Categories