# OpenGL Efficient way of computing faces of axially-aligned box

This topic is 2113 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Just found these forums and they look like they'd be pretty helpful for me. I'm semi-experienced in programming but fairly new to graphics specifically, so questions might seem basic while I'm getting to grips with some things.

I'm attempting to implement a primitive axially-aligned box renderable for a level editor written in Qt (C++). I'm using the Qt3D library and am intending to ensure that each renderable implements a render interface, which at the moment consists just of:

// Export to QGeometryData, in world co-ordinates.
virtual QGeometryData toGeomData() const = 0;


The QGeometryData is a Qt3D manager for vertex data. My box renderable's function looks like this:

QGeometryData RenderBox::toGeomData() const
{
// Calculate the min and max co-ordinates in world space.
QVector3D min = m_vecPosition + minimum();
QVector3D max = m_vecPosition + maximum();
QColor col = color();

// Order of vertices:
// 0. Minimum
// 1. Minimum with modified X co-ord
// 2. Minimum with modified X and Z co-ords
// 3. Minimum with modified Z co-ord
// 4. Maximum with modified Z co-ord
// 5. Maximum with modified Z and X co-ords
// 6. Maximum with modified X co-ord
// 7. Maximum
// This gives us an easy counter-clockwise winding for the top and bottom faces.

const QVector3D verts[8] =               // Taking Z as "north" and looking down on the box (Y pointing at us), we have:
{
min,                                    // Lower SW 0
QVector3D(max.x(), min.y(), min.z()),   // Lower NW 1
QVector3D(max.x(), min.y(), max.z()),   // Lower NE 2
QVector3D(min.x(), min.y(), max.z()),   // Lower SE 3
QVector3D(max.x(), max.y(), min.z()),   // Upper NW 4
QVector3D(min.x(), max.y(), min.z()),   // Upper SW 5
QVector3D(min.x(), max.y(), max.z()),   // Upper SE 6
max                                     // Upper NE 7
};

// Calculate normals for faces.
QVector3D nTop = ccwNormal(verts[5], verts[6], verts[7]);       // SW, SE, NE
QVector3D nBottom = ccwNormal(verts[0], verts[1], verts[2]);    // SW, NW, NE
QVector3D nNorth = ccwNormal(verts[7], verts[2], verts[1]);     // UNE, LNE, LNW
QVector3D nSouth = ccwNormal(verts[0], verts[3], verts[6]);     // LSW, LSE, USE
QVector3D nEast = ccwNormal(verts[7], verts[6], verts[3]);      // UNE, USE, LSE
QVector3D nWest = ccwNormal(verts[0], verts[5], verts[4]);      // LSW, USW, UNW

// Create a GeomData and add each face of the box.
QGeometryData geom;

// Top face
geom.appendVertex(verts[4], verts[5], verts[6], verts[7]);
geom.appendNormal(nTop, nTop, nTop, nTop);

// Bottom face
geom.appendVertex(verts[0], verts[1], verts[2], verts[3]);
geom.appendNormal(nBottom, nBottom, nBottom, nBottom);

// North face
geom.appendVertex(verts[7], verts[2], verts[1], verts[4]);
geom.appendNormal(nNorth, nNorth, nNorth, nNorth);

// South face
geom.appendVertex(verts[0], verts[3], verts[6], verts[5]);
geom.appendNormal(nSouth, nSouth, nSouth, nSouth);

// East face
geom.appendVertex(verts[7], verts[6], verts[3], verts[2]);
geom.appendNormal(nEast, nEast, nEast, nEast);

// West face
geom.appendVertex(verts[0], verts[5], verts[4], verts[1]);
geom.appendNormal(nWest, nWest, nWest, nWest);

// Append colour attributes.
// These will all be the same.
for ( int i = 0; i < 24; i++ )
{
geom.appendColor(col);
}

// Return the GeomData.
return geom;
}


ccwNormal() is a simple helper function that returns the normal (pointing towards the viewer) of three vectors assumed to be supplied in an anticlockwise winding order.

My question here is whether there is a more efficient/elegant way of calculating the faces of the box. Theoretically (if I've done the calculations right) this way should provide the correct vertex information, but it seems inflexible from a distance and looks like it'd be a pain to modify later on if I needed to. How acceptable is this method?

(Also, an implementation-specific question for those familiar with Qt/OpenGL: is returning a QGeometryData object the best way to implement rendering? My concerns with it are twofold: firstly, copying data from geom on the stack to the returned object might cause unnecessary overhead, especially considering that this would have to be done for every single renderable, and secondly returning a fresh object every time toGeomData() is called would be a waste of time if the render data was exactly the same as the previous frame. According to the documentation for QGeometryData the graphics data is not re-uploaded to the GPU if it hasn't changed, but if the object is being replaced by a new one each frame then it might prevent this optimisation from happening.)

##### Share on other sites

If the box is axis aligned, why calc normals at all? The face normal will be the axis it points down. Skip the normal calc calls, which will probably save 6 sqrt()'s.

##### Share on other sites

That's a very good point, actually. I guess I'm a bit blind to my own code. :P

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 13
• 18
• 15
• 11
• 9
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!