From 278e953b819e0cf1e98f436369d438acda8e35bf Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sat, 10 Apr 2021 15:22:41 -0700 Subject: [PATCH] Rewrote vertex attribute cache. --- common/lc_context.cpp | 228 +++++++++++++++++++----------------------- common/lc_context.h | 37 +++++-- 2 files changed, 132 insertions(+), 133 deletions(-) diff --git a/common/lc_context.cpp b/common/lc_context.cpp index b1cbd7c7..dfa7653c 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -276,15 +276,15 @@ void lcContext::CreateShaderPrograms() glAttachShader(Program, VertexShader); glAttachShader(Program, FragmentShader); - glBindAttribLocation(Program, LC_ATTRIB_POSITION, "VertexPosition"); - glBindAttribLocation(Program, LC_ATTRIB_NORMAL, "VertexNormal"); - glBindAttribLocation(Program, LC_ATTRIB_TEXCOORD, "VertexTexCoord"); - glBindAttribLocation(Program, LC_ATTRIB_COLOR, "VertexColor"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::Position), "VertexPosition"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::Normal), "VertexNormal"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::TexCoord), "VertexTexCoord"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::Color), "VertexColor"); - glBindAttribLocation(Program, 0, "VertexPosition1"); - glBindAttribLocation(Program, 1, "VertexPosition2"); - glBindAttribLocation(Program, 2, "VertexPosition3"); - glBindAttribLocation(Program, 3, "VertexPosition4"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint1), "VertexPosition1"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint2), "VertexPosition2"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint3), "VertexPosition3"); + glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint4), "VertexPosition4"); glLinkProgram(Program); @@ -394,10 +394,15 @@ void lcContext::SetDefaultState() if (gSupportsShaderObjects) { - glEnableVertexAttribArray(LC_ATTRIB_POSITION); - glDisableVertexAttribArray(LC_ATTRIB_NORMAL); - glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD); - glDisableVertexAttribArray(LC_ATTRIB_COLOR); + SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr); + EnableVertexAttrib(lcProgramAttrib::Position); + + DisableVertexAttrib(lcProgramAttrib::Normal); + SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, 0, nullptr); + DisableVertexAttrib(lcProgramAttrib::TexCoord); + SetVertexAttribPointer(lcProgramAttrib::TexCoord, 2, GL_FLOAT, false, 0, nullptr); + DisableVertexAttrib(lcProgramAttrib::Color); + SetVertexAttribPointer(lcProgramAttrib::Color, 4, GL_FLOAT, false, 0, nullptr); } else { @@ -411,13 +416,13 @@ void lcContext::SetDefaultState() glNormalPointer(GL_BYTE, 0, nullptr); glTexCoordPointer(2, GL_FLOAT, 0, nullptr); glColorPointer(4, GL_FLOAT, 0, nullptr); + + mNormalEnabled = false; + mTexCoordEnabled = false; + mColorEnabled = false; #endif } - mNormalEnabled = false; - mTexCoordEnabled = false; - mColorEnabled = false; - mVertexBufferObject = 0; mIndexBufferObject = 0; mVertexBufferPointer = nullptr; @@ -802,19 +807,14 @@ void lcContext::ClearVertexBuffer() if (gSupportsShaderObjects) { - if (mNormalEnabled) - glDisableVertexAttribArray(LC_ATTRIB_NORMAL); + SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr); - if (mTexCoordEnabled) - glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD); - - if (mColorEnabled) - glDisableVertexAttribArray(LC_ATTRIB_COLOR); - - glVertexAttribPointer(LC_ATTRIB_POSITION, 3, GL_FLOAT, false, 0, nullptr); - glVertexAttribPointer(LC_ATTRIB_NORMAL, 4, GL_FLOAT, false, 0, nullptr); - glVertexAttribPointer(LC_ATTRIB_TEXCOORD, 2, GL_FLOAT, false, 0, nullptr); - glVertexAttribPointer(LC_ATTRIB_COLOR, 4, GL_FLOAT, false, 0, nullptr); + DisableVertexAttrib(lcProgramAttrib::Normal); + SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, 0, nullptr); + DisableVertexAttrib(lcProgramAttrib::TexCoord); + SetVertexAttribPointer(lcProgramAttrib::TexCoord, 2, GL_FLOAT, false, 0, nullptr); + DisableVertexAttrib(lcProgramAttrib::Color); + SetVertexAttribPointer(lcProgramAttrib::Color, 4, GL_FLOAT, false, 0, nullptr); } else { @@ -869,36 +869,58 @@ void lcContext::SetVertexBufferPointer(const void* VertexBuffer) mVertexBufferOffset = (char*)~0; } +void lcContext::SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer) +{ + const int Index = static_cast(Attrib); + lcVertexAttribState& State = mVertexAttribState[Index]; + + if (State.Size != Size || State.Type != Type || State.Normalized != Normalized || State.Stride != Stride || State.Pointer != Pointer) + { + glVertexAttribPointer(Index, Size, Type, Normalized, Stride, Pointer); + + State.Size = Size; + State.Type = Type; + State.Normalized = Normalized; + State.Stride = Stride; + State.Pointer = Pointer; + } +} + +void lcContext::EnableVertexAttrib(lcProgramAttrib Attrib) +{ + const int Index = static_cast(Attrib); + lcVertexAttribState& State = mVertexAttribState[Index]; + + if (!State.Enabled) + { + glEnableVertexAttribArray(Index); + State.Enabled = true; + } +} + +void lcContext::DisableVertexAttrib(lcProgramAttrib Attrib) +{ + const int Index = static_cast(Attrib); + lcVertexAttribState& State = mVertexAttribState[Index]; + + if (State.Enabled) + { + glDisableVertexAttribArray(Index); + State.Enabled = false; + } +} + void lcContext::SetVertexFormatPosition(int PositionSize) { const int VertexSize = PositionSize * sizeof(float); - char* VertexBufferPointer = mVertexBufferPointer; + const char* VertexBufferPointer = mVertexBufferPointer; if (gSupportsShaderObjects) { - if (mVertexBufferOffset != mVertexBufferPointer) - { - glVertexAttribPointer(LC_ATTRIB_POSITION, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); - mVertexBufferOffset = VertexBufferPointer; - } - - if (mNormalEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_NORMAL); - mNormalEnabled = false; - } - - if (mTexCoordEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD); - mTexCoordEnabled = false; - } - - if (mColorEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_COLOR); - mColorEnabled = false; - } + SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); + DisableVertexAttrib(lcProgramAttrib::Normal); + DisableVertexAttrib(lcProgramAttrib::TexCoord); + DisableVertexAttrib(lcProgramAttrib::Color); } else { @@ -931,106 +953,62 @@ void lcContext::SetVertexFormatPosition(int PositionSize) void lcContext::SetVertexFormatConditional(int BufferOffset) { const int VertexSize = 12 * sizeof(float); - char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; + const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; if (gSupportsShaderObjects) { - if (mVertexBufferOffset != VertexBufferPointer) - { - glVertexAttribPointer(0, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer); - glVertexAttribPointer(1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float)); - glVertexAttribPointer(2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float)); - glVertexAttribPointer(3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float)); - - mVertexBufferOffset = VertexBufferPointer; - - if (!mNormalEnabled) - { - glEnableVertexAttribArray(1); - mNormalEnabled = true; // todo: store state using an array - } - - if (!mTexCoordEnabled) - { - glEnableVertexAttribArray(2); - mTexCoordEnabled = true; - } - - if (!mColorEnabled) - { - glEnableVertexAttribArray(3); - mColorEnabled = true; - } - } + SetVertexAttribPointer(lcProgramAttrib::ControlPoint1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer); + EnableVertexAttrib(lcProgramAttrib::ControlPoint1); + SetVertexAttribPointer(lcProgramAttrib::ControlPoint2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float)); + EnableVertexAttrib(lcProgramAttrib::ControlPoint2); + SetVertexAttribPointer(lcProgramAttrib::ControlPoint3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float)); + EnableVertexAttrib(lcProgramAttrib::ControlPoint3); + SetVertexAttribPointer(lcProgramAttrib::ControlPoint4, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float)); + EnableVertexAttrib(lcProgramAttrib::ControlPoint4); } } void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals) { const int VertexSize = (PositionSize + TexCoordSize) * sizeof(float) + NormalSize * sizeof(quint32) + ColorSize; - char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; + const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; if (gSupportsShaderObjects) { - if (mVertexBufferOffset != VertexBufferPointer) - { - glVertexAttribPointer(LC_ATTRIB_POSITION, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); - mVertexBufferOffset = VertexBufferPointer; - } + int Offset = 0; - int Offset = PositionSize * sizeof(float); + SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); + EnableVertexAttrib(lcProgramAttrib::Position); + + Offset += PositionSize * sizeof(float); if (NormalSize && EnableNormals) { - glVertexAttribPointer(LC_ATTRIB_NORMAL, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset); - - if (!mNormalEnabled) - { - glEnableVertexAttribArray(LC_ATTRIB_NORMAL); - mNormalEnabled = true; - } - } - else if (mNormalEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_NORMAL); - mNormalEnabled = false; + SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset); + EnableVertexAttrib(lcProgramAttrib::Normal); } + else + DisableVertexAttrib(lcProgramAttrib::Normal); Offset += NormalSize * sizeof(quint32); if (TexCoordSize) { - glVertexAttribPointer(LC_ATTRIB_TEXCOORD, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset); - - if (!mTexCoordEnabled) - { - glEnableVertexAttribArray(LC_ATTRIB_TEXCOORD); - mTexCoordEnabled = true; - } - - Offset += 2 * sizeof(float); - } - else if (mTexCoordEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD); - mTexCoordEnabled = false; + SetVertexAttribPointer(lcProgramAttrib::TexCoord, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset); + EnableVertexAttrib(lcProgramAttrib::TexCoord); } + else + DisableVertexAttrib(lcProgramAttrib::TexCoord); + + Offset += TexCoordSize * sizeof(float); if (ColorSize) { - glVertexAttribPointer(LC_ATTRIB_COLOR, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset); - - if (!mColorEnabled) - { - glEnableVertexAttribArray(LC_ATTRIB_COLOR); - mColorEnabled = true; - } - } - else if (mColorEnabled) - { - glDisableVertexAttribArray(LC_ATTRIB_COLOR); - mColorEnabled = false; + SetVertexAttribPointer(lcProgramAttrib::Color, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset); + EnableVertexAttrib(lcProgramAttrib::Color); } + else + DisableVertexAttrib(lcProgramAttrib::Color); } else { diff --git a/common/lc_context.h b/common/lc_context.h index d2a6a4ff..a4309f85 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -58,12 +58,17 @@ enum class lcMaterialType Count }; -enum lcProgramAttrib +enum class lcProgramAttrib { - LC_ATTRIB_POSITION, - LC_ATTRIB_NORMAL, - LC_ATTRIB_TEXCOORD, - LC_ATTRIB_COLOR + Position, + Normal, + TexCoord, + Color, + ControlPoint1 = 0, + ControlPoint2, + ControlPoint3, + ControlPoint4, + Count }; struct lcProgram @@ -90,6 +95,16 @@ enum class lcDepthFunction Always }; +struct lcVertexAttribState +{ + GLint Size = 0; + GLenum Type = 0; + GLboolean Normalized = 0; + bool Enabled = 0; + GLsizei Stride = 0; + const void* Pointer = nullptr; +}; + class lcContext : protected QOpenGLFunctions { public: @@ -206,20 +221,26 @@ protected: void CreateShaderPrograms(); void FlushState(); + void SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer); + void EnableVertexAttrib(lcProgramAttrib Attrib); + void DisableVertexAttrib(lcProgramAttrib Attrib); + QOpenGLWidget* mWidget = nullptr; QOpenGLContext* mContext = nullptr; GLuint mVertexBufferObject; GLuint mIndexBufferObject; - char* mVertexBufferPointer; - char* mIndexBufferPointer; - char* mVertexBufferOffset; + const char* mVertexBufferPointer; + const char* mIndexBufferPointer; + const char* mVertexBufferOffset; lcMaterialType mMaterialType; bool mNormalEnabled; bool mTexCoordEnabled; bool mColorEnabled; + lcVertexAttribState mVertexAttribState[static_cast(lcProgramAttrib::Count)]; + GLuint mTexture2D; GLuint mTextureCubeMap; lcPolygonOffset mPolygonOffset;