patterncppModerate
OpenGL game engine
Viewed 0 times
enginegameopengl
Problem
I'm making a C++ game engine for entertainment and am using OpenGL to render my stuff. I made a batch renderer that was able to render 50K sprites with 300 FPS (untextured). My old setup that was able to run with 300 FPS was the following:
I had a class called
Basically, this was a class that held everything: the texture coordinates (if it had any), the color, position and size. My batch renderer had a method to draw any
```
void BatchRenderer::Submit(const Renderable2D& renderable)
{
const vec3f& position = renderable.GetPosition();
const vec2f& size = renderable.GetSize();
const unsigned int color = renderable.GetColor();
const std::vector& texCoords = renderable.GetTexCoords();
const GLuint tid = renderable.GetTextureID();
float ts = 0.0f;
if (tid > 0)
{
bool found = false;
for (unsigned int i = 0; i = 3
I had a class called
Renderable2D, which held everything:class Renderable2D
{
protected:
vec3f m_Position;
vec2f m_Size;
vec4f m_Color;
const Texture2D * m_Texture;
std::vector m_TexCoords;
protected:
Renderable2D() { }
public:
Renderable2D(vec3f position, vec2f size, vec4f color)
: m_Position(position), m_Size(size), m_Color(color), m_Texture(nullptr)
{
m_TexCoords.push_back(vec2f(0, 0));
m_TexCoords.push_back(vec2f(0, 1));
m_TexCoords.push_back(vec2f(1, 1));
m_TexCoords.push_back(vec2f(1, 0));
}
virtual ~Renderable2D()
{ }
inline virtual void Submit(Renderer2D * renderer) const
{
renderer->Submit(*this);
}
inline const vec3f& GetPosition() const { return m_Position; }
inline const vec2f& GetSize() const { return m_Size; }
inline const vec4f& GetColor() const { return m_Color; }
inline const std::vector& GetTexCoords() const { return m_TexCoords; }
inline const GLuint GetTextureID() const { return (m_Texture == nullptr ? 0 : m_Texture->GetTextureID()); }
};Basically, this was a class that held everything: the texture coordinates (if it had any), the color, position and size. My batch renderer had a method to draw any
Renderable2D based on this class:```
void BatchRenderer::Submit(const Renderable2D& renderable)
{
const vec3f& position = renderable.GetPosition();
const vec2f& size = renderable.GetSize();
const unsigned int color = renderable.GetColor();
const std::vector& texCoords = renderable.GetTexCoords();
const GLuint tid = renderable.GetTextureID();
float ts = 0.0f;
if (tid > 0)
{
bool found = false;
for (unsigned int i = 0; i = 3
Solution
A couple things I would have done differently, plus some other broader advices:
-
-
You don't need to add
-
Always favor the C++-style casts.
Two bits of personal style:
-
It is a common convention to name user defined types using
-
I find it better to place the public interface of a class first in the header file, to give it more emphasis. That's usually the part you and users of your code will be looking at more often. protected and private are implementation details, so shouldn't need to stand out as much.
-
Renderable2D seems to me is representing a single sprite, each sprite being a quadrilateral. In that case, you really don't need a variable amount of texture coordinates, but rather just 4. No need to use a std::vector in this case and force a heap allocation. Just use a plain array of vec2f or a std::array if you are open to using C++11.-
You don't need to add
inline when the method is defined directly inside the class body in the header file. That serves no practical purpose and only makes the code more verbose.-
Always favor the C++-style casts.
static_cast and friends will provide better compiler diagnostics if you attempt some unsafe cast.Two bits of personal style:
-
It is a common convention to name user defined types using
PascalCase, like you already do, and variables and functions with camelCase, to differentiate both kinds of things. Actually, the idea is to name anything that can have its memory address take with camelCase and reserve the first letter capitalized for types.-
I find it better to place the public interface of a class first in the header file, to give it more emphasis. That's usually the part you and users of your code will be looking at more often. protected and private are implementation details, so shouldn't need to stand out as much.
Context
StackExchange Code Review Q#96659, answer score: 12
Revisions (0)
No revisions yet.