Context state cleanup.

This commit is contained in:
Leonardo Zide 2017-03-25 12:29:28 -07:00
parent 155fa7cdc2
commit 57b8732ed6
13 changed files with 107 additions and 136 deletions

View file

@ -92,6 +92,7 @@ lcContext::lcContext()
mLineWidth = 1.0f;
#ifndef LC_OPENGLES
mMatrixMode = GL_MODELVIEW;
mTextureEnabled = false;
#endif
mFramebufferObject = 0;
@ -441,8 +442,8 @@ void lcContext::SetDefaultState()
mIndexBufferPointer = NULL;
mVertexBufferOffset = (char*)~0;
glDisable(GL_TEXTURE_2D);
mTexture = NULL;
glBindTexture(GL_TEXTURE_2D, 0);
mTexture = 0;
glLineWidth(1.0f);
mLineWidth = 1.0f;
@ -458,10 +459,20 @@ void lcContext::SetDefaultState()
glMatrixMode(GL_MODELVIEW);
mMatrixMode = GL_MODELVIEW;
glShadeModel(GL_FLAT);
glDisable(GL_TEXTURE_2D);
mTextureEnabled = false;
#endif
}
}
void lcContext::ClearResources()
{
ClearVertexBuffer();
ClearIndexBuffer();
SetTexture(0);
}
void lcContext::SetMaterial(lcMaterialType MaterialType)
{
if (MaterialType == mMaterialType)
@ -483,16 +494,35 @@ void lcContext::SetMaterial(lcMaterialType MaterialType)
{
case LC_MATERIAL_UNLIT_TEXTURE_MODULATE:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (!mTextureEnabled)
{
glEnable(GL_TEXTURE_2D);
mTextureEnabled = true;
}
break;
case LC_MATERIAL_FAKELIT_TEXTURE_DECAL:
case LC_MATERIAL_UNLIT_TEXTURE_DECAL:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
if (!mTextureEnabled)
{
glEnable(GL_TEXTURE_2D);
mTextureEnabled = true;
}
break;
case LC_MATERIAL_UNLIT_COLOR:
case LC_MATERIAL_UNLIT_VERTEX_COLOR:
case LC_MATERIAL_FAKELIT_COLOR:
if (mTextureEnabled)
{
glDisable(GL_TEXTURE_2D);
mTextureEnabled = false;
}
break;
case LC_NUM_MATERIALS:
break;
}
@ -514,6 +544,15 @@ void lcContext::SetLineWidth(float LineWidth)
mLineWidth = LineWidth;
}
void lcContext::SetTexture(GLuint Texture)
{
if (mTexture == Texture)
return;
glBindTexture(GL_TEXTURE_2D, Texture);
mTexture = Texture;
}
void lcContext::SetColor(float Red, float Green, float Blue, float Alpha)
{
SetColor(lcVector4(Red, Green, Blue, Alpha));
@ -549,7 +588,7 @@ bool lcContext::BeginRenderToTexture(int Width, int Height)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferObject);
glBindTexture(GL_TEXTURE_2D, mFramebufferTexture);
SetTexture(mFramebufferTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFramebufferTexture, 0);
@ -558,7 +597,7 @@ bool lcContext::BeginRenderToTexture(int Width, int Height)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, Width, Height);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbufferObject);
glBindTexture(GL_TEXTURE_2D, 0);
SetTexture(0);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObject);
if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
@ -576,7 +615,7 @@ bool lcContext::BeginRenderToTexture(int Width, int Height)
glGenFramebuffersEXT(1, &mFramebufferObject);
glGenTextures(1, &mFramebufferTexture);
glBindTexture(GL_TEXTURE_2D, mFramebufferTexture);
SetTexture(mFramebufferTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@ -591,7 +630,7 @@ bool lcContext::BeginRenderToTexture(int Width, int Height)
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthRenderbufferObject);
glBindTexture(GL_TEXTURE_2D, 0);
SetTexture(0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebufferObject);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
@ -786,14 +825,38 @@ void lcContext::ClearVertexBuffer()
mVertexBufferObject = 0;
}
if (mNormalEnabled)
glDisableClientState(GL_NORMAL_ARRAY);
if (gSupportsShaderObjects)
{
if (mNormalEnabled)
glDisableVertexAttribArray(LC_ATTRIB_NORMAL);
if (mTexCoordEnabled)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (mTexCoordEnabled)
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD);
if (mColorEnabled)
glDisableClientState(GL_COLOR_ARRAY);
if (mColorEnabled)
glDisableVertexAttribArray(LC_ATTRIB_COLOR);
glVertexAttribPointer(LC_ATTRIB_POSITION, 3, GL_FLOAT, false, 0, NULL);
glVertexAttribPointer(LC_ATTRIB_NORMAL, 4, GL_FLOAT, false, 0, NULL);
glVertexAttribPointer(LC_ATTRIB_TEXCOORD, 2, GL_FLOAT, false, 0, NULL);
glVertexAttribPointer(LC_ATTRIB_COLOR, 4, GL_FLOAT, false, 0, NULL);
}
else
{
if (mNormalEnabled)
glDisableClientState(GL_NORMAL_ARRAY);
if (mTexCoordEnabled)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (mColorEnabled)
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, NULL);
glNormalPointer(GL_BYTE, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glColorPointer(4, GL_FLOAT, 0, NULL);
}
}
void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer)
@ -1102,44 +1165,6 @@ void lcContext::BindMesh(lcMesh* Mesh)
}
}
void lcContext::UnbindMesh()
{
if (mTexture)
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
mTexture = NULL;
}
if (gSupportsVertexBufferObject)
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
mVertexBufferObject = 0;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
mIndexBufferObject = 0;
}
mVertexBufferPointer = NULL;
mIndexBufferPointer = NULL;
if (gSupportsShaderObjects)
{
glDisableVertexAttribArray(LC_ATTRIB_TEXCOORD);
glDisableVertexAttribArray(LC_ATTRIB_NORMAL);
glDisableVertexAttribArray(LC_ATTRIB_COLOR);
}
else
{
glVertexPointer(3, GL_FLOAT, 0, NULL);
glNormalPointer(GL_BYTE, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
}
mNormalEnabled = false;
mTexCoordEnabled = false;
mColorEnabled = false;
}
void lcContext::FlushState()
{
if (gSupportsShaderObjects)
@ -1243,30 +1268,14 @@ void lcContext::DrawMeshSection(lcMesh* Mesh, lcMeshSection* Section)
{
SetMaterial(LightingMode == LC_LIGHTING_UNLIT ? LC_MATERIAL_UNLIT_COLOR : LC_MATERIAL_FAKELIT_COLOR);
SetVertexFormat(VertexBufferOffset, 3, 1, 0, 0, LightingMode != LC_LIGHTING_UNLIT);
if (mTexture)
{
glDisable(GL_TEXTURE_2D);
mTexture = NULL;
}
SetTexture(0);
}
else
{
VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex);
SetMaterial(LightingMode == LC_LIGHTING_UNLIT ? LC_MATERIAL_UNLIT_TEXTURE_DECAL : LC_MATERIAL_FAKELIT_TEXTURE_DECAL);
SetVertexFormat(VertexBufferOffset, 3, 1, 2, 0, LightingMode != LC_LIGHTING_UNLIT);
if (Texture != mTexture)
{
glBindTexture(GL_TEXTURE_2D, Texture->mTexture);
if (!mTexture)
{
glEnable(GL_TEXTURE_2D);
}
mTexture = Texture;
}
SetTexture(Texture->mTexture);
}
const bool DrawConditional = false;
@ -1541,12 +1550,7 @@ void lcContext::DrawRenderMeshes(const lcArray<lcRenderMesh>& RenderMeshes, cons
{
VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex);
SetVertexFormat(VertexBufferOffset, 3, 1, 2, 0, EnableNormals);
if (Texture != mTexture)
{
glBindTexture(GL_TEXTURE_2D, Texture->mTexture);
mTexture = Texture;
}
SetTexture(Texture->mTexture);
}
GLenum DrawPrimitiveType = (PrimitiveType == LC_MESH_TRIANGLES || PrimitiveType == LC_MESH_TEXTURED_TRIANGLES) ? GL_TRIANGLES : GL_LINES;
@ -1588,6 +1592,7 @@ void lcContext::DrawScene(const lcScene& Scene)
else
{
bool DrawLines = lcGetPreferences().mDrawEdgeLines;
SetTexture(0);
if (DrawLines)
{
@ -1611,8 +1616,6 @@ void lcContext::DrawScene(const lcScene& Scene)
if (Scene.mHasTexture)
{
glEnable(GL_TEXTURE_2D);
if (DrawLines)
{
SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_DECAL);
@ -1633,9 +1636,7 @@ void lcContext::DrawScene(const lcScene& Scene)
glDisable(GL_BLEND);
}
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
mTexture = NULL;
SetTexture(0);
}
}
}

View file

@ -63,7 +63,6 @@ public:
};
};
enum lcMaterialType
{
LC_MATERIAL_UNLIT_COLOR,
@ -103,6 +102,7 @@ public:
static void DestroyResources();
void SetDefaultState();
void ClearResources();
void SetWorldMatrix(const lcMatrix44& WorldMatrix)
{
@ -127,6 +127,7 @@ public:
void SetMaterial(lcMaterialType MaterialType);
void SetViewport(int x, int y, int Width, int Height);
void SetLineWidth(float LineWidth);
void SetTexture(GLuint Texture);
void SetColor(const lcVector4& Color)
{
@ -163,7 +164,6 @@ public:
void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count);
void DrawIndexedPrimitives(GLenum Mode, GLsizei Count, GLenum Type, int Offset);
void UnbindMesh();
void DrawScene(const lcScene& Scene);
void DrawInterfaceObjects(const lcArray<const lcObject*>& InterfaceObjects);
@ -188,9 +188,10 @@ protected:
bool mTexCoordEnabled;
bool mColorEnabled;
lcTexture* mTexture;
GLuint mTexture;
float mLineWidth;
int mMatrixMode;
bool mTextureEnabled;
lcVector4 mColor;
lcMatrix44 mWorldMatrix;

View file

@ -826,6 +826,7 @@ void lcMainWindow::Print(QPrinter* Printer)
free(Buffer);
Model->SetTemporaryStep(PreviousTime);
Context->EndRenderToTexture();
Context->ClearResources();
return;
}
@ -997,6 +998,7 @@ void lcMainWindow::Print(QPrinter* Printer)
Model->SetTemporaryStep(PreviousTime);
Context->EndRenderToTexture();
Context->ClearResources();
#endif
}

View file

@ -1196,16 +1196,13 @@ void lcModel::DrawBackground(lcGLWidget* Widget)
Context->DrawPrimitives(GL_TRIANGLE_FAN, 0, 4);
Context->ClearVertexBuffer(); // context remove
#ifndef LC_OPENGLES
glShadeModel(GL_FLAT);
#endif
}
else if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mBackgroundTexture->mTexture);
Context->SetTexture(mBackgroundTexture->mTexture);
float TileWidth = 1.0f, TileHeight = 1.0f;
@ -1224,15 +1221,11 @@ void lcModel::DrawBackground(lcGLWidget* Widget)
};
Context->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Context->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_MODULATE);
Context->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_DECAL);
Context->SetVertexBufferPointer(Verts);
Context->SetVertexFormat(0, 2, 0, 2, 0, false);
Context->DrawPrimitives(GL_TRIANGLE_FAN, 0, 4);
Context->ClearVertexBuffer(); // context remove
glDisable(GL_TEXTURE_2D);
}
glEnable(GL_DEPTH_TEST);
@ -1280,6 +1273,7 @@ void lcModel::SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Z
}
Context->EndRenderToTexture();
Context->ClearResources();
SetTemporaryStep(CurrentStep);

View file

@ -354,13 +354,12 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
Context->SetViewMatrix(ViewMatrix);
Context->DrawScene(Scene);
Context->UnbindMesh(); // context remove
Library->ReleasePieceInfo(Info);
mParts[InfoIndex].second = QPixmap::fromImage(Context->GetRenderToTextureImage(Width, Height)).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
Library->ReleasePieceInfo(Info);
Context->EndRenderToTexture();
Context->ClearResources();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
emit dataChanged(index(InfoIndex, 0), index(InfoIndex, 0), QVector<int>() << Qt::DecorationRole);

View file

@ -181,7 +181,7 @@ bool lcTexture::Load(lcMemFile& File, int Flags)
return Load(image, Flags);
}
bool lcTexture::Load(Image* images, int NumLevels, int Flags)
bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this should be part of lcContext, it can be called from multiple threads
{
mWidth = images[0].mWidth;
mHeight = images[0].mHeight;

View file

@ -430,8 +430,6 @@ void lcLight::DrawSpotLight(lcContext* Context) const
Context->DrawIndexedPrimitives(GL_LINES, 2 + 40, GL_UNSIGNED_SHORT, (56 + 24) * 2);
}
Context->ClearVertexBuffer(); // context remove
}
void lcLight::DrawPointLight(lcContext* Context) const

View file

@ -294,7 +294,7 @@ void MinifigWizard::OnDraw()
mContext->DrawScene(Scene);
mContext->UnbindMesh(); // context remove
mContext->ClearResources();
}
void MinifigWizard::OnLeftButtonDown()

View file

@ -1334,13 +1334,12 @@ void Project::ExportHTML()
Context->SetViewMatrix(ViewMatrix);
Context->DrawScene(Scene);
Context->UnbindMesh(); // context remove
QString FileName = QFileInfo(Dir, QLatin1String(Info->m_strName) + QLatin1String(".png")).absoluteFilePath();
if (!Context->SaveRenderToTextureImage(FileName, Width, Height))
break;
}
Context->EndRenderToTexture();
Context->ClearResources();
}
}

View file

@ -102,7 +102,7 @@ TexFont::~TexFont()
{
}
bool TexFont::Load()
bool TexFont::Load(lcContext* Context)
{
mRefCount++;
@ -112,7 +112,7 @@ bool TexFont::Load()
mFontHeight = 16;
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
Context->SetTexture(mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -236,8 +236,6 @@ void TexFont::PrintText(lcContext* Context, float Left, float Top, float Z, cons
Context->DrawPrimitives(GL_TRIANGLES, 0, 6 * (GLsizei)Length);
Context->ClearVertexBuffer(); // context remove
delete[] Verts;
}

View file

@ -12,12 +12,12 @@ public:
return mTexture != 0;
}
void MakeCurrent()
GLuint GetTexture() const
{
glBindTexture(GL_TEXTURE_2D, mTexture);
return mTexture;
}
bool Load();
bool Load(lcContext* Context);
void Release();
void PrintText(lcContext* Context, float Left, float Top, float Z, const char* Text) const;

View file

@ -586,8 +586,6 @@ void View::OnDraw()
mContext->DrawScene(mScene);
mContext->UnbindMesh(); // context remove
#ifndef LC_OPENGLES
if (Properties.mFogEnabled)
glDisable(GL_FOG);
@ -619,6 +617,8 @@ void View::OnDraw()
DrawViewport();
}
mContext->ClearResources();
}
void View::DrawSelectMoveOverlay()
@ -804,8 +804,6 @@ void View::DrawSelectMoveOverlay()
}
glEnable(GL_DEPTH_TEST);
mContext->ClearIndexBuffer(); // context remove
}
void View::DrawRotateOverlay()
@ -1087,9 +1085,7 @@ void View::DrawRotateOverlay()
mContext->SetWorldMatrix(lcMatrix44Identity());
mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0)));
mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f));
gTexFont.MakeCurrent();
glEnable(GL_TEXTURE_2D);
mContext->SetTexture(gTexFont.GetTexture());
glEnable(GL_BLEND);
char buf[32];
@ -1102,7 +1098,6 @@ void View::DrawRotateOverlay()
gTexFont.PrintText(mContext, ScreenPos[0] - (cx / 2), ScreenPos[1] + (cy / 2), 0.0f, buf);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}
glEnable(GL_DEPTH_TEST);
@ -1185,8 +1180,6 @@ void View::DrawSelectZoomRegionOverlay()
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
mContext->ClearVertexBuffer(); // context remove
}
void View::DrawRotateViewOverlay()
@ -1253,8 +1246,6 @@ void View::DrawRotateViewOverlay()
mContext->DrawIndexedPrimitives(GL_LINES, 96, GL_UNSIGNED_SHORT, 0);
glEnable(GL_DEPTH_TEST);
mContext->ClearVertexBuffer(); // context remove
}
void View::DrawGrid()
@ -1406,8 +1397,7 @@ void View::DrawGrid()
if (Preferences.mDrawGridStuds)
{
glBindTexture(GL_TEXTURE_2D, gGridTexture->mTexture);
glEnable(GL_TEXTURE_2D);
mContext->SetTexture(gGridTexture->mTexture);
glEnable(GL_BLEND);
mContext->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_MODULATE);
@ -1416,7 +1406,6 @@ void View::DrawGrid()
mContext->SetVertexFormat(0, 3, 0, 2, 0, false);
mContext->DrawPrimitives(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
BufferOffset = 4 * 5 * sizeof(float);
@ -1433,8 +1422,6 @@ void View::DrawGrid()
mContext->SetVertexFormat(BufferOffset, 3, 0, 0, 0, false);
mContext->DrawPrimitives(GL_LINES, 0, NumVerts);
}
mContext->ClearVertexBuffer(); // context remove
}
void View::DrawAxes()
@ -1485,8 +1472,7 @@ void View::DrawAxes()
mContext->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_MODULATE);
mContext->SetViewMatrix(TranslationMatrix);
gTexFont.MakeCurrent();
glEnable(GL_TEXTURE_2D);
mContext->SetTexture(gTexFont.GetTexture());
glEnable(GL_BLEND);
float TextBuffer[6 * 5 * 3];
@ -1504,9 +1490,6 @@ void View::DrawAxes()
mContext->DrawPrimitives(GL_TRIANGLES, 0, 6 * 3);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
mContext->ClearVertexBuffer(); // context remove
}
void View::DrawViewport()
@ -1529,23 +1512,19 @@ void View::DrawViewport()
mContext->DrawPrimitives(GL_LINE_LOOP, 0, 4);
}
mContext->ClearVertexBuffer(); // context remove
const char* CameraName = mCamera->GetName();
if (CameraName[0])
{
mContext->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_MODULATE);
mContext->SetColor(0.0f, 0.0f, 0.0f, 1.0f);
mContext->SetTexture(gTexFont.GetTexture());
glEnable(GL_TEXTURE_2D);
gTexFont.MakeCurrent();
glEnable(GL_BLEND);
gTexFont.PrintText(mContext, 3.0f, (float)mHeight - 1.0f - 6.0f, 0.0f, CameraName);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}
glDepthMask(GL_TRUE);

View file

@ -90,7 +90,7 @@ lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool view)
widget->MakeCurrent();
// TODO: Find a better place for the grid texture and font
gTexFont.Load();
gTexFont.Load(widget->mContext);
if (gWidgetList.isEmpty())
{
lcInitializeGLExtensions(context());