Probably just an stupid mistake...
public class Mesh {
private final int id;
private final int verticesVBO;
private final int indicesVBO;
private final int vertexCount;
public Mesh(float[]vertices,int[]indices){
vertexCount = indices.length;
id = GL30.glGenVertexArrays();
verticesVBO = GL15.glGenBuffers();
indicesVBO = GL15.glGenBuffers();
GL30.glBindVertexArray(id);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,verticesVBO);
FloatBuffer vbuffer = MemoryUtil.memAllocFloat(vertices.length);
vbuffer.put(vertices);
vbuffer.flip();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,vbuffer,GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0,3,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,indicesVBO);
IntBuffer ibuffer = MemoryUtil.memAllocInt(indices.length);
ibuffer.put(indices);
ibuffer.flip();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,ibuffer,GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
GL30.glBindVertexArray(0);
MemoryUtil.memFree(vbuffer);
}
public void render(){
GL30.glBindVertexArray(id);
GL20.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, id);
GL11.glDrawElements(GL11.GL_TRIANGLES,vertexCount,GL11.GL_UNSIGNED_INT,0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public void destroy(){
GL15.glDeleteBuffers(verticesVBO);
GL15.glDeleteBuffers(indicesVBO);
GL30.glDeleteVertexArrays(id);
}
}
public class GameEngine {
private final String title;
private int width;
private int height;
private boolean fullscreen;
private boolean resizable;
private boolean vsync;
private long handle;
private Color clearColor;
private final ArrayList<GameObject> objects = new ArrayList<>();
private Shader shader;
private final IGameLogic logic;
public GameEngine(IGameLogic logic){
this.logic = logic;
WindowProperties prop = this.logic.preInit();
this.title = prop.getTitle();
this.width = prop.getWidth();
this.height = prop.getHeight();
this.fullscreen = prop.isFullscreen();
this.resizable = prop.isResizable();
this.vsync = prop.isVsync();
this.clearColor = prop.getClearColor();
}
private void init() throws GLException, ClassNotFoundException, IOException{
GLFWErrorCallback.createThrow().set();
if(!GLFW.glfwInit()){
throw new GLException("cannot initialize GLFW");
}
long monitor = MemoryUtil.NULL;
if(fullscreen){
monitor = GLFW.glfwGetPrimaryMonitor();
}
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR,3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR,2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE,GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT,GLFW.GLFW_TRUE);
if(resizable){
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE,GLFW.GLFW_TRUE);
}
handle = GLFW.glfwCreateWindow(width,height,title,monitor,MemoryUtil.NULL);
GLFW.glfwSetWindowSizeCallback(handle,new GLFWWindowSizeCallbackI() {
@Override
public void invoke(long window, int width, int height) {
GL11.glViewport(0,0, width,height);
}
@Override
public void callback(long args) {
}
@Override
public String getSignature() {
return null;
}
@Override
public long address() {
return MemoryUtil.NULL;
}
});
GLFW.glfwMakeContextCurrent(handle);
if(vsync){
GLFW.glfwSwapInterval(1);
}
GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClearColor(clearColor.getRed(),clearColor.getGreen(),clearColor.getBlue(),clearColor.getAlpha());
shader = new Shader(Utils.loadResource("/shader/vertex.vs"),Utils.loadResource("/shader/fragment.fs"));
logic.init();
}
private void destroy(){
logic.destroy();
shader.destroy();
GLFW.glfwDestroyWindow(handle);
GLFW.glfwTerminate();
}
private void update(){
GLFW.glfwPollEvents();
}
private void render(){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
shader.bind();
logic.render();
shader.unbind();
if(!vsync){
GLFW.glfwSwapBuffers(handle);
}
}
public void start() throws ClassNotFoundException, IOException{
try{
init();
long lastTime = System.nanoTime();
double delta = 0.0;
double ns = 1000000000.0 / 60.0;
long timer = System.currentTimeMillis();
int updates = 0;
int frames = 0;
while(!GLFW.glfwWindowShouldClose(handle)){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1.0) {
update();
updates++;
delta--;
}
update();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " ups, " + frames + " fps");
updates = 0;
frames = 0;
}
}
destroy();
}catch(GLException ex){
ex.printStackTrace();
}
}
}
public class GameEngine {
private final String title;
private int width;
private int height;
private boolean fullscreen;
private boolean resizable;
private boolean vsync;
private long handle;
private Color clearColor;
private final ArrayList<GameObject> objects = new ArrayList<>();
private Shader shader;
private final IGameLogic logic;
public GameEngine(IGameLogic logic){
this.logic = logic;
WindowProperties prop = this.logic.preInit();
this.title = prop.getTitle();
this.width = prop.getWidth();
this.height = prop.getHeight();
this.fullscreen = prop.isFullscreen();
this.resizable = prop.isResizable();
this.vsync = prop.isVsync();
this.clearColor = prop.getClearColor();
}
private void init() throws GLException, ClassNotFoundException, IOException{
GLFWErrorCallback.createThrow().set();
if(!GLFW.glfwInit()){
throw new GLException("cannot initialize GLFW");
}
long monitor = MemoryUtil.NULL;
if(fullscreen){
monitor = GLFW.glfwGetPrimaryMonitor();
}
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR,3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR,2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE,GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT,GLFW.GLFW_TRUE);
if(resizable){
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE,GLFW.GLFW_TRUE);
}
handle = GLFW.glfwCreateWindow(width,height,title,monitor,MemoryUtil.NULL);
GLFW.glfwSetWindowSizeCallback(handle,new GLFWWindowSizeCallbackI() {
@Override
public void invoke(long window, int width, int height) {
GL11.glViewport(0,0, width,height);
}
@Override
public void callback(long args) {
}
@Override
public String getSignature() {
return null;
}
@Override
public long address() {
return MemoryUtil.NULL;
}
});
GLFW.glfwMakeContextCurrent(handle);
if(vsync){
GLFW.glfwSwapInterval(1);
}
GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClearColor(clearColor.getRed(),clearColor.getGreen(),clearColor.getBlue(),clearColor.getAlpha());
shader = new Shader(Utils.loadResource("/shader/vertex.vs"),Utils.loadResource("/shader/fragment.fs"));
logic.init();
}
private void destroy(){
logic.destroy();
shader.destroy();
GLFW.glfwDestroyWindow(handle);
GLFW.glfwTerminate();
}
private void update(){
GLFW.glfwPollEvents();
}
private void render(){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
shader.bind();
logic.render();
shader.unbind();
if(!vsync){
GLFW.glfwSwapBuffers(handle);
}
}
public void start() throws ClassNotFoundException, IOException{
try{
init();
long lastTime = System.nanoTime();
double delta = 0.0;
double ns = 1000000000.0 / 60.0;
long timer = System.currentTimeMillis();
int updates = 0;
int frames = 0;
while(!GLFW.glfwWindowShouldClose(handle)){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1.0) {
update();
updates++;
delta--;
}
update();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " ups, " + frames + " fps");
updates = 0;
frames = 0;
}
}
destroy();
}catch(GLException ex){
ex.printStackTrace();
}
}
}
#version 450
in vec3 exColor;
out vec4 fragColor;
void main(){
}
#version 450
layout(location=0) in vec3 position;
void main(){
gl_Position = vec4(position,1.0);
}
public class GameLogic implements IGameLogic{
private Mesh mesh;
@Override
public void init() {
mesh = new Mesh(new float[]{0,0,0,1,0,0,1,1,0},new int[]{0,1,2});
}
@Override
public WindowProperties preInit() {
return new WindowProperties("Game",500,500,false,true,false,new Color(0,0,1,0));
}
@Override
public void update() {
}
@Override
public void render() {
mesh.render();
}
@Override
public void destroy() {
mesh.destroy();
}
}
public class Main{
/**
* @param args the command line arguments
* @throws java.lang.ClassNotFoundException
* @throws java.io.IOException
*/
public static void main(String[] args) throws ClassNotFoundException, IOException {
new GameEngine(new GameLogic()).start();
}
}