Hello fellow JGO members,
I have been in the process of migrating my game engine from legacy OpenGL to OpenGL v3.3 Core Profile and have run into some errors.
Everything seems to compile fine, and my view matrix is changing, I just cant seem to see anything on the screen no matter what I try.
Basically, the engine creates the GL context; then generates a chunk and calls the createMatrices then createVBO methods. The chunk is then (supposed to be) rendered using the calculated projection, view and model matrices.
Here’s my code for reference;
Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 colour;
out vec4 vertexColor; // Specify a color output to the fragment shader
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
void main()
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0f);
vertexColor = vec4(colour, 1.0f); // Set the output variable to a dark-red color
}
Fragment Shader
#version 330 core
in vec4 vertexColor; // The input variable from the vertex shader (same name and same type)
out vec4 color;
void main()
{
color = vertexColor;
}
Shader Loader class:
public class ShaderLoader {
public int getProgram() {
return program;
}
private int program=0;
public void useShader(){
GL20.glUseProgram(program);
}
public void disableShader(){
GL20.glUseProgram(0);
}
public void load(String vert, String frag){
// Load the vertex shader
int vsId = loadShader("src/shaders/" + vert, GL20.GL_VERTEX_SHADER);
// Load the fragment shader
int fsId = loadShader("src/shaders/" + frag, GL20.GL_FRAGMENT_SHADER);
// Create a new shader program that links both shaders
program = GL20.glCreateProgram();
GL20.glAttachShader(program, vsId);
GL20.glAttachShader(program, fsId);
GL20.glBindAttribLocation(program, 0, "position");
GL20.glBindAttribLocation(program, 1, "normal");
GL20.glBindAttribLocation(program, 2, "colour");
GL20.glLinkProgram(program);
GL20.glValidateProgram(program);
}
private int loadShader(String filename, int type) {
StringBuilder shaderSource = new StringBuilder();
int shaderID = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Could not read file.");
e.printStackTrace();
System.exit(-1);
}
shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if (GL20.glGetShader(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Could not compile shader.");
System.exit(-1);
}
return shaderID;
}
}
And finally, my chunk class (some irrelevant sections emmitted:
public class Chunk {
public static short xSize = 64;
public static short ySize = 64;
public static short zSize = 64;
private Vector3f position = new Vector3f(0, 0, 0);
private Vector3f angle = new Vector3f(0, 0, 0);
private Vector3f scale = new Vector3f(1, 1, 1);
private Matrix4f modelMatrix;
private Matrix4f viewMatrix;
private Matrix4f projectionMatrix;
private byte[] RLEdata; //RLE Data is Run Length Encoded data of the world; Irrelevant to this as I know this worked in the previous rendering engine.
private int VBOVertexHandle;
private int VAOVertexHandle;
private int vertexNum = 0;
private ShaderLoader mainShader;
public Chunk(Vector3f position, byte[][][] data){
this.position = position;
RLEdata = RLEOps.computeRLEData(data);
}
public void DrawVBO() {
mainShader.useShader(); \\This enables the shader program
int locModel = GL20.glGetUniformLocation(mainShader.getProgram(), "modelMatrix");
FloatBuffer modelMatrixBuffer = BufferUtils.createFloatBuffer(4*4);
modelMatrix.store(modelMatrixBuffer);
modelMatrixBuffer.flip();
GL20.glUniformMatrix4(locModel, false, modelMatrixBuffer);
viewMatrix.setIdentity(); \\updates the view matrix from camera data (this camera data is correct)
viewMatrix.rotate(Camera.getRotationX(), Camera.xAxis);
viewMatrix.rotate(Camera.getRotationY(), Camera.yAxis);
viewMatrix.rotate(Camera.getRotationZ(), Camera.zAxis);
viewMatrix.translate(Camera.getPos());
int locView = GL20.glGetUniformLocation(mainShader.getProgram(), "viewMatrix");
FloatBuffer viewMatrixBuffer = BufferUtils.createFloatBuffer(4*4);
viewMatrix.store(viewMatrixBuffer);
viewMatrixBuffer.flip();
GL20.glUniformMatrix4(locView, false, viewMatrixBuffer);
int locProjection = GL20.glGetUniformLocation(mainShader.getProgram(), "projectionMatrix");
FloatBuffer projectionMatrixBuffer = BufferUtils.createFloatBuffer(4*4);
projectionMatrix.store(projectionMatrixBuffer);
projectionMatrixBuffer.flip();
GL20.glUniformMatrix4(locProjection, false, projectionMatrixBuffer);
GL30.glBindVertexArray(VAOVertexHandle);
GL11.glDrawArrays(GL11.GL_QUADS, 0, vertexNum);
GL30.glBindVertexArray(0);
mainShader.disableShader();
}
public void createMatrices(){
//Initialise Model Matrix
modelMatrix = new Matrix4f();
modelMatrix.setIdentity();
Matrix4f.scale(scale, modelMatrix, modelMatrix);
Matrix4f.translate(position, modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(angle.z), new Vector3f(0, 0, 1), modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(angle.y), new Vector3f(0, 1, 0), modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(angle.x), new Vector3f(1, 0, 0), modelMatrix, modelMatrix);
//Initialise View Matrix
viewMatrix = new Matrix4f();
viewMatrix.setIdentity();
//Initialise Projection Matrix
projectionMatrix = new Matrix4f();
float y_scale = 1/(float)Math.tan(Math.toRadians(Game.fieldOfView / 2f));
float x_scale = y_scale / Game.aspectRatio;
float frustum_length = Game.far_plane - Game.near_plane;
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((Game.far_plane + Game.near_plane) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * Game.near_plane * Game.far_plane) / frustum_length);
projectionMatrix.m33 = 0;
}
public void CreateVBO() {
mainShader = new ShaderLoader();
mainShader.load("main.vert", "main.frag");
byte[] RLEFaces = RLEOps.computeRLEFaces(RLEdata);
vertexNum = RLEOps.getVertexNum();
short x = 0;
short y = 0;
short z = 0;
VBOVertexHandle = GL15.glGenBuffers();
ByteBuffer vertexData = BufferUtils.createByteBuffer(vertexNum*12); //6 bytes for vertex + 3 bytes for normal + 3 bytes for colour
for(int n = 0; n + 1 < RLEFaces.length; n += 2){
if(RLEFaces[n] != 0) {
for (int i = 0; i < RLEFaces[n + 1]; i++) {
byte gr = (byte) ((float) y / ySize * 0xFF);
if ((RLEFaces[n] & 0x01) == 0x01) {
vertexData.putShort((short) (x + 1)); //y+
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((RLEFaces[n] & 0x02) / 0x02 == 0x01) {
vertexData.putShort((short) (x + 1)); //y-
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((RLEFaces[n] & 0x04) / 0x04 == 0x01) {
vertexData.putShort((short) (x + 1)); //z+
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((RLEFaces[n] & 0x08) / 0x08 == 0x01) {
vertexData.putShort((short) (x + 1)); //z-
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((RLEFaces[n] & 0x10) / 0x10 == 0x01) {
vertexData.putShort((short) (x + 1)); //x+
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort((short) (x + 1));
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) 1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((RLEFaces[n] & 0x20) / 0x20 == 0x01) {
vertexData.putShort(x); //x-
vertexData.putShort((short) (y + 1));
vertexData.putShort((short) (z + 1));
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort((short) (y + 1));
vertexData.putShort(z);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort(z);
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
vertexData.putShort(x);
vertexData.putShort(y);
vertexData.putShort((short) (z + 1));
vertexData.put((byte) -1);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put((byte) 0);
vertexData.put(gr);
vertexData.put((byte) 0);
}
if ((x + z) % 2 == 0 && y + 1 < ySize) {
y++;
}
else if ((x + z) % 2 != 0 && y > 0) {
y--;
}
else if (x % 2 == 0 && z + 1 < zSize) {
z++;
}
else if (x % 2 != 0 && z > 0){
z--;
}
else {
x++;
}
}
}
else{
int packedXYZ = RLEOps.getPackedXYZ(RLEFaces[n + 1], x, y, z);
x = (short)(packedXYZ/0x10000);
y = (short)((packedXYZ/0x100)&0xFF);
z = (short)(packedXYZ&0xFF);
}
}
vertexData.flip();
VAOVertexHandle = GL30.glGenVertexArrays();
GL30.glBindVertexArray(VAOVertexHandle);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBOVertexHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexData, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_SHORT, false, 12, 0L);
GL20.glEnableVertexAttribArray(0);
GL20.glVertexAttribPointer(1, 3, GL11.GL_BYTE, false, 12, 6L);
GL20.glEnableVertexAttribArray(1);
GL20.glVertexAttribPointer(2, 3, GL11.GL_UNSIGNED_BYTE, false, 12, 9L);
GL20.glEnableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
}
Any help in direction would be much appreciated as I am completely at a loss of what to do now.
Thanks,
Lucas