I'm making a custom engine, and after much research, I realized that the state changes and the vertex or texture data loadings to VRAM are the most slow operations.
So I want to optimize it making a wrapper between OpenGL and a rendering engine that has a set of functions like OpenGL's, but making it like it saves the calls in arrays. After the "pre-rendering" phase, it schedules all operations, when possible, to make the state changes of GPU less frequent. Next, the scheduler groups vertices to make contiguous packs of vertices, when possible, and render it all, together.
Example of interface
class Renderer
{
typedef int Texture; // TMP
class State
{ public:
Vertex * Start;
Vertex * End;
};
class SOC : public State
{ public:
Shader * Reference;
// End Null if update
};
class EOC : public State
{ public:
GLenum * Reference;
Vertex * Start;
Vertex * End;
};
class FOC : public State
{ public:
FrameBuffer * Reference;
// End Null if draw
};
public:
// Rendering api
//-------------------------------------------------
static void End();
static void Begin(GLenum);
static void Enable(GLenum);
static void Disable(GLenum);
static void BlendMode(GLenum, GLenum);
static void BindShader(Shader *);
static void UnbindShader(Shader *);
static void UpdateShader(Shader *);
static void SamplingType(GLenum, GLenum, GLenum);
static void DrawFrameBuffer(FrameBuffer *);
static void BindFrameBuffer(FrameBuffer *);
static void UnbindFrameBuffer(FrameBuffer *);
static void Vertex2(int, int);
static void Vertex2(float, float);
static void Vertex2(int, int, Color);
static void Vertex2(float, float, Color);
static void Vertex2(int, int, Texture);
static void Vertex2(float, float, Texture);
static void Vertex2(int, int, Color, Texture);
static void Vertex2(float, float, Color, Texture);
//-------------------------------------------------
// Rendering phases
//-------------------------------------------------
static void Initialize(); // 0
static void PreparePipeline(); // 1
static void Schedule(); // 2
static void StartRenderPipeline(); // 3
static void RestorePipeline(); // (0.5)
//-------------------------------------------------
private:
// Rendering source
//-------------------------------------------------
static Vertex * GlobalVertexBuffer;
static std::vector<SOC> ShaderStates;
static std::vector<EOC> EnableStates;
static std::vector<FOC> FBOStates;
//-------------------------------------------------
// Handlers openGL
//-------------------------------------------------
static GLuint StreamVertexBuffer;
static GLuint Index;
//-------------------------------------------------
// Current state
//--------------------------------------------------------------
static std::unordered_map<GLenum, bool> ActiveFlags;
static std::unordered_map<Shader *, bool> ActiveShaders;
static std::unordered_map<VertexBuffer *, bool> ActiveVBOS;
static GLenum CurrentPrimitive;
Is this scheduling operation a slowdown for the CPU, or is it a benefit?