dreadiscool
dreadiscool

Reputation: 1598

OpenGL Quad Visible on Both Sides?

I've just started learning OpenGL, and came across an interesting bug (that's probably through my wrongdoing)

However, I can't seem to figure out why my faces are being drawn by default on both sides, rather than one. Here are a few screenshots describing the problem

enter image description here

enter image description here

When I go ahead and enable GL_CULL_FACE (because apparently it isn't enabled by default, as it should be), my quads get rendered, but all on the wrong side. Is this due to a way I'm calculating normals?

Here is my code for calculating a normal

public static Point3D calculateNormals(Point3D p1, Point3D p2, Point3D p3) {
    Point3D v1 = new Point3D(p2.getX() - p1.getX(), p2.getY() - p1.getY(), p2.getZ() - p1.getZ());
    Point3D v2 = new Point3D(p3.getX() - p1.getX(), p3.getY() - p1.getY(), p3.getZ() - p1.getZ());
    Point3D normal = new Point3D();
    normal.addX((v1.getY() * v2.getZ()) - (v1.getZ() - v2.getY()));
    normal.addY((v2.getZ() * v1.getX()) - (v2.getX() * v1.getZ()));
    normal.addZ((v1.getX() - v2.getY()) - (v1.getY() - v2.getX()));
    return normal;
}

Note: Creating a Point3D with no arguments results in x, y, and z all being set to 0, hence why addX, andY, and addZ can be used.

Should I flip my normal calculations?

Upvotes: 2

Views: 4203

Answers (2)

Joehot200
Joehot200

Reputation: 1090

GL_CULL_FACE(GL_BACK) will cull out the back face of an object. Before doing that, remember to glEnable(GL_CULL_FACE). You can re-enable and disable culling at any time. Sometimes its important to render both sides (e.g. a sail on a ship).

Upvotes: 2

derhass
derhass

Reputation: 45362

When I go ahead and enable GL_CULL_FACE (because apparently it isn't enabled by default, as it should be)

What do you mean? GL_CULL_FACE is disabled by default, as dictated by the spec.

The decision what is the front face and what is the back face is completely indepentent of the normal you use, GL uses the winding order of the primitive (defined by the order of the vertices you specify). By default, a face is considered the front face if its vertices (in screen space) are oriented in counter-clockwise.

You can either reorient your faces by flipping the winding of every primitive, or you can use glFrontFace() to change GL's order rule from GL_CCW to GL_CW (clockwise), or you could even use glCullFace() to tell OpenGL that you want to cull front faces instead of back faces.

No matter what option you choose, I would advise you that you make sure that you make sure that the winding order of all objects in your scene is consistent. It is in principle possible to switch the oders for each draw call, but you should avoid that if it is not absolutely necessary.

Upvotes: 6

Related Questions