Rewrote vertex attribute cache.

This commit is contained in:
Leonardo Zide 2021-04-10 15:22:41 -07:00
parent b6acab713d
commit 278e953b81
2 changed files with 132 additions and 133 deletions

View file

@ -276,15 +276,15 @@ void lcContext::CreateShaderPrograms()
glAttachShader(Program, VertexShader); glAttachShader(Program, VertexShader);
glAttachShader(Program, FragmentShader); glAttachShader(Program, FragmentShader);
glBindAttribLocation(Program, LC_ATTRIB_POSITION, "VertexPosition"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::Position), "VertexPosition");
glBindAttribLocation(Program, LC_ATTRIB_NORMAL, "VertexNormal"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::Normal), "VertexNormal");
glBindAttribLocation(Program, LC_ATTRIB_TEXCOORD, "VertexTexCoord"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::TexCoord), "VertexTexCoord");
glBindAttribLocation(Program, LC_ATTRIB_COLOR, "VertexColor"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::Color), "VertexColor");
glBindAttribLocation(Program, 0, "VertexPosition1"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint1), "VertexPosition1");
glBindAttribLocation(Program, 1, "VertexPosition2"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint2), "VertexPosition2");
glBindAttribLocation(Program, 2, "VertexPosition3"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint3), "VertexPosition3");
glBindAttribLocation(Program, 3, "VertexPosition4"); glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint4), "VertexPosition4");
glLinkProgram(Program); glLinkProgram(Program);
@ -394,10 +394,15 @@ void lcContext::SetDefaultState()
if (gSupportsShaderObjects) if (gSupportsShaderObjects)
{ {
glEnableVertexAttribArray(LC_ATTRIB_POSITION); SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr);
glDisableVertexAttribArray(LC_ATTRIB_NORMAL); EnableVertexAttrib(lcProgramAttrib::Position);
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD);
glDisableVertexAttribArray(LC_ATTRIB_COLOR); 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 else
{ {
@ -411,13 +416,13 @@ void lcContext::SetDefaultState()
glNormalPointer(GL_BYTE, 0, nullptr); glNormalPointer(GL_BYTE, 0, nullptr);
glTexCoordPointer(2, GL_FLOAT, 0, nullptr); glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
glColorPointer(4, GL_FLOAT, 0, nullptr); glColorPointer(4, GL_FLOAT, 0, nullptr);
mNormalEnabled = false;
mTexCoordEnabled = false;
mColorEnabled = false;
#endif #endif
} }
mNormalEnabled = false;
mTexCoordEnabled = false;
mColorEnabled = false;
mVertexBufferObject = 0; mVertexBufferObject = 0;
mIndexBufferObject = 0; mIndexBufferObject = 0;
mVertexBufferPointer = nullptr; mVertexBufferPointer = nullptr;
@ -802,19 +807,14 @@ void lcContext::ClearVertexBuffer()
if (gSupportsShaderObjects) if (gSupportsShaderObjects)
{ {
if (mNormalEnabled) SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr);
glDisableVertexAttribArray(LC_ATTRIB_NORMAL);
if (mTexCoordEnabled) DisableVertexAttrib(lcProgramAttrib::Normal);
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD); SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, 0, nullptr);
DisableVertexAttrib(lcProgramAttrib::TexCoord);
if (mColorEnabled) SetVertexAttribPointer(lcProgramAttrib::TexCoord, 2, GL_FLOAT, false, 0, nullptr);
glDisableVertexAttribArray(LC_ATTRIB_COLOR); DisableVertexAttrib(lcProgramAttrib::Color);
SetVertexAttribPointer(lcProgramAttrib::Color, 4, GL_FLOAT, false, 0, nullptr);
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);
} }
else else
{ {
@ -869,36 +869,58 @@ void lcContext::SetVertexBufferPointer(const void* VertexBuffer)
mVertexBufferOffset = (char*)~0; mVertexBufferOffset = (char*)~0;
} }
void lcContext::SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer)
{
const int Index = static_cast<int>(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<int>(Attrib);
lcVertexAttribState& State = mVertexAttribState[Index];
if (!State.Enabled)
{
glEnableVertexAttribArray(Index);
State.Enabled = true;
}
}
void lcContext::DisableVertexAttrib(lcProgramAttrib Attrib)
{
const int Index = static_cast<int>(Attrib);
lcVertexAttribState& State = mVertexAttribState[Index];
if (State.Enabled)
{
glDisableVertexAttribArray(Index);
State.Enabled = false;
}
}
void lcContext::SetVertexFormatPosition(int PositionSize) void lcContext::SetVertexFormatPosition(int PositionSize)
{ {
const int VertexSize = PositionSize * sizeof(float); const int VertexSize = PositionSize * sizeof(float);
char* VertexBufferPointer = mVertexBufferPointer; const char* VertexBufferPointer = mVertexBufferPointer;
if (gSupportsShaderObjects) if (gSupportsShaderObjects)
{ {
if (mVertexBufferOffset != mVertexBufferPointer) SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
{ DisableVertexAttrib(lcProgramAttrib::Normal);
glVertexAttribPointer(LC_ATTRIB_POSITION, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); DisableVertexAttrib(lcProgramAttrib::TexCoord);
mVertexBufferOffset = VertexBufferPointer; DisableVertexAttrib(lcProgramAttrib::Color);
}
if (mNormalEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_NORMAL);
mNormalEnabled = false;
}
if (mTexCoordEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD);
mTexCoordEnabled = false;
}
if (mColorEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_COLOR);
mColorEnabled = false;
}
} }
else else
{ {
@ -931,106 +953,62 @@ void lcContext::SetVertexFormatPosition(int PositionSize)
void lcContext::SetVertexFormatConditional(int BufferOffset) void lcContext::SetVertexFormatConditional(int BufferOffset)
{ {
const int VertexSize = 12 * sizeof(float); const int VertexSize = 12 * sizeof(float);
char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset;
if (gSupportsShaderObjects) if (gSupportsShaderObjects)
{ {
if (mVertexBufferOffset != VertexBufferPointer) SetVertexAttribPointer(lcProgramAttrib::ControlPoint1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer);
{ EnableVertexAttrib(lcProgramAttrib::ControlPoint1);
glVertexAttribPointer(0, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer); SetVertexAttribPointer(lcProgramAttrib::ControlPoint2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float));
glVertexAttribPointer(1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float)); EnableVertexAttrib(lcProgramAttrib::ControlPoint2);
glVertexAttribPointer(2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float)); SetVertexAttribPointer(lcProgramAttrib::ControlPoint3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float));
glVertexAttribPointer(3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float)); EnableVertexAttrib(lcProgramAttrib::ControlPoint3);
SetVertexAttribPointer(lcProgramAttrib::ControlPoint4, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float));
mVertexBufferOffset = VertexBufferPointer; EnableVertexAttrib(lcProgramAttrib::ControlPoint4);
if (!mNormalEnabled)
{
glEnableVertexAttribArray(1);
mNormalEnabled = true; // todo: store state using an array
}
if (!mTexCoordEnabled)
{
glEnableVertexAttribArray(2);
mTexCoordEnabled = true;
}
if (!mColorEnabled)
{
glEnableVertexAttribArray(3);
mColorEnabled = true;
}
}
} }
} }
void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals) 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; const int VertexSize = (PositionSize + TexCoordSize) * sizeof(float) + NormalSize * sizeof(quint32) + ColorSize;
char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset;
if (gSupportsShaderObjects) if (gSupportsShaderObjects)
{ {
if (mVertexBufferOffset != VertexBufferPointer) int Offset = 0;
{
glVertexAttribPointer(LC_ATTRIB_POSITION, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
mVertexBufferOffset = VertexBufferPointer;
}
int Offset = PositionSize * sizeof(float); SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
EnableVertexAttrib(lcProgramAttrib::Position);
Offset += PositionSize * sizeof(float);
if (NormalSize && EnableNormals) if (NormalSize && EnableNormals)
{ {
glVertexAttribPointer(LC_ATTRIB_NORMAL, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset); SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset);
EnableVertexAttrib(lcProgramAttrib::Normal);
if (!mNormalEnabled)
{
glEnableVertexAttribArray(LC_ATTRIB_NORMAL);
mNormalEnabled = true;
}
}
else if (mNormalEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_NORMAL);
mNormalEnabled = false;
} }
else
DisableVertexAttrib(lcProgramAttrib::Normal);
Offset += NormalSize * sizeof(quint32); Offset += NormalSize * sizeof(quint32);
if (TexCoordSize) if (TexCoordSize)
{ {
glVertexAttribPointer(LC_ATTRIB_TEXCOORD, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset); SetVertexAttribPointer(lcProgramAttrib::TexCoord, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset);
EnableVertexAttrib(lcProgramAttrib::TexCoord);
if (!mTexCoordEnabled)
{
glEnableVertexAttribArray(LC_ATTRIB_TEXCOORD);
mTexCoordEnabled = true;
}
Offset += 2 * sizeof(float);
}
else if (mTexCoordEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD);
mTexCoordEnabled = false;
} }
else
DisableVertexAttrib(lcProgramAttrib::TexCoord);
Offset += TexCoordSize * sizeof(float);
if (ColorSize) if (ColorSize)
{ {
glVertexAttribPointer(LC_ATTRIB_COLOR, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset); SetVertexAttribPointer(lcProgramAttrib::Color, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset);
EnableVertexAttrib(lcProgramAttrib::Color);
if (!mColorEnabled)
{
glEnableVertexAttribArray(LC_ATTRIB_COLOR);
mColorEnabled = true;
}
}
else if (mColorEnabled)
{
glDisableVertexAttribArray(LC_ATTRIB_COLOR);
mColorEnabled = false;
} }
else
DisableVertexAttrib(lcProgramAttrib::Color);
} }
else else
{ {

View file

@ -58,12 +58,17 @@ enum class lcMaterialType
Count Count
}; };
enum lcProgramAttrib enum class lcProgramAttrib
{ {
LC_ATTRIB_POSITION, Position,
LC_ATTRIB_NORMAL, Normal,
LC_ATTRIB_TEXCOORD, TexCoord,
LC_ATTRIB_COLOR Color,
ControlPoint1 = 0,
ControlPoint2,
ControlPoint3,
ControlPoint4,
Count
}; };
struct lcProgram struct lcProgram
@ -90,6 +95,16 @@ enum class lcDepthFunction
Always 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 class lcContext : protected QOpenGLFunctions
{ {
public: public:
@ -206,20 +221,26 @@ protected:
void CreateShaderPrograms(); void CreateShaderPrograms();
void FlushState(); 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; QOpenGLWidget* mWidget = nullptr;
QOpenGLContext* mContext = nullptr; QOpenGLContext* mContext = nullptr;
GLuint mVertexBufferObject; GLuint mVertexBufferObject;
GLuint mIndexBufferObject; GLuint mIndexBufferObject;
char* mVertexBufferPointer; const char* mVertexBufferPointer;
char* mIndexBufferPointer; const char* mIndexBufferPointer;
char* mVertexBufferOffset; const char* mVertexBufferOffset;
lcMaterialType mMaterialType; lcMaterialType mMaterialType;
bool mNormalEnabled; bool mNormalEnabled;
bool mTexCoordEnabled; bool mTexCoordEnabled;
bool mColorEnabled; bool mColorEnabled;
lcVertexAttribState mVertexAttribState[static_cast<int>(lcProgramAttrib::Count)];
GLuint mTexture2D; GLuint mTexture2D;
GLuint mTextureCubeMap; GLuint mTextureCubeMap;
lcPolygonOffset mPolygonOffset; lcPolygonOffset mPolygonOffset;