Advertisement Jump to content
Sign in to follow this  
Irlan Robson

OpenGL Need a design advice on a Mesh Class

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

The OpenGL Context that I'm coding it's instance based, so owns OpenGL Objects (shaders, programs, textures).

I think that the code it's very redundant since the context creates the Mesh Buffer.

In that case why I can't store the Mesh in a Struct and just call Mesh.buffer = GLContext.CreateBuffer?

 

My Mesh class follows:

 

class Mesh {

public:

std::vector<Vertex> vertex;

std::vector<unsigned int> index;

GraphicsBuffer* buffer; //a wrapper for GL vertex/index buffers

 

void CreateBuffer(GLContext& context) //looks like DX methods for creating Vertex/Index Buffer

{

  buffer = context.CreateBuffer(*this);

}

 

};

 

I know that this violates the OOP but it's very very redundant.

Edited by irlanrobson

Share this post


Link to post
Share on other sites
Advertisement

If Context::CreateBuffer calls Mesh::CreateBuffer you have an infinite loop. This is in my opinion the main reason to avoid doing that.

Share this post


Link to post
Share on other sites

If Context::CreateBuffer calls Mesh::CreateBuffer you have an infinite loop. This is in my opinion the main reason to avoid doing that.

The GLContext returns a MeshBuffer* which is stored in a std::vector<MeshBuffer*> inside the context.

Edited by irlanrobson

Share this post


Link to post
Share on other sites

I’ve already covered this in detail.

 

A mesh does not manage an OpenGL object of any kind directly.

A vertex buffer class manages an OpenGL VBO.

An index buffer class manages an OpenGL IBO.

 

A mesh brings these 2 things together without knowing what OpenGL is.

 

 

Your suggestion is severely flawed in that the mesh knows what a context is and the context knows what a mesh is.

The context should have absolutely no idea what a mesh is.

Vertex buffers and index buffers live inside the graphics module, but meshes and models live above that.

A mesh knows what graphics are, not the other way around.

Let the mesh make its own vertices and indices via the CVertexBuffer and CIndexBuffer classes that wrap around GLuint VBO/IBO ID’s.

 

 

L. Spiro

Share this post


Link to post
Share on other sites

I’ve already covered this in detail.

 

A mesh does not manage an OpenGL object of any kind directly.

A vertex buffer class manages an OpenGL VBO.

An index buffer class manages an OpenGL IBO.

 

A mesh brings these 2 things together without knowing what OpenGL is.

 

 

Your suggestion is severely flawed in that the mesh knows what a context is and the context knows what a mesh is.

The context should have absolutely no idea what a mesh is.

Vertex buffers and index buffers live inside the graphics module, but meshes and models live above that.

A mesh knows what graphics are, not the other way around.

Let the mesh make its own vertices and indices via the CVertexBuffer and CIndexBuffer classes that wrap around GLuint VBO/IBO ID’s.

 

 

L. Spiro

 

Always helpful LS.Spiro. Now becomes:

class VertexBuffer; 
class IndexBuffer; 

//Mesh.h 
class Mesh { //the context manages the buffers 
public: 
Mesh() : vbuffer(0), ibuffer(0) 
{ 
} 
void GenBuffers(GLContext& context) //inside cpp file 
{ 
context.GenVertexBuffer(vertex, vbuffer); 
context.GenIndexBuffer(index, ibuffer); 
} 
void DrawBuffers(GLContext& context) //inside cpp file 
{ 
context.DrawBuffersIndexed(vbuffer, ibuffer, index.size()); //index count 
} 

private: 
std::vector<Vertex> vertex; 
std::vector<unsigned int> index; 
VertexBuffer* vbuffer; 
IndexBuffer* ibuffer; 
}; 

struct VertexBuffer { 
GLuint vbo; 
}; 
struct IndexBuffer { 
GLuint ibo; 
};
Edited by irlanrobson

Share this post


Link to post
Share on other sites

I’ve already covered this in detail.

 

A mesh does not manage an OpenGL object of any kind directly.

A vertex buffer class manages an OpenGL VBO.

An index buffer class manages an OpenGL IBO.

 

A mesh brings these 2 things together without knowing what OpenGL is.

 

 

Your suggestion is severely flawed in that the mesh knows what a context is and the context knows what a mesh is.

The context should have absolutely no idea what a mesh is.

Vertex buffers and index buffers live inside the graphics module, but meshes and models live above that.

A mesh knows what graphics are, not the other way around.

Let the mesh make its own vertices and indices via the CVertexBuffer and CIndexBuffer classes that wrap around GLuint VBO/IBO ID’s.

 

 

L. Spiro

 
I'm confused with one thing. In the post you made you said that VertexBuffer has vertex data and a VBO.
If a physics system needs to acess vertex data for compute AABBs (eg.) it will via vertex buffer and not the mesh itself?
I understand that that vertex data type it's a very specific thing for the graphics context, but the physics system will not have acess to vertex data until the buffer is created in that case.
 
One more thing. In the old topic you said that the only thing a VB has is vertex data and shouldn't be hardcoded. That makes sense but my point of view is:
 
If a VertexBuffer is suposed to have positions, normals, binormals and texture coordinates. The class should be the following:
 
class VertexBuffer {
(...) //vao, vbo etc...

std::vector<Vector3> position;
std::vector<Vector3> uv;
std::vector<Vector3> normal;
std::vector<Vector3> binormal;
};

or better:

class BaseVertex {
public:
position;
uv;
normal;
};

class OtherVertex : public BaseVertex {
public:
binormal;
tangent;
};
Edited by irlanrobson

Share this post


Link to post
Share on other sites
Currently I don’t have time to respond in full to all points that need to be addressed, but the 2 major issues can be addressed briefly.
 
#1:

If a physics system needs to acess vertex data for compute AABBs (eg.) it will via vertex buffer and not the mesh itself?

The AABB will have already been computed offline during the creation of your custom model format. It has nothing to do with vertex buffers. Again, vertex buffers are related to graphics and graphics only, no other sub-system. If any other sub-system is involved, a local CPU copy of the vertices is used, not a vertex buffer.

#2:

If a VertexBuffer is suposed to have positions, normals, binormals and texture coordinates. The class should be the following:

And what about all the 2D HUD elements that have only a position and UV?
Any combination of any set of attributes can be used to create a vertex buffer. That is why we never use structures to create vertex buffer elements. Your wrapper should work the way graphics API’s work. Let the user decide what is inside the vertex buffer and at what offsets, and give them a structure to fill out that you can translate into something your graphics API can use.


L. Spiro Edited by L. Spiro

Share this post


Link to post
Share on other sites

Currently I don’t have time to respond in full to all points that need to be addressed, but the 2 major issues can be addressed briefly.
 
#1:

If a physics system needs to acess vertex data for compute AABBs (eg.) it will via vertex buffer and not the mesh itself?

The AABB will have already been computed offline during the creation of your custom model format. It has nothing to do with vertex buffers. Again, vertex buffers are related to graphics and graphics only, no other sub-system. If any other sub-system is involved, a local CPU copy of the vertices is used, not a vertex buffer.

#2:

If a VertexBuffer is suposed to have positions, normals, binormals and texture coordinates. The class should be the following:

And what about all the 2D HUD elements that have only a position and UV?
Any combination of any set of attributes can be used to create a vertex buffer. That is why we never use structures to create vertex buffer elements. Your wrapper should work the way graphics API’s work. Let the user decide what is inside the vertex buffer and at what offsets, and give them a structure to fill out that you can translate into something your graphics API can use.


L. Spiro

 

1# Understood. I'll use a copy of the vertex data.
2# This approach looks similar of a Vertex Layout (used in DX11). So I'm emulating DirectX 11 in OpenGL. I'll create a Vertex Layout structure and pass to the vertex buffer creation.

Share this post


Link to post
Share on other sites

Currently I don’t have time to respond in full to all points that need to be addressed, but the 2 major issues can be addressed briefly.
 
#1:

If a physics system needs to acess vertex data for compute AABBs (eg.) it will via vertex buffer and not the mesh itself?

The AABB will have already been computed offline during the creation of your custom model format. It has nothing to do with vertex buffers. Again, vertex buffers are related to graphics and graphics only, no other sub-system. If any other sub-system is involved, a local CPU copy of the vertices is used, not a vertex buffer.

#2:

If a VertexBuffer is suposed to have positions, normals, binormals and texture coordinates. The class should be the following:

And what about all the 2D HUD elements that have only a position and UV?
Any combination of any set of attributes can be used to create a vertex buffer. That is why we never use structures to create vertex buffer elements. Your wrapper should work the way graphics API’s work. Let the user decide what is inside the vertex buffer and at what offsets, and give them a structure to fill out that you can translate into something your graphics API can use.


L. Spiro

 

 
That's my perspective:
 
struct VertexInfo {
GLuint index;
GLint size;
(...) pointer to data etc...
};


mesh.CreateVertexBuffer(ContextGL& context)
{
VertexAttribute vinfo;
(...) fill info
context.CreateVertexBuffer(vbuffer, vinfo);
}

Share this post


Link to post
Share on other sites
You are getting closer, but one of the things I wanted to say that I didn’t have time to say before is in regards to passing an OpenGL context around all the time.

Are you going to call ::wglMakeCurrent() (or similar) on every single OpenGL call? That is the only reason the vertex buffer would need you to pass a context into it; it is the only relevant function that can be called related to the context. If that is how you want to emulate object-oriented programming, you would be calling ::wglMakeCurrent() for every single call, including ::glEnable() etc.

Why do you need more than one context anyway? Even if you have multiple “renderer” instances a single context is enough. You don’t need more than one context to do object-oriented OpenGL programming, and even if you did the object you would be passing around would be some kind of more-generalized class such as “Renderer” or something above and beyond “ContextGL”.


L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

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!