0
votes

I am attempting to render a cube where each side is 64x64 faces (32*32 squares consisting of 2 triangles). Vertices are de-duplicated before mesh is sent to OpenGL.

I messed up something and I am getting some confusing results:

  1. Cube is transparent from outside only on negative positions relative to camera on x-axis.
  2. The vertical bars that makes it solid. What are they? I guess it is related to cube being made up of 32x32 rows of faces(x2).
  3. I have CullFace set to Back, but Cube is solid from inside (sides not culled). I would understand the issue if FrontFace Cw/Ccw was wrong compared to indices order, but either way works. I expect it to cull one of the sides.

Poking at it for hours has not made me less confused, so I am hoping someone can help.

enter image description here
Full video on YouTube.

#version 450 core

layout (location = 0) in mediump vec3 aPos;
layout (location = 1) in mediump vec3 aNormal;
layout (location = 2) in mediump vec2 aTexCoords;

out mediump vec3 vs_FragPos;
out mediump vec3 vs_Normal;
out mediump vec2 vs_Uv;
out mediump vec3 vs_LightPos;
out mediump vec3 vs_LightColor;

layout (location = 10) uniform  mat4 iProjection;
layout (location = 11) uniform  mat4 iView;
layout (location = 12) uniform  mat4 iModel;
layout (location = 20) uniform  vec3 lghtPos;
layout (location = 21) uniform  vec3 lightColor;

void main(void)
{
    gl_Position = iProjection * iView * iModel * vec4(aPos, 1.0);
    vs_FragPos = vec3(iProjection * vec4(aPos, 1.0));
    vs_Normal = aNormal;
    vs_Uv = aTexCoords;
    vs_LightPos = lghtPos;
    vs_LightColor = lightColor;
}
#version 450 core
in mediump vec3 vs_FragPos;
in mediump vec3 vs_Normal;
in mediump vec2 vs_Uv;
in mediump vec3 vs_LightPos;
in mediump vec3 vs_LightColor;
uniform sampler2D textureObject;

out mediump vec4 color;

float near = 0.1; 
float far  = 100.0; 

float LinearizeDepth(float depth) 
{
    float z = depth * 2.0 - 1.0; // back to NDC 
    return (2.0 * near * far) / (far + near - z * (far - near));    
}

void main(void)
{
    float depth = LinearizeDepth(gl_FragCoord.z) / far;
    color = vec4(vec3(depth), 1.0);
}

I am using these as basis for building the mesh, but each side face is repeated for every corresponding side. (C# language)

private static readonly Vector3[] _cubeVertices = new[]
{
    new Vector3(0, 0, 0), // 0
    new Vector3(1, 0, 0), // 1
    new Vector3(1, 1, 0), // 2
    new Vector3(0, 1, 0), // 3
    new Vector3(0, 1, 1), // 4
    new Vector3(1, 1, 1), // 5
    new Vector3(1, 0, 1), // 6
    new Vector3(0, 0, 1), // 7
};

private static readonly Vector3[] _cubeNormals = new[]
{
    Vector3Ex.Right, Vector3Ex.Left,
    Vector3Ex.Up, Vector3Ex.Down,
    Vector3Ex.Forward, Vector3Ex.Back
};
// For reference:
// Up = new Vector3(0F, 1F, 0F);
// Down = new Vector3(0F, -1F, 0F);
// Left = new Vector3(-1F, 0F, 0F);
// Right = new Vector3(1F, 0F, 0F);
// Forward = new Vector3(0F, 0F, 1F);
// Back = new Vector3(0F, 0F, -1F);

private static readonly int[] _cubeTriangles = new[]
{
    1, 2, 5, // East face
    1, 5, 6,
    0, 7, 4, // West face
    0, 4, 3,

    2, 3, 4, // Up face
    2, 4, 5,
    0, 6, 7, // Down face
    0, 1, 6,

    0, 2, 1, // South face
    0, 3, 2,
    5, 4, 7, // North face
    5, 7, 6,
};
2
may be z-buffer precision related too ... what are your znear,zfar parameters how many bits your depth buffer got and how big and far your cube is relative to camera ? try to increase znear if the result changes ... - Spektre

2 Answers

1
votes

I used RenderDoc to debug my application and found one entry I had overlooked. I am using NoesisGUI to render Xaml on top of the screen and it disabled cull face, depth test and set depth mask to false (as well as setting stencil buffer). Resetting these for every frame fixed the problem.

0
votes

At a glance, I would say that your triangle windings are not correct.

It seems that you are winding your triangles clockwise. This can happen with hand coded indexed meshes.

Reduce the scope of your application, and attempt to draw 2 triangles per face.

Front facing triangles should be wound anti(counter) clockwise, like so(reduced to a plane for simplicity):

private static readonly Vector3[] PlaneVertices = new[]
{
    new Vector3(0, 0, 0), // 0
    new Vector3(1, 0, 0), // 1
    new Vector3(1, 1, 0), // 2
    new Vector3(0, 1, 0), // 3
};

private static readonly int[] _cubeTriangles = new[]
{
    0, 1, 2,
    0, 2, 3
};

If you look at it visually:

3--------2
 |     /|
 |    / |
 |   /  |
 |  /   |
 | /    |
 |/     |
0--------1

If you repeat this pattern for each face of the cube, the hardware will generate the correct normals, and render correctly. See here for more information on culling and winding.

Additionally, as Spektre mentioned in his comment, check your Z-buffer values, and make sure there is enough precision there to handle all your geometry.