Hi Thomas,
many thanks for your detailed post! I've looked at your code, and I have a number of questions:
About the renderers being independent:
Well, sure, but they are still allowed to (re-)use anything in
Libs/or
ExtLibs/, because the code in there is supposed to be "generic", and is not part of the engine. Said differently, what makes you think that OpenGLEx and OpenGLState are part of the engine? (they aren't)
Using GL3W for now is ok, but as GLEW could also be used for the old OpenGL "below 3.0" renderers. I might soon try to switch some of them to GLEW, or at least test if that is reasonably possible.
UnivMeshT
seems to have no
TypeT
member? (Points, Lines, LineStrip, LineLoop, Triangles, ...)
Why do we need methods
Init()
and
Update()
in the public portion of
UnivMeshT
?
Can't we just hide them in the implementation, e.g. have the implementation check on first use (in
Render()
) if the mesh has been inited already, and if not, do so?
Your explanations about channels made me wonder if we can move away from the horrible
VertexT
struct in the meshes. Instead, we could have one separate
ArrayT<...>
for each channel. The user would use it like this:
Code: Select all
for all my vertices
{
// VertexNr is the index number of the current vertex.
my_mesh->SetOrigin(VertexNr, Origin);
my_mesh->SetColor(VertexNr, r, g, b);
...
}
Here is some pseudo could that outlines the general idea:
Code: Select all
// This is PSEUDO-code: Not tested, not compiled.
namespace MatSys
{
// A suggestion for a UnivMeshT class design.
// The key idea is that the user must specify a "proper" mesh:
// If he wants to use colors, he has to make sure that there are as many colors are there are origins;
// if he wants to use uv's, he has to make sure that there are as many us-pairs are there are origins;
// etc.
// The implementation derives everything else automatically.
class UnivMeshT
{
public:
enum TypeT { Points, Lines, LineStrip, LineLoop, Triangles, TriangleStrip, TriangleFan, Quads, QuadStrip, Polygon };
enum WindingT { CW, CCW };
typedef float Vec2T[2];
typedef float Vec4T[4];
/// Constructor.
UnivMeshT(TypeT T, WindingT W=CW);
void SetOrigin(unsigned int VertexNr, const Vector3fT& pos, float w=1.0f);
void SetColor(unsigned int VertexNr, const Vector3fT& col);
// ...
private:
const TypeT m_Type;
const WindingT m_Winding; ///< The orientation (cw or ccw) of front faces.
bool m_IsInited;
bool m_IsModified;
ArrayT<Vec4T> m_Origins;
ArrayT<Vector3fT> m_Colors;
ArrayT<Vec2T> m_TexCoords;
ArrayT<Vec2T> m_LM_Coords;
ArrayT<Vec2T> m_SHL_Coords;
ArrayT<Vector3fT> m_Normals;
ArrayT<Vector3fT> m_Tangents;
ArrayT<Vector3fT> m_BiNormals;
};
}
void MatSys::UnivMeshT::UnivMeshT(TypeT T, WindingT W)
: m_Type(T),
m_Winding(W),
m_IsInited(false),
m_IsModified(true)
{
}
void MatSys::UnivMeshT::SetColor(unsigned int VertexNr, const Vector3fT& col)
{
if (VertexNr >= m_Colors.Size())
m_Colors.PushBackEmpty(VertexNr+1-m_Colors.Size());
m_Colors[VertexNr]=col;
m_IsModified=true;
}
void MatSys::UnivMeshT::Render()
{
if (!m_IsInited)
{
if (m_Colors.Size() == m_Origins.Size())
{
// This mesh requires the "colors" channel!
}
m_IsInited=true;
}
// ... do the actual render work
}
Do you think this would work (with the GL3+ renderers)?
This would also allow us to not need the
AttributeT
enum.
Btw., I'd prefer to work with SVN
patches -- at least when many small edits to existing files are concerned.
Creating them is really simple (do you know / can you use TortoiseSVN?), and they
really help reducing the confusion of manually typed "in x find y, then change to z" instructions, because it's unambiguously clear to the receiving person how to understand them. They also help to keep related things together, rather scattering them in random bits of text that are
really hard to reproduce locally.