PDA

View Full Version : Problem with model rendering (JAVA, OPENGL 2.1)



kaboom
09-25-2015, 11:30 AM
I am having a small issue with my new game engine that I cannot figure out. I am relatively new to using openGL and the whole of GLSL for shading as a concept; this is the engine for my game called Redwall.

Currently when I try and render more then one model with my engine it gets distorted like this:
2114

If I only load the one model, I can load it a million times and have no problems or distortion. If I load another model however, the last (current) model to be passed through the render engine will load properly but all the other models before it will become distored on their vertices for some reason. I have went over it a million times and cannot find an issue. I will post the whole render process for a model and you can tell me where I went wrong hopefully? Models are stored into vbo and vaos and loaded in order, game engine is ran in Java using LWJGL and slicktools

Here is loading one model a bunch of times properly:
2115

I have included the relevant loading information here and cut out a lot of other non relevant things.

First in my main loop i call the model and set its name:

//load my tree model and set the settings on it
ModelData treeData = OBJFileLoader.loadOBJ("lowPolyTree");
RawModel treeModel = loader.loadToVAO(treeData.getVertices(), treeData.getTextureCoords(), treeData.getNormals(), treeData.getIndices());
TexturedModel treeTexturedModel = new TexturedModel(treeModel, new ModelTexture(loader.loadTexture("lowPolyTree")));
ModelTexture tree = treeTexturedModel.getTexture();
tree.setHasTransparency(true);
tree.setUseFakeLighting(false);
tree.setShineDamper(8);
tree.setReflectivity(0);

then they are loaded to a vao with this code which is my loader class:

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 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);
}
}

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;
}


this is all used in the master renderer to load for the main game loop as this:

private Matrix4f projectionMatrix;
private StaticShader shader = new StaticShader();
private EntityRenderer renderer;
private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();

public MasterRenderer(Loader loader) {
enableCulling();
createProjectionMatrix();
renderer = new EntityRenderer(shader, projectionMatrix);
}

public Matrix4f getProjectionMatrix() {
return projectionMatrix;
}

public void render(Light sun, Camera camera) {
prepare();
shader.start();
shader.loadLight(sun);
shader.loadViewMatrix(camera);
renderer.render(entities);
shader.stop();
entities.clear();
}

public static void enableCulling() {
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK);
}

public void processEntity(Entity entity) {
TexturedModel entityModel = entity.getModel();
List<Entity> batch = entities.get(entityModel);
if (batch != null) {
batch.add(entity);
} else {
List<Entity> newBatch = new ArrayList<Entity>();
newBatch.add(entity);
entities.put(entityModel, newBatch);
}
}

public void cleanUp() {
shader.cleanUp();
terrainShader.cleanUp();
}

public void prepare() {
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(RED, GREEN, BLUE, 1);
}

private void createProjectionMatrix() {
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;

projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}



this is all passed through the entityrenderer as this:

public class EntityRenderer {

private StaticShader shader;

public EntityRenderer(StaticShader shader, Matrix4f projectionMatrix) {
this.shader = shader;
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
}

public void render(Map<TexturedModel, List<Entity>> entities) {
for (TexturedModel model : entities.keySet()) {
prepareTexturedModel(model);
List<Entity> batch = entities.get(model);
for (Entity entity : batch) {
prepareInstance(entity);
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
}
unbindTexturedModel();
}
}

private void prepareTexturedModel(TexturedModel model) {
RawModel rawModel = model.getRawModel();
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
ModelTexture texture = model.getTexture();
if(texture.isHasTransparency()) {
MasterRenderer.disableCulling();
}
shader.loadNumberOfRows(texture.getNumberOfRows()) ;
shader.loadFakeLightingVariable(texture.isUseFakeL ighting());
shader.loadShineVariables(texture.getShineDamper() , texture.getReflectivity());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getID());
}

private void unbindTexturedModel() {
MasterRenderer.enableCulling();
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}

private void prepareInstance(Entity entity) {
Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPositio n(), entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale());
shader.loadTransformationMatrix(transformationMatr ix);
shader.loadOffset(entity.getTextureXOffset(), entity.getTextureYOffset());
}

}


Everything is passed through a shader to load texture and light. The shaders have all been written in glsl 130 and work great at rendering colour and light properly. Something is stopping my cpu from loading the models and displaying them correctly even tho as far as I can tell they should be working. On a better pc this code worked to load models correctly but wont on this laptop now.

kaboom
09-30-2015, 10:49 AM
Bump , anyone?

kaboom
10-16-2015, 05:46 PM
I guess not :(