LWJGL Forum

Programming => OpenGL => Topic started by: Kaboom on September 14, 2015, 18:40:58

Title: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on September 14, 2015, 18:40:58
Hey guys I need some help with my game rendering engine from someone with a bit more experience than I currently have as I cannot get my models to load properly.

The game is coded in OpenGL and Java and uses GLSL 130 for shader support. What happens is when I load one single object it will render taht object properly and have spectral lighting and ambient lighting and everything else works great. I can load up 1000+ of the same model onto my screen and they all render properly. Sounds good right?

But if I load a second model, the second model that is rendered will come up properly and the first model will be distorted all over its vertexes. I cannot switch to a higher GLSL version so I am currently using #version 130. When I generate my terrain, it loads properly as its the last thing rendered by the engine but all the models for npc and players and the like get scewered verteces.

The game is using lwjgl (latest version 2, legacy) and slicktools2D. I have had it suggested that it could be an issue with the matrix not reseting on the next model but my code looks good. It could also be a hardware problem as i have only opengl 2.1 with some 3.0 capacity on my laptop, but since it does load one model at a time perfectly with this engine, it doesnt make sense it cant load more than one type.

Here is a screen shot of my problem to see what I mean for you guys: 
http://imgur.com/NwKhqeS (http://imgur.com/NwKhqeS)

Hopefully by submitting my source here someone can go through it and see if they can tell me what I am missing?? I have included all my java files and models in the attachment below.

Here is the source code for my game so far (from eclipse):   
https://www.mediafire.com/?clwgbxwvo605ht1 (https://www.mediafire.com/?clwgbxwvo605ht1)
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: emris on September 28, 2015, 13:04:08
I see you are using an engine based on ThinMatrix tutorials, cool :)  ..  https://www.youtube.com/playlist?list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP

Your download link is not working so i can't take a closer look, but maybe your problem is with the loader, maybe the VAO/VBO id's are getting mixed up, or it could be something totally different. It's very hard to say without the code.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on September 30, 2015, 17:57:47
Here is my current game engine. And yes it was based on ThinMatrix engine :) Unfortunately even he could not find an issue with my code to see what was causing the issue :(

https://www.mediafire.com/?clwgbxwvo605ht1 (https://www.mediafire.com/?clwgbxwvo605ht1)

and here is my loader.class
package renderEngine;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import models.RawModel;
import textures.TextureData;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
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 de.matthiasmann.twl.utils.PNGDecoder;
import de.matthiasmann.twl.utils.PNGDecoder.Format;

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, float[] textureCoords, float[] normals, int[] indices) {
        int vaoID = createVAO();
        bindIndicesBuffer(indices);
        storeDataInAttributeList(0, 3, positions);
        storeDataInAttributeList(1, 2, textureCoords);
        storeDataInAttributeList(2, 3, normals);
        unbindVAO();
        return new RawModel(vaoID, indices.length);
    }
   
    public RawModel loadToVAO(float[] positions, int dimensions) {
        int vaoID = createVAO();
        storeDataInAttributeList(0, dimensions, positions);
        unbindVAO();
        return new RawModel(vaoID, positions.length / dimensions);
    }
   
    public int loadTexture(String fileName) {
        Texture texture = null;
        try {
            texture = TextureLoader.getTexture("PNG", new FileInputStream("models/"+fileName+".png"));
            //To add mipmapping for objects we need this, doesn't work on my cpu tho
            //GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
            //GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
            //GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -0.4f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        textures.add(texture.getTextureID());
        return texture.getTextureID();
    }
   
    public void cleanUp() {
        for (int vao : vaos) {
            GL30.glDeleteVertexArrays(vao);
        }
        for (int vbo : vbos) {
            GL15.glDeleteBuffers(vbo);
        }
        for (int texture : textures) {
            GL11.glDeleteTextures(texture);
        }
    }
   
    public int loadCubeMap(String[] textureFiles) {
        int texID = GL11.glGenTextures();
        GL13.glActiveTexture(GL13.GL_TEXTURE0);
        GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texID);
        for (int i = 0; i < textureFiles.length; i++) {
            TextureData data = decodeTextureFile("models/skybox/" + textureFiles[i] + ".png");
            GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL11.GL_RGBA, data.getWidth(), data.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data.getBuffer());
        }
        GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        textures.add(texID);
        return texID;
    }
   
    private TextureData decodeTextureFile(String fileName) {
        int width = 0;
        int height = 0;
        ByteBuffer buffer = null;
        try {
            FileInputStream in = new FileInputStream(fileName);
            PNGDecoder decoder = new PNGDecoder(in);
            width = decoder.getWidth();
            height = decoder.getHeight();
            buffer = ByteBuffer.allocateDirect(4 * width * height);
            decoder.decode(buffer, width * 4, Format.RGBA);
            buffer.flip();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Tried to load texture " + fileName + ", didn't work");
            System.exit(-1);
        }
        return new TextureData(buffer, width, height);
    }
   
    private int createVAO() {
        int vaoID = GL30.glGenVertexArrays();
        vaos.add(vaoID);
        GL30.glBindVertexArray(vaoID);
        return vaoID;
    }
   
    private void storeDataInAttributeList(int attributeNumber, int coordinateSize, 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_STATIC_DRAW);
        GL20.glVertexAttribPointer(attributeNumber, coordinateSize, 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 indicesBuffer = storeDataInIntBuffer(indices);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
    }
   
    private IntBuffer storeDataInIntBuffer(int[] data) {
        IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }
   
    private FloatBuffer storeDataInFloatBuffer(float[] data) {
        FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(data.length);
        floatBuffer.put(data);
        floatBuffer.flip();
        return floatBuffer;
    }
   
}
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: emris on September 30, 2015, 19:58:48
I just downloaded and tried your code, and everything looks fine for me. No strange graphical glitches that i can see.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on September 30, 2015, 23:58:00
Thats because your gpu is doing something to render the models correctly while mine cannot since it only supports opengl 2.1 with some support for 3.2 stuff. Thats why I cannot use mipmapping on my code at all. I am missing something gpu specific to tell my gfx card to render the models correctly because it doesnt understand the buffering or something and is distorting models when it loads the next one. It is programmed perfectly for a gpu supporitng opengl 3+ but sadly not 2.1+ and since most normal laptops (mine included) run 2.1 varients, I need to be able to run in those gpus as well to support my game (and continue coding it without a new pc).

If you can see anything I am missing to render multiple objects on older gpus please let me know! :) thanks.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 01, 2015, 03:57:01
glbindVertexarray using opengl 2.1 to use my vbo and vao is apparently unsupported so its messing up my model rendering :( I dont know  a way to work around this
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kai on October 01, 2015, 08:56:06
Quote from: Kaboom on October 01, 2015, 03:57:01
glbindVertexarray using opengl 2.1 to use my vbo and vao is apparently unsupported so its messing up my model rendering :( I dont know  a way to work around this
If you currently rely on using VAOs to encapsulate vertex array state, such as vertex bindings and array enablings, then there is no easy way to work around this.
However, OpenGL VAOs do not require a full OpenGL 3.0 capable graphics cards.
The extension itself is written against OpenGL 2.1, and the functionality should be purely server-side book-keeping.
So please update your graphics card driver and/or see whether you have the ARB_vertex_array_object (https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt) extension available, and use that.
(I have an Nvidia GeForce 6200 LE, with driver 309.08 right now here, that also only supports OpenGL 2.1.2, but does have that extension available.)
If that does not help, then I would probably build my own abstraction of a VAO and delegate all vertex array state functions (glVertexAttribPointer, glEnableVertexAttrib, ...) through it.
That abstract VAO class then handles whether it can use a real OpenGL VAO or must emulate it by using many OpenGL vertex array state functions when switching from one VAO to another.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 01, 2015, 16:36:08
Quote from: Kai on October 01, 2015, 08:56:06
If you currently rely on using VAOs to encapsulate vertex array state, such as vertex bindings and array enablings, then there is no easy way to work around this.
However, OpenGL VAOs do not require a full OpenGL 3.0 capable graphics cards.
The extension itself is written against OpenGL 2.1, and the functionality should be purely server-side book-keeping.
So please update your graphics card driver and/or see whether you have the ARB_vertex_array_object (https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt) extension available, and use that.
(I have an Nvidia GeForce 6200 LE, with driver 309.08 right now here, that also only supports OpenGL 2.1.2, but does have that extension available.)
If that does not help, then I would probably build my own abstraction of a VAO and delegate all vertex array state functions (glVertexAttribPointer, glEnableVertexAttrib, ...) through it.
That abstract VAO class then handles whether it can use a real OpenGL VAO or must emulate it by using many OpenGL vertex array state functions when switching from one VAO to another.

I have the latest drivers for my pc, I thought maybe I could get a better one and fix the problem but my pc doesnt support the binding function from gl30 so it returns all the vaos vertexes as the same and it distorts my models. I can load them without the use of the vao since all the model data is stored in vbos and only load vaos if the driver support is over 3.0, but it adds a lot more code for me so I was kind of syked to use the vao system to load my models. Ill have a look and see if I have support for the ARB version, but if I do, what would I use instead in my renderer to load the models using arb extensions if I am using lwjgl? I've never used them before.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kai on October 01, 2015, 16:43:01
Well, just use:


import static org.lwjgl.opengl.ARBVertexArrayObject.*;


instead of:


import static org.lwjgl.opengl.GL30.*;


You can check whether the driver supports that extension by doing (LWJGL 3 latest nightly build):


GLCapabilities caps = GL.createCapabilities();
boolean hasThatExtension = caps.GL_ARB_vertex_array_object;
if (hasThatExtension) {
  // use it
} else {
  // emulate it
}


So, if the driver does not export that extension, then I would build another class containing the static vertex array state functions, and do the bookkeeping of the vertex array state myself.
So, you would just not call GL30.glBindVertexArray anymore, but your own GL30Emulation.glBindVertexArray, as well as the GL15 functions.
Then you would not have to update your current application/engine code, except switch the static import.

It is however a pity that all the GLxx classes in LWJGL 3 are final. Because otherwise one could just extend those classes and override or rather "hide" the vertex array functions by implementing new ones. This way, one would not have to choose between either GL15 functions unrelated to vertex array state and the GL30Emulation (and GL15Emulation) classes which also disallows static imports, because of ambiguous methods.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 01, 2015, 17:40:23
I did a quick print out from my code and this is what my pc has:

OpenGL Version: 2.1.0 - Build 8.15.10.2869
GPU Chipset: Mobile Intel(R) 4 Series Express Chipset Family
Chip Type: Intel
Supported Extentions:
GL_EXT_blend_minmax
GL_EXT_blend_subtract
GL_EXT_blend_color
GL_EXT_abgr
GL_EXT_texture3D
GL_EXT_clip_volume_hint
GL_EXT_compiled_vertex_array
GL_SGIS_texture_edge_clamp
GL_SGIS_generate_mipmap
GL_EXT_draw_range_elements
GL_SGIS_texture_lod
GL_EXT_rescale_normal
GL_EXT_packed_pixels
GL_EXT_texture_edge_clamp
GL_EXT_separate_specular_color
GL_ARB_multitexture
GL_EXT_texture_env_combine
GL_EXT_bgra
GL_EXT_blend_func_separate
GL_EXT_secondary_color
GL_EXT_fog_coord
GL_EXT_texture_env_add
GL_ARB_texture_cube_map
GL_ARB_transpose_matrix
GL_ARB_texture_env_add
GL_IBM_texture_mirrored_repeat
GL_EXT_multi_draw_arrays
GL_NV_blend_square
GL_ARB_texture_compression
GL_3DFX_texture_compression_FXT1
GL_EXT_texture_filter_anisotropic
GL_ARB_texture_border_clamp
GL_ARB_point_parameters
GL_ARB_texture_env_combine
GL_ARB_texture_env_dot3
GL_ARB_texture_env_crossbar
GL_EXT_texture_compression_s3tc
GL_ARB_shadow
GL_ARB_window_pos
GL_EXT_shadow_funcs
GL_EXT_stencil_wrap
GL_ARB_vertex_program
GL_EXT_texture_rectangle
GL_ARB_fragment_program
GL_EXT_stencil_two_side
GL_ATI_separate_stencil
GL_ARB_vertex_buffer_object
GL_EXT_texture_lod_bias
GL_ARB_occlusion_query
GL_ARB_fragment_shader
GL_ARB_shader_objects
GL_ARB_shading_language_100
GL_ARB_texture_non_power_of_two
GL_ARB_vertex_shader
GL_NV_texgen_reflection
GL_ARB_point_sprite
GL_EXT_blend_equation_separate
GL_ARB_depth_texture
GL_ARB_texture_rectangle
GL_ARB_draw_buffers
GL_ARB_color_buffer_float
GL_ARB_half_float_pixel
GL_ARB_texture_float
GL_ARB_pixel_buffer_object
GL_EXT_framebuffer_object
GL_ARB_draw_instanced
GL_ARB_half_float_vertex
GL_EXT_draw_buffers2
GL_WIN_swap_hint
GL_EXT_texture_sRGB
GL_EXT_packed_float
GL_EXT_texture_shared_exponent
GL_ARB_texture_rg
GL_ARB_texture_compression_rgtc
GL_NV_conditional_render
GL_EXT_texture_swizzle
GL_ARB_framebuffer_sRGB
GL_EXT_packed_depth_stencil
GL_ARB_depth_buffer_float
GL_EXT_transform_feedback
GL_EXT_framebuffer_blit
GL_ARB_vertex_array_object


I switched all my gl30 calls to ARB:
//GL30.glDeleteVertexArrays(vao);
ARBVertexArrayObject.glDeleteVertexArrays(vao);


//int vaoID = GL30.glGenVertexArrays();
int vaoID = ARBVertexArrayObject.glGenVertexArrays();
vaos.add(vaoID);
//GL30.glBindVertexArray(vaoID);
ARBVertexArrayObject.glBindVertexArray(vaoID);


My models are still not rendering properly on my machine though and it says it supports the arb functions :( So i am at a loss..
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 01, 2015, 18:39:35
I set up a way to check the opengl version of the pc and then set it to load the code based on wether or not the user has opengl 3+ support or is running less then they use the arb versions. While this doesnt solve my issue with my pc, it might add engine support to other computers that can run it. I did so as follows:

if (DisplayManager.OPENGL < 300) {
    ARBVertexArrayObject.glBindVertexArray(0);
} else {
    GL30.glBindVertexArray(0);
}


I check the version by implementing a check on the opengl string for GL_VERSION in my Display manager as follows:
public static int OPENGL = 0;

//Load the openGL version from string as "2.1.0" and set result to 0
String gl_Version = GL11.glGetString(GL11.GL_VERSION);
String result = "";
           
//Because it loads int . int . int we need to have the first 5
for (int i = 0; i < 5; i++) {
    Character character = gl_Version.charAt(i);
    if (Character.isDigit(character)) {
        result += character;
        Integer.parseInt(result);
    }
}
           
OPENGL = Integer.parseInt(result);
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: quew8 on October 02, 2015, 17:39:42
I'd suggest a more reliable way to ascertain the OpenGL version is by using LWJGL's GLCapabilities class. Check out this code:


boolean isGL33 = GL.getCapabilities().OpenGL33;


That class also contains information on supported extensions, which would also be useful to you. For example if you wanted to check for the ARB framebuffers extension.


boolean ihasFramebuffers = GL.getCapabilities().GL_ARB_framebuffer_object;
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 27, 2015, 00:18:03
Thats for lwjgl 3.0. this uses 2.9
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: SHC on October 27, 2015, 13:48:25
In LWJGL 2.9, that is GLContext.getCapabilities().OpenGL33;

http://legacy.lwjgl.org/javadoc/org/lwjgl/opengl/GLContext.html#getCapabilities()
http://legacy.lwjgl.org/javadoc/org/lwjgl/opengl/ContextCapabilities.html#OpenGL33

That makes the previous code to this.


boolean isGL33 = GLContext.getCapabilities().OpenGL33;
boolean ihasFramebuffers = GLContext.getCapabilities().GL_ARB_framebuffer_object;


The only change is the class name, GLContext is replaced by GL in LWJGL 3.
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 28, 2015, 21:55:41
Quote from: SHC on October 27, 2015, 13:48:25
In LWJGL 2.9, that is GLContext.getCapabilities().OpenGL33;

...

The only change is the class name, GLContext is replaced by GL in LWJGL 3.

Thanks for the response but I found out that method shortly after I had replied to him and forgot to check back in :P Unfortunately, while I also am using the LWJGL function to check for ARB function support on clients PC and use those extensions where available, it is still rendering strange on my laptop supporting openGL 2.1 but works well on my friends PC who runs opengl 3. As far as I can tell on my code it should be showing properly on my laptop as well but it is not.

Here is an updated picture of whats happening to the models:
http://i.imgur.com/7OysbUa.png (http://i.imgur.com/7OysbUa.png)

I will also give you a link to the newer source code here, I have been changing some stuff up and added support for icons and what not as well as some other things to make the layout nicer but I am still having that issue on this PC shown in the image above and I really want to fix it. Thanks to some awesome users here, my shaders running version 130 also support an inverse function now that isn't core until 150 so I can do proper texturing now. Just wish the models kept proper vertices and normals on this pc like they do on a better one :(

Newer source code:
http://www.megafileupload.com/5ofy/Redwall_v30.rar

Here is a video of the problem I have
https://www.youtube.com/watch?v=FJcTVu2eXQk
Title: Re: Problem loading mutiple objects properly in game (full source)
Post by: Kaboom on October 29, 2015, 21:46:07
I posted a video of the issue now for you guys

Here is the video
https://www.youtube.com/watch?v=FJcTVu2eXQk