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, 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<int>(lcProgramAttrib::Position), "VertexPosition");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::Normal), "VertexNormal");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::TexCoord), "VertexTexCoord");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::Color), "VertexColor");
glBindAttribLocation(Program, 0, "VertexPosition1");
glBindAttribLocation(Program, 1, "VertexPosition2");
glBindAttribLocation(Program, 2, "VertexPosition3");
glBindAttribLocation(Program, 3, "VertexPosition4");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint1), "VertexPosition1");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint2), "VertexPosition2");
glBindAttribLocation(Program, static_cast<int>(lcProgramAttrib::ControlPoint3), "VertexPosition3");
glBindAttribLocation(Program, static_cast<int>(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<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)
{
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
{

View file

@ -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<int>(lcProgramAttrib::Count)];
GLuint mTexture2D;
GLuint mTextureCubeMap;
lcPolygonOffset mPolygonOffset;