PDA

View Full Version : Strange culling behavior while drawing voxels



Oply1953
06-14-2015, 01:33 AM
I'm trying to draw a 12x12 voxel "world" but I'm getting unexpected (and quite ugly tbh) results.

I wrapped most of the OpenGL objects into classes so make my code a bit cleaner (and to not interfere with another library which also uses OpenGL), but the code's still self-explanatory and I didn't alter any behavior.

Here is the initialization code:

grass_texture = createTexture("grass_128x128.png"); //createTexture returns an OpenGL texture handle, one of the few things I didn't wrap yet
dirt_texture = createTexture("dirt_128x128.png");

vertex_vbo.data(sizeof(voxel_vertices), voxel_vertices, GL_STATIC_DRAW);
uv_vbo.data(sizeof(voxel_uvs), voxel_uvs, GL_STATIC_DRAW);

voxel_vao.enableAttrib(0);
voxel_vao.enableAttrib(1);
voxel_vao.vertexAttribPointer(vertex_vbo, 0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
voxel_vao.vertexAttribPointer(uv_vbo, 1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

GLShader vertex_shader(GL_VERTEX_SHADER), fragment_shader(GL_FRAGMENT_SHADER);
vertex_shader.source(loadFile("voxel.vert")); vertex_shader.compile();
fragment_shader.source(loadFile("voxel.frag")); fragment_shader.compile();
voxel_program.attach(vertex_shader);
voxel_program.attach(fragment_shader);
voxel_program.link();
voxel_program.detachAll();

The rendering code:

voxel_vao.bind();

glm::mat4 projection_matrix = camera.toTransformationMatrix(); //toTransformationMatrix returns, well, the transformation matrix of the camera

glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

glEnable(GL_CULL_FACE);

voxel_program.use();

for (unsigned x = 0; x < width; x++)
{
for (unsigned y = 0; y < height; y++)
{
for (unsigned z = 0; z < depth; z++)
{
glm::mat4 modelview_matrix(1.0f);
modelview_matrix = glm::translate(modelview_matrix, glm::vec3(x, y, z));

glm::mat4 MVP = projection_matrix * modelview_matrix;
glUniformMatrix4fv(voxel_program.getUniformLocatio n("MVP"), 1, GL_FALSE, glm::value_ptr(MVP));

int type = getBlock(x, y, z);

switch (type)
{
case 0:
glBindTexture(GL_TEXTURE_2D, grass_texture);
break;

case 1:
glBindTexture(GL_TEXTURE_2D, dirt_texture);
break;

default:
break;
}

glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
}

glBindVertexArray(0);

And the shader code:

voxel.frag
#version 330

out vec4 color;

in vec2 fragment_texcoord;

uniform sampler2D tex_sampler;

void main()
{
color = texture(tex_sampler, fragment_texcoord);
}
voxel.vert
#version 330

layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec2 vertex_texcoord;

out vec2 fragment_texcoord;

uniform mat4 MVP;

void main()
{
gl_Position.xyzw = MVP * vec4(vertex_position, 1);
fragment_texcoord = vertex_texcoord;
}

The vertices and uvs took too much space so I put them on pastebin: pastebin.com/43CjLHCA
Here's what it looks like from the front:
1868

From the back:
1869

And inside (looking towards the bottom-right corner):
1870

I've been trying to figure this out for a while now, but I can't seem to figure out what's wrong. Any input is appreciated!

Oply1953
06-14-2015, 09:29 AM
Ok, fixed it. Turns out the window manager I was using (SFML) created the window with a depth bit level of 0. Nothing was wrong with the OpenGL code.