mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Clean up shader initialization and preserve optional rendering fallbacks
The fixed-function renderer was removed, but shader capability guards, bitmap text paths, and legacy attribute state still implied a working shaderless fallback. Remove that obsolete state and check shader support once when initializing rendering resources. Return detailed context and shader errors through lcResult and show fatal startup errors in GUI mode. Keep lighting, conditional lines, SDF text, view sphere, and outlines optional, with program validity checks selecting Flat shading, skipping unavailable overlays, or retaining selection tint. Non-rendering exports initialize only the context needed for asset loading. Apply icon availability to every parts list without overwriting requested sizes. Disable unavailable lighting and view-sphere preference controls, make attribute aliases explicit, and prevent signed-byte glyph indexing. Validation: macOS debug build, GUI and image export under forced optional shader compile/link failures, Flat fallback image comparisons, export initialization checks, preference preservation, and glyph byte-range checks.
This commit is contained in:
1 parent
75dc3883da
commit
a84c3d7b7e
16 files changed
+457
-524
No files matched your search
@@ -36,14 +36,13 @@ lcAboutDialog::lcAboutDialog(QWidget* Parent)
|
||||
const QString BuffersFormat = tr("Color Buffer: %1 bits\nDepth Buffer: %2 bits\nStencil Buffer: %3 bits\n\n");
|
||||
const QString Buffers = BuffersFormat.arg(QString::number(ColorDepth), QString::number(Format.depthBufferSize()), QString::number(Format.stencilBufferSize()));
|
||||
|
||||
const QString ExtensionsFormat = tr("Buffers: %1\nShaders: %2\nFramebuffers: %3\nBlendFuncSeparate: %4\nAnisotropic: %5\n");
|
||||
const QString ExtensionsFormat = tr("Buffers: %1\nFramebuffers: %2\nBlendFuncSeparate: %3\nAnisotropic: %4\n");
|
||||
const QString VertexBuffers = gSupportsVertexBufferObject ? tr("Supported") : tr("Not supported");
|
||||
const QString Shaders = gSupportsShaderObjects ? tr("Supported") : tr("Not supported");
|
||||
const QString Framebuffers = gSupportsFramebufferObject ? tr("Supported") : tr("Not supported");
|
||||
const QString BlendFuncSeparate = gSupportsBlendFuncSeparate ? tr("Supported") : tr("Not supported");
|
||||
const QString Anisotropic = gSupportsAnisotropic ? tr("Supported (max %1)").arg(gMaxAnisotropy) : tr("Not supported");
|
||||
|
||||
const QString Extensions = ExtensionsFormat.arg(VertexBuffers, Shaders, Framebuffers, BlendFuncSeparate, Anisotropic);
|
||||
const QString Extensions = ExtensionsFormat.arg(VertexBuffers, Framebuffers, BlendFuncSeparate, Anisotropic);
|
||||
|
||||
ui->info->setText(QtVersion + Version + Buffers + Extensions);
|
||||
}
|
||||
|
||||
@@ -946,6 +946,8 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
|
||||
if (Options.Exit)
|
||||
return lcStartupMode::Success;
|
||||
|
||||
const bool SaveAndExit = (Options.SaveImage || Options.SaveWavefront || Options.Save3DS || Options.SaveCOLLADA || Options.SaveCSV || Options.SaveHTML);
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
if (Options.SaveImage)
|
||||
{
|
||||
@@ -955,14 +957,22 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
if (!lcContext::InitializeRenderer())
|
||||
const bool CreateRenderResources = !SaveAndExit || Options.SaveImage || Options.SaveHTML;
|
||||
const lcResult<void> RendererResult = lcContext::InitializeRenderer(CreateRenderResources);
|
||||
|
||||
if (!RendererResult)
|
||||
{
|
||||
StdErr << tr("Error creating OpenGL context.\n");
|
||||
StdErr << RendererResult.error() << '\n';
|
||||
|
||||
if (!SaveAndExit)
|
||||
QMessageBox::critical(nullptr, tr("LeoCAD"), RendererResult.error());
|
||||
|
||||
return lcStartupMode::Error;
|
||||
}
|
||||
|
||||
emit RendererInitialized();
|
||||
#endif
|
||||
|
||||
const bool SaveAndExit = (Options.SaveImage || Options.SaveWavefront || Options.Save3DS || Options.SaveCOLLADA || Options.SaveCSV || Options.SaveHTML);
|
||||
bool OutputFailed = false;
|
||||
|
||||
if (!SaveAndExit)
|
||||
@@ -1332,11 +1342,16 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
|
||||
gMainWindow->GetPartSelectionWidget()->SetDefaultPart();
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
if (!lcContext::InitializeRenderer())
|
||||
const lcResult<void> RendererResult = lcContext::InitializeRenderer(true);
|
||||
|
||||
if (!RendererResult)
|
||||
{
|
||||
StdErr << tr("Error creating OpenGL context.\n");
|
||||
StdErr << RendererResult.error() << '\n';
|
||||
QMessageBox::critical(gMainWindow, tr("LeoCAD"), RendererResult.error());
|
||||
return lcStartupMode::Error;
|
||||
}
|
||||
|
||||
emit RendererInitialized();
|
||||
#endif
|
||||
|
||||
gMainWindow->show();
|
||||
|
||||
@@ -205,6 +205,9 @@ public:
|
||||
lcPreferences mPreferences;
|
||||
QByteArray mClipboard;
|
||||
|
||||
signals:
|
||||
void RendererInitialized();
|
||||
|
||||
protected:
|
||||
void UpdateStyle();
|
||||
QString GetTabLayoutKey() const;
|
||||
|
||||
+294
-263
@@ -11,15 +11,9 @@
|
||||
#include "lc_viewsphere.h"
|
||||
#include "lc_viewmanipulator.h"
|
||||
#include "lc_stringcache.h"
|
||||
#include "lc_partselectionwidget.h"
|
||||
#include "lc_scene.h"
|
||||
|
||||
#ifdef LC_OPENGLES
|
||||
#define glEnableClientState(...)
|
||||
#define glDisableClientState(...)
|
||||
#define glVertexPointer(...)
|
||||
#define glTexCoordPointer(...)
|
||||
#define glColorPointer(...)
|
||||
#define GL_ARRAY_BUFFER_ARB GL_ARRAY_BUFFER
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_ARB GL_ELEMENT_ARRAY_BUFFER
|
||||
#define GL_STATIC_DRAW_ARB GL_STATIC_DRAW
|
||||
@@ -28,6 +22,7 @@
|
||||
std::unique_ptr<QOpenGLContext> lcContext::mOffscreenContext;
|
||||
std::unique_ptr<QOffscreenSurface> lcContext::mOffscreenSurface;
|
||||
std::unique_ptr<lcContext> lcContext::mGlobalOffscreenContext;
|
||||
bool lcContext::mRenderResourcesCreated = false;
|
||||
lcProgram lcContext::mPrograms[static_cast<int>(lcMaterialType::Count)];
|
||||
|
||||
lcScopedGLContextState::lcScopedGLContextState()
|
||||
@@ -81,11 +76,6 @@ lcContext::lcContext()
|
||||
mIndexBufferObject = 0;
|
||||
mVertexBufferPointer = nullptr;
|
||||
mIndexBufferPointer = nullptr;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
|
||||
mNormalEnabled = false;
|
||||
mTexCoordEnabled = false;
|
||||
mColorEnabled = false;
|
||||
|
||||
mTexture2D = 0;
|
||||
mTextureCubeMap = 0;
|
||||
@@ -127,39 +117,60 @@ lcContext::~lcContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool lcContext::InitializeRenderer()
|
||||
lcResult<void> lcContext::InitializeRenderer(bool CreateRenderResources)
|
||||
{
|
||||
if (!CreateOffscreenContext())
|
||||
return false;
|
||||
const lcResult<void> OffscreenResult = CreateOffscreenContext();
|
||||
|
||||
if (!OffscreenResult)
|
||||
return lcUnexpected(OffscreenResult.error());
|
||||
|
||||
mGlobalOffscreenContext = std::unique_ptr<lcContext>(new(lcContext));
|
||||
|
||||
lcContext* Context = mGlobalOffscreenContext.get();
|
||||
|
||||
Context->SetOffscreenContext();
|
||||
|
||||
lcInitializeGLExtensions(mOffscreenContext.get());
|
||||
|
||||
if (!CreateRenderResources)
|
||||
return lcResult<void>();
|
||||
|
||||
if (!Context->hasOpenGLFeature(QOpenGLFunctions::Shaders))
|
||||
{
|
||||
mGlobalOffscreenContext.reset();
|
||||
DestroyOffscreenContext();
|
||||
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "OpenGL shader support is required."));
|
||||
}
|
||||
|
||||
const lcResult<void> ResourcesResult = Context->CreateResources();
|
||||
|
||||
if (!ResourcesResult)
|
||||
{
|
||||
Context->DestroyResources();
|
||||
mGlobalOffscreenContext.reset();
|
||||
DestroyOffscreenContext();
|
||||
|
||||
return lcUnexpected(ResourcesResult.error());
|
||||
}
|
||||
|
||||
gStringCache.Initialize(Context);
|
||||
gTexFont.Initialize(Context);
|
||||
|
||||
if (SupportsMaterial(lcMaterialType::TextSDF))
|
||||
gTexFont.Initialize(Context);
|
||||
|
||||
Context->CreateResources();
|
||||
lcView::CreateResources(Context);
|
||||
lcViewManipulator::CreateResources(Context);
|
||||
lcViewSphere::CreateResources(Context);
|
||||
|
||||
if (!gSupportsShaderObjects && lcGetPreferences().mShadingMode == lcShadingMode::DefaultLights)
|
||||
lcGetPreferences().mShadingMode = lcShadingMode::Flat;
|
||||
if (SupportsMaterial(lcMaterialType::UnlitViewSphere))
|
||||
lcViewSphere::CreateResources(Context);
|
||||
|
||||
if (!gSupportsShaderObjects && lcGetPreferences().mDrawConditionalLines)
|
||||
lcGetPreferences().mDrawConditionalLines = false;
|
||||
mRenderResourcesCreated = true;
|
||||
|
||||
if (!SupportsSelectionOutline())
|
||||
lcGetPreferences().mSelectionRenderMode = lcSelectionRenderMode::Tint;
|
||||
|
||||
if (!gSupportsFramebufferObject)
|
||||
gMainWindow->GetPartSelectionWidget()->DisableIconMode();
|
||||
|
||||
return true;
|
||||
return lcResult<void>();
|
||||
}
|
||||
|
||||
void lcContext::ShutdownRenderer()
|
||||
@@ -170,13 +181,18 @@ void lcContext::ShutdownRenderer()
|
||||
mGlobalOffscreenContext->MakeCurrent();
|
||||
lcContext* Context = mGlobalOffscreenContext.get();
|
||||
|
||||
gStringCache.Reset();
|
||||
gTexFont.Reset();
|
||||
if (mRenderResourcesCreated)
|
||||
{
|
||||
gStringCache.Reset();
|
||||
gTexFont.Reset();
|
||||
|
||||
lcView::DestroyResources(Context);
|
||||
Context->DestroyResources();
|
||||
lcViewManipulator::DestroyResources(Context);
|
||||
lcViewSphere::DestroyResources(Context);
|
||||
lcView::DestroyResources(Context);
|
||||
Context->DestroyResources();
|
||||
lcViewManipulator::DestroyResources(Context);
|
||||
lcViewSphere::DestroyResources(Context);
|
||||
|
||||
mRenderResourcesCreated = false;
|
||||
}
|
||||
|
||||
mGlobalOffscreenContext.reset();
|
||||
|
||||
@@ -188,35 +204,29 @@ lcContext* lcContext::GetGlobalOffscreenContext()
|
||||
return mGlobalOffscreenContext.get();
|
||||
}
|
||||
|
||||
bool lcContext::CreateOffscreenContext()
|
||||
lcResult<void> lcContext::CreateOffscreenContext()
|
||||
{
|
||||
std::unique_ptr<QOpenGLContext> OffscreenContext(new QOpenGLContext());
|
||||
|
||||
if (!OffscreenContext)
|
||||
return false;
|
||||
|
||||
OffscreenContext->setShareContext(QOpenGLContext::globalShareContext());
|
||||
|
||||
if (!OffscreenContext->create() || !OffscreenContext->isValid())
|
||||
return false;
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not create the OpenGL context."));
|
||||
|
||||
std::unique_ptr<QOffscreenSurface> OffscreenSurface(new QOffscreenSurface());
|
||||
|
||||
if (!OffscreenSurface)
|
||||
return false;
|
||||
|
||||
OffscreenSurface->create();
|
||||
|
||||
if (!OffscreenSurface->isValid())
|
||||
return false;
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not create the offscreen OpenGL surface."));
|
||||
|
||||
if (!OffscreenContext->makeCurrent(OffscreenSurface.get()))
|
||||
return false;
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not make the offscreen OpenGL context current."));
|
||||
|
||||
mOffscreenContext = std::move(OffscreenContext);
|
||||
mOffscreenSurface = std::move(OffscreenSurface);
|
||||
|
||||
return true;
|
||||
return lcResult<void>();
|
||||
}
|
||||
|
||||
void lcContext::DestroyOffscreenContext()
|
||||
@@ -225,7 +235,7 @@ void lcContext::DestroyOffscreenContext()
|
||||
mOffscreenContext.reset();
|
||||
}
|
||||
|
||||
void lcContext::CreateShaderPrograms()
|
||||
lcResult<void> lcContext::CreateShaderPrograms()
|
||||
{
|
||||
const char* ShaderPrefix =
|
||||
{
|
||||
@@ -291,17 +301,21 @@ void lcContext::CreateShaderPrograms()
|
||||
|
||||
LC_ARRAY_SIZE_CHECK(FragmentShaders, lcMaterialType::Count);
|
||||
|
||||
const auto LoadShader = [this, ShaderPrefix](const char* FileName, GLuint ShaderType) -> GLuint
|
||||
const auto LoadShader = [this, ShaderPrefix](const char* FileName, GLuint ShaderType) -> lcResult<GLuint>
|
||||
{
|
||||
QFile ShaderFile(FileName);
|
||||
|
||||
if (!ShaderFile.open(QIODevice::ReadOnly))
|
||||
return 0;
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not read shader %1: %2").arg(QString::fromUtf8(FileName), ShaderFile.errorString()));
|
||||
|
||||
QByteArray Data = ShaderPrefix + ShaderFile.readAll();
|
||||
const char* Source = Data.constData();
|
||||
|
||||
const GLuint Shader = glCreateShader(ShaderType);
|
||||
|
||||
if (!Shader)
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not create shader %1.").arg(QString::fromUtf8(FileName)));
|
||||
|
||||
glShaderSource(Shader, 1, &Source, nullptr);
|
||||
glCompileShader(Shader);
|
||||
|
||||
@@ -310,22 +324,17 @@ void lcContext::CreateShaderPrograms()
|
||||
|
||||
if (ShaderCompiled == GL_FALSE)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
GLint Length = 0;
|
||||
QByteArray InfoLog;
|
||||
|
||||
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &Length);
|
||||
|
||||
InfoLog.resize(Length);
|
||||
QByteArray InfoLog(Length, '\0');
|
||||
|
||||
glGetShaderInfoLog(Shader, Length, &Length, InfoLog.data());
|
||||
|
||||
qDebug() << InfoLog;
|
||||
#endif
|
||||
if (Length > 0)
|
||||
glGetShaderInfoLog(Shader, Length, nullptr, InfoLog.data());
|
||||
|
||||
glDeleteShader(Shader);
|
||||
|
||||
return 0;
|
||||
return lcUnexpected(QCoreApplication::translate("lcContext", "Could not compile shader %1:\n%2").arg(QString::fromUtf8(FileName), QString::fromUtf8(InfoLog.constData())));
|
||||
}
|
||||
|
||||
return Shader;
|
||||
@@ -333,21 +342,75 @@ void lcContext::CreateShaderPrograms()
|
||||
|
||||
for (int MaterialType = 0; MaterialType < static_cast<int>(lcMaterialType::Count); MaterialType++)
|
||||
{
|
||||
const GLuint VertexShader = LoadShader(VertexShaders[MaterialType], GL_VERTEX_SHADER);
|
||||
const GLuint FragmentShader = LoadShader(FragmentShaders[MaterialType], GL_FRAGMENT_SHADER);
|
||||
bool Optional = false;
|
||||
|
||||
if (!VertexShader || !FragmentShader)
|
||||
switch (static_cast<lcMaterialType>(MaterialType))
|
||||
{
|
||||
case lcMaterialType::UnlitColorConditional:
|
||||
case lcMaterialType::TextSDF:
|
||||
case lcMaterialType::UnlitViewSphere:
|
||||
case lcMaterialType::FakeLitColor:
|
||||
case lcMaterialType::FakeLitTextureDecal:
|
||||
case lcMaterialType::OutlineComposite:
|
||||
Optional = true;
|
||||
break;
|
||||
|
||||
case lcMaterialType::UnlitColor:
|
||||
case lcMaterialType::UnlitTextureModulate:
|
||||
case lcMaterialType::UnlitTextureDecal:
|
||||
case lcMaterialType::UnlitVertexColor:
|
||||
case lcMaterialType::Count:
|
||||
break;
|
||||
}
|
||||
|
||||
const lcResult<GLuint> VertexResult = LoadShader(VertexShaders[MaterialType], GL_VERTEX_SHADER);
|
||||
|
||||
if (!VertexResult)
|
||||
{
|
||||
if (Optional)
|
||||
{
|
||||
qWarning().noquote() << VertexResult.error();
|
||||
continue;
|
||||
}
|
||||
|
||||
return lcUnexpected(VertexResult.error());
|
||||
}
|
||||
|
||||
const GLuint VertexShader = VertexResult.value();
|
||||
const lcResult<GLuint> FragmentResult = LoadShader(FragmentShaders[MaterialType], GL_FRAGMENT_SHADER);
|
||||
|
||||
if (!FragmentResult)
|
||||
{
|
||||
glDeleteShader(VertexShader);
|
||||
|
||||
if (Optional)
|
||||
{
|
||||
qWarning().noquote() << FragmentResult.error();
|
||||
continue;
|
||||
}
|
||||
|
||||
return lcUnexpected(FragmentResult.error());
|
||||
}
|
||||
|
||||
const GLuint FragmentShader = FragmentResult.value();
|
||||
const GLuint Program = glCreateProgram();
|
||||
|
||||
if (!Program)
|
||||
{
|
||||
glDeleteShader(VertexShader);
|
||||
glDeleteShader(FragmentShader);
|
||||
|
||||
mPrograms[MaterialType].Object = 0;
|
||||
const QString Error = QCoreApplication::translate("lcContext", "Could not create the shader program for %1 and %2.").arg(QString::fromUtf8(VertexShaders[MaterialType]), QString::fromUtf8(FragmentShaders[MaterialType]));
|
||||
|
||||
continue;
|
||||
if (Optional)
|
||||
{
|
||||
qWarning().noquote() << Error;
|
||||
continue;
|
||||
}
|
||||
|
||||
return lcUnexpected(Error);
|
||||
}
|
||||
|
||||
GLuint Program = glCreateProgram();
|
||||
|
||||
glAttachShader(Program, VertexShader);
|
||||
glAttachShader(Program, FragmentShader);
|
||||
|
||||
@@ -373,26 +436,29 @@ void lcContext::CreateShaderPrograms()
|
||||
|
||||
if (IsLinked == GL_FALSE)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
GLint Length = 0;
|
||||
QByteArray InfoLog;
|
||||
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &Length);
|
||||
|
||||
InfoLog.resize(Length);
|
||||
QByteArray InfoLog(Length, '\0');
|
||||
|
||||
glGetProgramInfoLog(Program, Length, &Length, InfoLog.data());
|
||||
#endif
|
||||
if (Length > 0)
|
||||
glGetProgramInfoLog(Program, Length, nullptr, InfoLog.data());
|
||||
|
||||
glDeleteProgram(Program);
|
||||
Program = 0;
|
||||
|
||||
const QString Error = QCoreApplication::translate("lcContext", "Could not link the shader program for %1 and %2:\n%3").arg(QString::fromUtf8(VertexShaders[MaterialType]), QString::fromUtf8(FragmentShaders[MaterialType]), QString::fromUtf8(InfoLog.constData()));
|
||||
|
||||
if (Optional)
|
||||
{
|
||||
qWarning().noquote() << Error;
|
||||
continue;
|
||||
}
|
||||
|
||||
return lcUnexpected(Error);
|
||||
}
|
||||
|
||||
mPrograms[MaterialType].Object = Program;
|
||||
|
||||
if (!Program)
|
||||
continue;
|
||||
|
||||
|
||||
mPrograms[MaterialType].WorldViewProjectionMatrixLocation = glGetUniformLocation(Program, "WorldViewProjectionMatrix");
|
||||
mPrograms[MaterialType].WorldMatrixLocation = glGetUniformLocation(Program, "WorldMatrix");
|
||||
mPrograms[MaterialType].MaterialColorLocation = glGetUniformLocation(Program, "MaterialColor");
|
||||
@@ -412,7 +478,7 @@ void lcContext::CreateShaderPrograms()
|
||||
}
|
||||
|
||||
const GLint VisibleTextureLocation = glGetUniformLocation(Program, "VisibleTexture");
|
||||
|
||||
|
||||
if (VisibleTextureLocation != -1)
|
||||
{
|
||||
glUseProgram(Program);
|
||||
@@ -420,21 +486,17 @@ void lcContext::CreateShaderPrograms()
|
||||
glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
return lcResult<void>();
|
||||
}
|
||||
|
||||
void lcContext::CreateResources()
|
||||
lcResult<void> lcContext::CreateResources()
|
||||
{
|
||||
if (!gSupportsShaderObjects)
|
||||
return;
|
||||
|
||||
CreateShaderPrograms();
|
||||
return CreateShaderPrograms();
|
||||
}
|
||||
|
||||
void lcContext::DestroyResources()
|
||||
{
|
||||
if (!gSupportsShaderObjects)
|
||||
return;
|
||||
|
||||
for (int MaterialType = 0; MaterialType < static_cast<int>(lcMaterialType::Count); MaterialType++)
|
||||
{
|
||||
glDeleteProgram(mPrograms[MaterialType].Object);
|
||||
@@ -494,24 +556,20 @@ void lcContext::SetDefaultState()
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr);
|
||||
EnableVertexAttrib(lcProgramAttrib::Position);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
mVertexBufferObject = 0;
|
||||
mIndexBufferObject = 0;
|
||||
mVertexBufferPointer = nullptr;
|
||||
mIndexBufferPointer = nullptr;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
|
||||
for (int AttribIndex = 0; AttribIndex < static_cast<int>(lcProgramAttrib::Count); AttribIndex++)
|
||||
mVertexAttribState[AttribIndex] = lcVertexAttribState();
|
||||
@@ -533,11 +591,8 @@ void lcContext::SetDefaultState()
|
||||
glLineWidth(1.0f);
|
||||
mLineWidth = 1.0f;
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
glUseProgram(0);
|
||||
mMaterialType = lcMaterialType::Count;
|
||||
}
|
||||
glUseProgram(0);
|
||||
mMaterialType = lcMaterialType::Count;
|
||||
}
|
||||
|
||||
void lcContext::ClearColorAndDepth(const lcVector4& ClearColor)
|
||||
@@ -553,7 +608,7 @@ void lcContext::ClearDepth()
|
||||
|
||||
bool lcContext::SupportsSelectionOutline()
|
||||
{
|
||||
return gSupportsShaderObjects && gSupportsFramebufferObject &&
|
||||
return gSupportsFramebufferObject &&
|
||||
mPrograms[static_cast<int>(lcMaterialType::UnlitColor)].Object &&
|
||||
mPrograms[static_cast<int>(lcMaterialType::OutlineComposite)].Object;
|
||||
}
|
||||
@@ -572,23 +627,23 @@ std::unique_ptr<QOpenGLFramebufferObject> lcContext::CreateFramebuffer(int Width
|
||||
|
||||
const int MaxTextureSize = GetMaxTextureSize();
|
||||
GLint MaxRenderbufferSize = 0;
|
||||
|
||||
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &MaxRenderbufferSize);
|
||||
|
||||
|
||||
if (Width > MaxTextureSize || Height > MaxTextureSize || Width > MaxRenderbufferSize || Height > MaxRenderbufferSize)
|
||||
return nullptr;
|
||||
|
||||
lcScopedGLContextState GLState;
|
||||
QOpenGLFramebufferObjectFormat Format;
|
||||
|
||||
|
||||
Format.setAttachment(QOpenGLFramebufferObject::Depth);
|
||||
|
||||
|
||||
std::unique_ptr<QOpenGLFramebufferObject> Framebuffer = std::make_unique<QOpenGLFramebufferObject>(QSize(Width, Height), Format);
|
||||
|
||||
if (!Framebuffer->isValid())
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, mTexture2D);
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -598,7 +653,7 @@ std::unique_ptr<QOpenGLFramebufferObject> lcContext::CreateFramebuffer(int Width
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, mTexture2D);
|
||||
|
||||
|
||||
return Framebuffer;
|
||||
}
|
||||
|
||||
@@ -609,40 +664,40 @@ bool lcContext::TryShareDepthAttachment(GLuint SourceFramebuffer, QOpenGLFramebu
|
||||
return false;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, SourceFramebuffer);
|
||||
|
||||
|
||||
GLint Samples = 0;
|
||||
|
||||
|
||||
glGetIntegerv(GL_SAMPLES, &Samples);
|
||||
|
||||
|
||||
if (Samples != 0)
|
||||
return false;
|
||||
|
||||
GLint ObjectType = 0;
|
||||
GLint DepthBuffer = 0;
|
||||
|
||||
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &ObjectType);
|
||||
|
||||
|
||||
if (ObjectType != GL_RENDERBUFFER)
|
||||
return false;
|
||||
|
||||
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &DepthBuffer);
|
||||
|
||||
GLint PreviousRenderbuffer = 0;
|
||||
GLint Width = 0;
|
||||
GLint Height = 0;
|
||||
|
||||
|
||||
glGetIntegerv(GL_RENDERBUFFER_BINDING, &PreviousRenderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, DepthBuffer);
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &Width);
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &Height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, PreviousRenderbuffer);
|
||||
|
||||
|
||||
if (QSize(Width, Height) != TargetFramebuffer.size())
|
||||
return false;
|
||||
|
||||
TargetFramebuffer.bind();
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBuffer);
|
||||
|
||||
|
||||
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -651,10 +706,10 @@ bool lcContext::GenerateOutlineMasks(const lcScene& Scene, QOpenGLFramebufferObj
|
||||
lcScopedGLContextState GLState;
|
||||
GLint SceneFramebuffer = 0;
|
||||
GLint Viewport[4];
|
||||
|
||||
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &SceneFramebuffer);
|
||||
glGetIntegerv(GL_VIEWPORT, Viewport);
|
||||
|
||||
|
||||
const lcMatrix44 WorldMatrix = mWorldMatrix;
|
||||
const lcMatrix44 ViewMatrix = mViewMatrix;
|
||||
const lcMatrix44 ProjectionMatrix = mProjectionMatrix;
|
||||
@@ -669,28 +724,28 @@ bool lcContext::GenerateOutlineMasks(const lcScene& Scene, QOpenGLFramebufferObj
|
||||
Scene.DrawOutlineMask(this);
|
||||
|
||||
const bool Success = VisibleFramebuffer.bind() && glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||
|
||||
|
||||
if (Success)
|
||||
{
|
||||
GLint OwnDepthBuffer = 0;
|
||||
|
||||
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &OwnDepthBuffer);
|
||||
|
||||
|
||||
const bool SharedDepth = Scene.CanReuseSceneDepth() && TryShareDepthAttachment(SceneFramebuffer, VisibleFramebuffer);
|
||||
|
||||
|
||||
VisibleFramebuffer.bind();
|
||||
|
||||
|
||||
if (!SharedDepth)
|
||||
{
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OwnDepthBuffer);
|
||||
|
||||
|
||||
ClearColorAndDepth(lcVector4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
|
||||
EnableColorWrite(false);
|
||||
SetPolygonOffset(lcPolygonOffset::Opaque);
|
||||
|
||||
|
||||
Scene.DrawOutlineOccluders(this);
|
||||
|
||||
|
||||
SetPolygonOffset(lcPolygonOffset::None);
|
||||
EnableColorWrite(true);
|
||||
}
|
||||
@@ -701,9 +756,9 @@ bool lcContext::GenerateOutlineMasks(const lcScene& Scene, QOpenGLFramebufferObj
|
||||
}
|
||||
|
||||
SetDepthWrite(false);
|
||||
|
||||
|
||||
Scene.DrawOutlineMask(this);
|
||||
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OwnDepthBuffer);
|
||||
}
|
||||
|
||||
@@ -715,7 +770,7 @@ bool lcContext::GenerateOutlineMasks(const lcScene& Scene, QOpenGLFramebufferObj
|
||||
SetProjectionMatrix(ProjectionMatrix);
|
||||
SetViewport(Viewport[0], Viewport[1], Viewport[2], Viewport[3]);
|
||||
SetLineWidth(LineWidth);
|
||||
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -735,7 +790,7 @@ void lcContext::DrawOutline(QOpenGLFramebufferObject& FullFramebuffer, QOpenGLFr
|
||||
SetMaterial(lcMaterialType::OutlineComposite);
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
|
||||
|
||||
SetOutlineParams(lcVector4(1.0f / FullFramebuffer.width(), 1.0f / FullFramebuffer.height(), 2.0f * DeviceScale, 0.3f),
|
||||
lcVector4FromColor(Preferences.mObjectSelectedColor), lcVector4FromColor(Preferences.mObjectFocusedColor));
|
||||
|
||||
@@ -752,12 +807,12 @@ void lcContext::DrawOutline(QOpenGLFramebufferObject& FullFramebuffer, QOpenGLFr
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
|
||||
SetVertexBufferPointer(Vertices);
|
||||
SetVertexFormat(0, 3, 0, 2, 0, false);
|
||||
|
||||
|
||||
DrawPrimitives(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -783,16 +838,13 @@ void lcContext::SetMaterial(lcMaterialType MaterialType)
|
||||
|
||||
mMaterialType = MaterialType;
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
glUseProgram(mPrograms[static_cast<int>(MaterialType)].Object);
|
||||
mColorDirty = true;
|
||||
mWorldMatrixDirty = true; // todo: change dirty to a bitfield and set the lighting constants dirty here
|
||||
mViewMatrixDirty = true;
|
||||
mHighlightParamsDirty = true;
|
||||
mOutlineParamsDirty = true;
|
||||
mTextHaloColorDirty = true;
|
||||
}
|
||||
glUseProgram(mPrograms[static_cast<int>(MaterialType)].Object);
|
||||
mColorDirty = true;
|
||||
mWorldMatrixDirty = true; // todo: change dirty to a bitfield and set the lighting constants dirty here
|
||||
mViewMatrixDirty = true;
|
||||
mHighlightParamsDirty = true;
|
||||
mOutlineParamsDirty = true;
|
||||
mTextHaloColorDirty = true;
|
||||
}
|
||||
|
||||
void lcContext::SetViewport(int x, int y, int Width, int Height)
|
||||
@@ -1245,7 +1297,6 @@ void lcContext::DestroyIndexBuffer(lcIndexBuffer& IndexBuffer)
|
||||
void lcContext::ClearVertexBuffer()
|
||||
{
|
||||
mVertexBufferPointer = nullptr;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
|
||||
if (mVertexBufferObject)
|
||||
{
|
||||
@@ -1253,17 +1304,14 @@ void lcContext::ClearVertexBuffer()
|
||||
mVertexBufferObject = 0;
|
||||
}
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr);
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, 3, 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer)
|
||||
@@ -1277,13 +1325,11 @@ void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBufferObject);
|
||||
mVertexBufferObject = VertexBufferObject;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mVertexBufferPointer = (char*)VertexBuffer.Pointer;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,7 +1342,6 @@ void lcContext::SetVertexBufferPointer(const void* VertexBuffer)
|
||||
}
|
||||
|
||||
mVertexBufferPointer = (char*)VertexBuffer;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
}
|
||||
|
||||
void lcContext::SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer)
|
||||
@@ -1346,13 +1391,10 @@ void lcContext::SetVertexFormatPosition(int PositionSize)
|
||||
const int VertexSize = PositionSize * sizeof(float);
|
||||
const char* VertexBufferPointer = mVertexBufferPointer;
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
|
||||
DisableVertexAttrib(lcProgramAttrib::Normal);
|
||||
DisableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
DisableVertexAttrib(lcProgramAttrib::Color);
|
||||
}
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
|
||||
DisableVertexAttrib(lcProgramAttrib::Normal);
|
||||
DisableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
DisableVertexAttrib(lcProgramAttrib::Color);
|
||||
}
|
||||
|
||||
void lcContext::SetVertexFormatConditional(int BufferOffset)
|
||||
@@ -1360,17 +1402,14 @@ void lcContext::SetVertexFormatConditional(int BufferOffset)
|
||||
constexpr int VertexSize = 12 * sizeof(float);
|
||||
const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset;
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
@@ -1378,43 +1417,40 @@ void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int NormalSi
|
||||
const int VertexSize = (PositionSize + TexCoordSize) * sizeof(float) + NormalSize * sizeof(quint32) + ColorSize;
|
||||
const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset;
|
||||
|
||||
if (gSupportsShaderObjects)
|
||||
int Offset = 0;
|
||||
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
|
||||
EnableVertexAttrib(lcProgramAttrib::Position);
|
||||
|
||||
Offset += PositionSize * sizeof(float);
|
||||
|
||||
if (NormalSize && EnableNormals)
|
||||
{
|
||||
int Offset = 0;
|
||||
|
||||
SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer);
|
||||
EnableVertexAttrib(lcProgramAttrib::Position);
|
||||
|
||||
Offset += PositionSize * sizeof(float);
|
||||
|
||||
if (NormalSize && EnableNormals)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::Normal);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::Normal);
|
||||
|
||||
Offset += NormalSize * sizeof(quint32);
|
||||
|
||||
if (TexCoordSize)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::TexCoord, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
|
||||
Offset += TexCoordSize * sizeof(float);
|
||||
|
||||
if (ColorSize)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Color, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::Color);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::Color);
|
||||
SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::Normal);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::Normal);
|
||||
|
||||
Offset += NormalSize * sizeof(quint32);
|
||||
|
||||
if (TexCoordSize)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::TexCoord, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::TexCoord);
|
||||
|
||||
Offset += TexCoordSize * sizeof(float);
|
||||
|
||||
if (ColorSize)
|
||||
{
|
||||
SetVertexAttribPointer(lcProgramAttrib::Color, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset);
|
||||
EnableVertexAttrib(lcProgramAttrib::Color);
|
||||
}
|
||||
else
|
||||
DisableVertexAttrib(lcProgramAttrib::Color);
|
||||
}
|
||||
|
||||
void lcContext::ClearIndexBuffer()
|
||||
@@ -1470,7 +1506,6 @@ void lcContext::BindMesh(const lcMesh* Mesh)
|
||||
glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBufferObject);
|
||||
mVertexBufferObject = VertexBufferObject;
|
||||
mVertexBufferPointer = nullptr;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
}
|
||||
|
||||
if (IndexBufferObject != mIndexBufferObject)
|
||||
@@ -1496,74 +1531,70 @@ void lcContext::BindMesh(const lcMesh* Mesh)
|
||||
|
||||
mVertexBufferPointer = (char*)Mesh->mVertexData;
|
||||
mIndexBufferPointer = (char*)Mesh->mIndexData;
|
||||
mVertexBufferOffset = (char*)~0;
|
||||
}
|
||||
}
|
||||
|
||||
void lcContext::FlushState()
|
||||
{
|
||||
if (gSupportsShaderObjects)
|
||||
const lcProgram& Program = mPrograms[static_cast<int>(mMaterialType)];
|
||||
|
||||
if (mWorldMatrixDirty || mViewMatrixDirty || mProjectionMatrixDirty)
|
||||
{
|
||||
const lcProgram& Program = mPrograms[static_cast<int>(mMaterialType)];
|
||||
|
||||
if (mWorldMatrixDirty || mViewMatrixDirty || mProjectionMatrixDirty)
|
||||
if (mViewProjectionMatrixDirty)
|
||||
{
|
||||
if (mViewProjectionMatrixDirty)
|
||||
mViewProjectionMatrix = lcMul(mViewMatrix, mProjectionMatrix);
|
||||
mViewProjectionMatrixDirty = false;
|
||||
}
|
||||
|
||||
if (mWorldMatrixDirty)
|
||||
{
|
||||
if (Program.WorldMatrixLocation != -1)
|
||||
glUniformMatrix4fv(Program.WorldMatrixLocation, 1, false, mWorldMatrix.GetFloats());
|
||||
}
|
||||
|
||||
if (mViewMatrixDirty)
|
||||
{
|
||||
const lcMatrix44 InverseViewMatrix = lcMatrix44AffineInverse(mViewMatrix);
|
||||
lcVector3 ViewPosition = lcMul30(-mViewMatrix.GetTranslation(), InverseViewMatrix);
|
||||
|
||||
if (Program.LightPositionLocation != -1)
|
||||
{
|
||||
mViewProjectionMatrix = lcMul(mViewMatrix, mProjectionMatrix);
|
||||
mViewProjectionMatrixDirty = false;
|
||||
lcVector3 LightPosition = ViewPosition + lcMul30(lcVector3(300.0f, 300.0f, 0.0f), InverseViewMatrix);
|
||||
glUniform3fv(Program.LightPositionLocation, 1, LightPosition.GetFloats());
|
||||
}
|
||||
|
||||
if (mWorldMatrixDirty)
|
||||
{
|
||||
if (Program.WorldMatrixLocation != -1)
|
||||
glUniformMatrix4fv(Program.WorldMatrixLocation, 1, false, mWorldMatrix.GetFloats());
|
||||
}
|
||||
|
||||
if (mViewMatrixDirty)
|
||||
{
|
||||
const lcMatrix44 InverseViewMatrix = lcMatrix44AffineInverse(mViewMatrix);
|
||||
lcVector3 ViewPosition = lcMul30(-mViewMatrix.GetTranslation(), InverseViewMatrix);
|
||||
|
||||
if (Program.LightPositionLocation != -1)
|
||||
{
|
||||
lcVector3 LightPosition = ViewPosition + lcMul30(lcVector3(300.0f, 300.0f, 0.0f), InverseViewMatrix);
|
||||
glUniform3fv(Program.LightPositionLocation, 1, LightPosition.GetFloats());
|
||||
}
|
||||
|
||||
if (Program.EyePositionLocation != -1)
|
||||
glUniform3fv(Program.EyePositionLocation, 1, ViewPosition.GetFloats());
|
||||
}
|
||||
|
||||
glUniformMatrix4fv(Program.WorldViewProjectionMatrixLocation, 1, false, lcMul(mWorldMatrix, mViewProjectionMatrix).GetFloats());
|
||||
mWorldMatrixDirty = false;
|
||||
mViewMatrixDirty = false;
|
||||
mProjectionMatrixDirty = false;
|
||||
if (Program.EyePositionLocation != -1)
|
||||
glUniform3fv(Program.EyePositionLocation, 1, ViewPosition.GetFloats());
|
||||
}
|
||||
|
||||
if (mColorDirty && Program.MaterialColorLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.MaterialColorLocation, 1, mColor.GetFloats());
|
||||
mColorDirty = false;
|
||||
}
|
||||
glUniformMatrix4fv(Program.WorldViewProjectionMatrixLocation, 1, false, lcMul(mWorldMatrix, mViewProjectionMatrix).GetFloats());
|
||||
mWorldMatrixDirty = false;
|
||||
mViewMatrixDirty = false;
|
||||
mProjectionMatrixDirty = false;
|
||||
}
|
||||
|
||||
if (mTextHaloColorDirty && Program.TextHaloColorLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.TextHaloColorLocation, 1, mTextHaloColor.GetFloats());
|
||||
mTextHaloColorDirty = false;
|
||||
}
|
||||
if (mColorDirty && Program.MaterialColorLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.MaterialColorLocation, 1, mColor.GetFloats());
|
||||
mColorDirty = false;
|
||||
}
|
||||
|
||||
if (mHighlightParamsDirty && Program.HighlightParamsLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.HighlightParamsLocation, 4, mHighlightParams[0].GetFloats());
|
||||
mHighlightParamsDirty = false;
|
||||
}
|
||||
if (mTextHaloColorDirty && Program.TextHaloColorLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.TextHaloColorLocation, 1, mTextHaloColor.GetFloats());
|
||||
mTextHaloColorDirty = false;
|
||||
}
|
||||
|
||||
if (mOutlineParamsDirty && Program.OutlineParamsLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.OutlineParamsLocation, 3, mOutlineParams[0].GetFloats());
|
||||
mOutlineParamsDirty = false;
|
||||
}
|
||||
if (mHighlightParamsDirty && Program.HighlightParamsLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.HighlightParamsLocation, 4, mHighlightParams[0].GetFloats());
|
||||
mHighlightParamsDirty = false;
|
||||
}
|
||||
|
||||
if (mOutlineParamsDirty && Program.OutlineParamsLocation != -1)
|
||||
{
|
||||
glUniform4fv(Program.OutlineParamsLocation, 3, mOutlineParams[0].GetFloats());
|
||||
mOutlineParamsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-13
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "lc_math.h"
|
||||
#include "lc_mesh.h"
|
||||
#include "lc_result.h"
|
||||
|
||||
class lcVertexBuffer
|
||||
{
|
||||
@@ -64,11 +65,11 @@ enum class lcProgramAttrib
|
||||
Normal,
|
||||
TexCoord,
|
||||
Color,
|
||||
ControlPoint1 = 0,
|
||||
ControlPoint2,
|
||||
ControlPoint3,
|
||||
ControlPoint4,
|
||||
Count
|
||||
Count,
|
||||
ControlPoint1 = Position,
|
||||
ControlPoint2 = Normal,
|
||||
ControlPoint3 = TexCoord,
|
||||
ControlPoint4 = Color
|
||||
};
|
||||
|
||||
struct lcProgram
|
||||
@@ -137,11 +138,11 @@ public:
|
||||
lcContext& operator=(const lcContext&) = delete;
|
||||
lcContext& operator=(lcContext&&) = delete;
|
||||
|
||||
static bool InitializeRenderer();
|
||||
static lcResult<void> InitializeRenderer(bool CreateRenderResources);
|
||||
static void ShutdownRenderer();
|
||||
static lcContext* GetGlobalOffscreenContext();
|
||||
|
||||
void CreateResources();
|
||||
lcResult<void> CreateResources();
|
||||
void DestroyResources();
|
||||
|
||||
void SetDefaultState();
|
||||
@@ -160,6 +161,17 @@ public:
|
||||
|
||||
void ClearColorAndDepth(const lcVector4& ClearColor);
|
||||
void ClearDepth();
|
||||
|
||||
static bool SupportsMaterial(lcMaterialType MaterialType)
|
||||
{
|
||||
return mPrograms[static_cast<int>(MaterialType)].Object != 0;
|
||||
}
|
||||
|
||||
static bool SupportsDefaultLights()
|
||||
{
|
||||
return SupportsMaterial(lcMaterialType::FakeLitColor) && SupportsMaterial(lcMaterialType::FakeLitTextureDecal);
|
||||
}
|
||||
|
||||
static bool SupportsSelectionOutline();
|
||||
int GetMaxTextureSize();
|
||||
std::unique_ptr<QOpenGLFramebufferObject> CreateFramebuffer(int Width, int Height);
|
||||
@@ -266,10 +278,10 @@ public:
|
||||
void BindMesh(const lcMesh* Mesh);
|
||||
|
||||
protected:
|
||||
static bool CreateOffscreenContext();
|
||||
static lcResult<void> CreateOffscreenContext();
|
||||
static void DestroyOffscreenContext();
|
||||
|
||||
void CreateShaderPrograms();
|
||||
lcResult<void> CreateShaderPrograms();
|
||||
void FlushState();
|
||||
bool TryShareDepthAttachment(GLuint SourceFramebuffer, QOpenGLFramebufferObject& TargetFramebuffer);
|
||||
|
||||
@@ -284,12 +296,8 @@ protected:
|
||||
GLuint mIndexBufferObject;
|
||||
const char* mVertexBufferPointer;
|
||||
const char* mIndexBufferPointer;
|
||||
const char* mVertexBufferOffset;
|
||||
|
||||
lcMaterialType mMaterialType;
|
||||
bool mNormalEnabled;
|
||||
bool mTexCoordEnabled;
|
||||
bool mColorEnabled;
|
||||
|
||||
lcVertexAttribState mVertexAttribState[static_cast<int>(lcProgramAttrib::Count)];
|
||||
|
||||
@@ -325,6 +333,7 @@ protected:
|
||||
static std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
|
||||
static std::unique_ptr<lcContext> mGlobalOffscreenContext;
|
||||
|
||||
static bool mRenderResourcesCreated;
|
||||
static lcProgram mPrograms[static_cast<int>(lcMaterialType::Count)];
|
||||
|
||||
Q_DECLARE_TR_FUNCTIONS(lcContext);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "lc_global.h"
|
||||
#include "lc_glextensions.h"
|
||||
|
||||
bool gSupportsShaderObjects;
|
||||
bool gSupportsVertexBufferObject;
|
||||
bool gSupportsFramebufferObject;
|
||||
bool gSupportsBlendFuncSeparate;
|
||||
@@ -60,5 +59,4 @@ void lcInitializeGLExtensions(const QOpenGLContext* Context)
|
||||
gSupportsVertexBufferObject = Functions->hasOpenGLFeature(QOpenGLFunctions::Buffers);
|
||||
gSupportsFramebufferObject = Functions->hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
|
||||
gSupportsBlendFuncSeparate = Functions->hasOpenGLFeature(QOpenGLFunctions::BlendFuncSeparate);
|
||||
gSupportsShaderObjects = Functions->hasOpenGLFeature(QOpenGLFunctions::Shaders);
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
void lcInitializeGLExtensions(const QOpenGLContext* Context);
|
||||
|
||||
extern bool gSupportsShaderObjects;
|
||||
extern bool gSupportsVertexBufferObject;
|
||||
extern bool gSupportsFramebufferObject;
|
||||
extern bool gSupportsBlendFuncSeparate;
|
||||
|
||||
@@ -574,7 +574,10 @@ lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectio
|
||||
connect(this, &QListView::doubleClicked, this, &lcPartSelectionListView::DoubleClicked);
|
||||
connect(this, &QListView::customContextMenuRequested, this, &lcPartSelectionListView::CustomContextMenuRequested);
|
||||
|
||||
SetIconSize(lcGetProfileInt(LC_PROFILE_PARTS_LIST_ICONS));
|
||||
connect(gApplication, &lcApplication::RendererInitialized, this, &lcPartSelectionListView::UpdateIconSize);
|
||||
|
||||
mRequestedIconSize = lcGetProfileInt(LC_PROFILE_PARTS_LIST_ICONS);
|
||||
UpdateIconSize();
|
||||
}
|
||||
|
||||
void lcPartSelectionListView::keyPressEvent(QKeyEvent* KeyEvent)
|
||||
@@ -816,8 +819,15 @@ void lcPartSelectionListView::UpdateViewMode()
|
||||
|
||||
void lcPartSelectionListView::SetIconSize(int Size)
|
||||
{
|
||||
setIconSize(QSize(Size, Size));
|
||||
mRequestedIconSize = Size;
|
||||
lcSetProfileInt(LC_PROFILE_PARTS_LIST_ICONS, Size);
|
||||
UpdateIconSize();
|
||||
}
|
||||
|
||||
void lcPartSelectionListView::UpdateIconSize()
|
||||
{
|
||||
const int Size = gSupportsFramebufferObject ? mRequestedIconSize : NoIconSize;
|
||||
setIconSize(QSize(Size, Size));
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
float DeviceScale = devicePixelRatioF();
|
||||
@@ -1083,11 +1093,6 @@ void lcPartSelectionWidget::SaveState(QSettings& Settings)
|
||||
Settings.setValue("PartSelectionSplitter", QVariant::fromValue(Sizes));
|
||||
}
|
||||
|
||||
void lcPartSelectionWidget::DisableIconMode()
|
||||
{
|
||||
mPartsWidget->SetNoIcons();
|
||||
}
|
||||
|
||||
void lcPartSelectionWidget::SetCurrentPart(PieceInfo* Info)
|
||||
{
|
||||
mPartsWidget->SetCurrentPart(Info);
|
||||
|
||||
@@ -258,6 +258,7 @@ protected slots:
|
||||
|
||||
protected:
|
||||
void SetIconSize(int Size);
|
||||
void UpdateIconSize();
|
||||
void UpdateItemGeometry();
|
||||
void SetPartFilterType(lcPartFilterType Option);
|
||||
void keyPressEvent(QKeyEvent* KeyEvent) override;
|
||||
@@ -265,6 +266,7 @@ protected:
|
||||
lcPartSelectionListModel* mListModel = nullptr;
|
||||
lcPartSelectionWidget* mPartSelectionWidget = nullptr;
|
||||
PieceInfo* mContextInfo = nullptr;
|
||||
int mRequestedIconSize = NoIconSize;
|
||||
lcPartCategoryType mCategoryType = lcPartCategoryType::AllParts;
|
||||
int mCategoryIndex = 0;
|
||||
std::map<std::pair<lcPartCategoryType, int>, int> mLastCategoryRow;
|
||||
@@ -284,7 +286,6 @@ public:
|
||||
void UpdateCategories();
|
||||
void LoadState(QSettings& Settings);
|
||||
void SaveState(QSettings& Settings);
|
||||
void DisableIconMode();
|
||||
void SetOrientation(Qt::Orientation Orientation);
|
||||
void SetCurrentPart(PieceInfo* Info);
|
||||
void SetCategory(lcPartCategoryType Type, int Index);
|
||||
|
||||
+7
-6
@@ -440,13 +440,14 @@ void lcScene::Draw(lcContext* Context, const std::function<void()>& PreTransluce
|
||||
|
||||
const lcPreferences& Preferences = lcGetPreferences();
|
||||
const bool DrawLines = Preferences.mDrawEdgeLines && Preferences.mLineWidth > 0.0f;
|
||||
const bool DrawConditional = Preferences.mDrawConditionalLines && Preferences.mLineWidth > 0.0f;
|
||||
const bool DrawConditional = Preferences.mDrawConditionalLines && Preferences.mLineWidth > 0.0f && lcContext::SupportsMaterial(lcMaterialType::UnlitColorConditional);
|
||||
|
||||
// lcShadingMode ShadingMode = Preferences.mShadingMode;
|
||||
// if (ShadingMode == lcShadingMode::Wireframe && !mAllowWireframe)
|
||||
// ShadingMode = lcShadingMode::Flat;
|
||||
lcShadingMode ShadingMode = mShadingMode;
|
||||
|
||||
if (mShadingMode == lcShadingMode::Wireframe)
|
||||
if (ShadingMode != lcShadingMode::Wireframe && ShadingMode != lcShadingMode::Flat && !lcContext::SupportsDefaultLights())
|
||||
ShadingMode = lcShadingMode::Flat;
|
||||
|
||||
if (ShadingMode == lcShadingMode::Wireframe)
|
||||
{
|
||||
DrawOpaqueMeshes(Context, false, LC_MESH_LINES, true, true);
|
||||
|
||||
@@ -456,7 +457,7 @@ void lcScene::Draw(lcContext* Context, const std::function<void()>& PreTransluce
|
||||
if (PreTranslucentCallback)
|
||||
PreTranslucentCallback();
|
||||
}
|
||||
else if (mShadingMode == lcShadingMode::Flat)
|
||||
else if (ShadingMode == lcShadingMode::Flat)
|
||||
{
|
||||
const int SolidPrimitiveTypes = LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES | (DrawLines ? LC_MESH_LINES : 0);
|
||||
|
||||
|
||||
+23
-16
@@ -1167,24 +1167,27 @@ void lcView::OnDraw()
|
||||
TimerAverage += Result;
|
||||
TimerAverage /= TimerResults.size();
|
||||
|
||||
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));
|
||||
if (gTexFont.IsLoaded())
|
||||
{
|
||||
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));
|
||||
|
||||
QString Line = QString("GPU: %1 CPU: %2").arg(QString::number(QueryAverage / 1000000.0, 'f', 2), QString::number(TimerAverage / 1000000.0, 'f', 2));
|
||||
QString Line = QString("GPU: %1 CPU: %2").arg(QString::number(QueryAverage / 1000000.0, 'f', 2), QString::number(TimerAverage / 1000000.0, 'f', 2));
|
||||
|
||||
mContext->SetMaterial(gTexFont.IsSDF() ? lcMaterialType::TextSDF : lcMaterialType::UnlitTextureModulate);
|
||||
mContext->SetColor(lcVector4FromColor(lcGetPreferences().mTextColor));
|
||||
mContext->SetTextHaloColor(lcVector4FromColor(lcGetPreferences().mTextHaloColor));
|
||||
mContext->BindTexture2D(gTexFont.GetTexture());
|
||||
mContext->SetMaterial(lcMaterialType::TextSDF);
|
||||
mContext->SetColor(lcVector4FromColor(lcGetPreferences().mTextColor));
|
||||
mContext->SetTextHaloColor(lcVector4FromColor(lcGetPreferences().mTextHaloColor));
|
||||
mContext->BindTexture2D(gTexFont.GetTexture());
|
||||
|
||||
mContext->EnableDepthTest(false);
|
||||
mContext->EnableColorBlend(true);
|
||||
mContext->EnableDepthTest(false);
|
||||
mContext->EnableColorBlend(true);
|
||||
|
||||
gTexFont.PrintText(mContext, 3.0f, (float)mHeight - 1.0f - 6.0f, 0.0f, Line.toLatin1().constData());
|
||||
gTexFont.PrintText(mContext, 3.0f, (float)mHeight - 1.0f - 6.0f, 0.0f, Line.toLatin1().constData());
|
||||
|
||||
mContext->EnableColorBlend(false);
|
||||
mContext->EnableDepthTest(true);
|
||||
mContext->EnableColorBlend(false);
|
||||
mContext->EnableDepthTest(true);
|
||||
}
|
||||
|
||||
Redraw();
|
||||
#endif
|
||||
@@ -1308,15 +1311,16 @@ void lcView::DrawViewport() const
|
||||
|
||||
QString CameraName = mCamera->GetName();
|
||||
|
||||
if (!CameraName.isEmpty())
|
||||
if (!CameraName.isEmpty() && gTexFont.IsLoaded())
|
||||
{
|
||||
mContext->SetMaterial(gTexFont.IsSDF() ? lcMaterialType::TextSDF : lcMaterialType::UnlitTextureModulate);
|
||||
mContext->SetMaterial(lcMaterialType::TextSDF);
|
||||
mContext->SetColor(lcVector4FromColor(lcGetPreferences().mTextColor));
|
||||
mContext->SetTextHaloColor(lcVector4FromColor(lcGetPreferences().mTextHaloColor));
|
||||
mContext->BindTexture2D(gTexFont.GetTexture());
|
||||
|
||||
mContext->EnableColorBlend(true);
|
||||
|
||||
// TODO: Make TexFont support Unicode camera names instead of converting them to Latin-1.
|
||||
gTexFont.PrintText(mContext, 3.0f, (float)Height - 1.0f - 6.0f, 0.0f, CameraName.toLatin1().constData());
|
||||
|
||||
mContext->EnableColorBlend(false);
|
||||
@@ -1417,7 +1421,10 @@ void lcView::DrawAxes() const
|
||||
mContext->DrawIndexedPrimitives(GL_LINES, 6, GL_UNSIGNED_SHORT, 0);
|
||||
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, 6 * 2);
|
||||
|
||||
mContext->SetMaterial(gTexFont.IsSDF() ? lcMaterialType::TextSDF : lcMaterialType::UnlitTextureModulate);
|
||||
if (!gTexFont.IsLoaded())
|
||||
return;
|
||||
|
||||
mContext->SetMaterial(lcMaterialType::TextSDF);
|
||||
mContext->SetViewMatrix(TranslationMatrix);
|
||||
mContext->BindTexture2D(gTexFont.GetTexture());
|
||||
mContext->EnableColorBlend(true);
|
||||
|
||||
@@ -959,7 +959,7 @@ void lcViewManipulator::DrawAxisRotationRings(lcTrackButton TrackButton, lcTrack
|
||||
|
||||
void lcViewManipulator::DrawRotationText(lcTrackButton TrackButton, const lcVector3& MouseToolDistance, const std::optional<lcRotationDiscInfo>& RotationDisc, const lcMatrix44& WorldMatrix, float OverlayScale) const
|
||||
{
|
||||
if (TrackButton == lcTrackButton::None || !RotationDisc)
|
||||
if (TrackButton == lcTrackButton::None || !RotationDisc || !gTexFont.IsLoaded())
|
||||
return;
|
||||
|
||||
lcContext* Context = mView->mContext;
|
||||
@@ -978,7 +978,7 @@ void lcViewManipulator::DrawRotationText(lcTrackButton TrackButton, const lcVect
|
||||
const lcVector3 ScreenPos = mView->ProjectPoint(lcMul31(TextPosition, RotatedWorldMatrix));
|
||||
const float UIScale = mView->GetUIScale();
|
||||
|
||||
Context->SetMaterial(gTexFont.IsSDF() ? lcMaterialType::TextSDF : lcMaterialType::UnlitTextureModulate);
|
||||
Context->SetMaterial(lcMaterialType::TextSDF);
|
||||
Context->SetWorldMatrix(lcMatrix44Identity());
|
||||
Context->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0)));
|
||||
Context->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mView->GetWidth() / UIScale, 0.0f, mView->GetHeight() / UIScale, -1.0f, 1.0f));
|
||||
@@ -1045,10 +1045,13 @@ void lcViewManipulator::DrawMoveDistance(lcTrackButton TrackButton, lcTrackTool
|
||||
Context->SetVertexFormatPosition(3);
|
||||
Context->DrawPrimitives(GL_TRIANGLES, 0, 18);
|
||||
|
||||
if (!gTexFont.IsLoaded())
|
||||
return;
|
||||
|
||||
const lcVector3 ScreenPos = mView->ProjectPoint(TextPosition);
|
||||
const float UIScale = mView->GetUIScale();
|
||||
|
||||
Context->SetMaterial(gTexFont.IsSDF() ? lcMaterialType::TextSDF : lcMaterialType::UnlitTextureModulate);
|
||||
Context->SetMaterial(lcMaterialType::TextSDF);
|
||||
Context->SetWorldMatrix(lcMatrix44Identity());
|
||||
Context->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0)));
|
||||
Context->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mView->GetWidth() / UIScale, 0.0f, mView->GetHeight() / UIScale, -1.0f, 1.0f));
|
||||
|
||||
+25
-58
@@ -5,7 +5,6 @@
|
||||
#include "lc_context.h"
|
||||
#include "lc_stringcache.h"
|
||||
#include "lc_application.h"
|
||||
#include "lc_glextensions.h"
|
||||
#include "image.h"
|
||||
#include "lc_texture.h"
|
||||
|
||||
@@ -46,6 +45,8 @@ void lcViewSphere::UpdateSettings()
|
||||
case lcViewType::Count:
|
||||
break;
|
||||
}
|
||||
|
||||
mEnabled = mEnabled && lcContext::SupportsMaterial(lcMaterialType::UnlitViewSphere);
|
||||
}
|
||||
|
||||
lcMatrix44 lcViewSphere::GetViewMatrix() const
|
||||
@@ -74,23 +75,11 @@ void lcViewSphere::CreateResources(lcContext* Context)
|
||||
|
||||
QImage PainterImage(SourceCellSize, SourceCellSize, QImage::Format_ARGB32);
|
||||
QPainter Painter;
|
||||
QFont Font("Helvetica", gSupportsShaderObjects ? 36 : 20);
|
||||
const bool UseSDF = gSupportsShaderObjects;
|
||||
QFont Font("Helvetica", 36);
|
||||
Image AtlasImage;
|
||||
std::vector<Image> BitmapFaces;
|
||||
if (UseSDF)
|
||||
{
|
||||
AtlasImage.Allocate(AtlasWidth, AtlasHeight, lcPixelFormat::A8);
|
||||
memset(AtlasImage.mData, 0, AtlasWidth * AtlasHeight);
|
||||
}
|
||||
else
|
||||
BitmapFaces.reserve(6);
|
||||
const QTransform BitmapTransforms[6] =
|
||||
{
|
||||
QTransform(0, 1, 1, 0, 0, 0), QTransform(0, -1, -1, 0, SourceCellSize, SourceCellSize),
|
||||
QTransform(-1, 0, 0, 1, SourceCellSize, 0), QTransform(1, 0, 0, -1, 0, SourceCellSize),
|
||||
QTransform(1, 0, 0, -1, 0, SourceCellSize), QTransform(-1, 0, 0, 1, SourceCellSize, 0)
|
||||
};
|
||||
AtlasImage.Allocate(AtlasWidth, AtlasHeight, lcPixelFormat::A8);
|
||||
memset(AtlasImage.mData, 0, AtlasWidth * AtlasHeight);
|
||||
|
||||
auto ConvertToSDF = [](Image& TextureImage)
|
||||
{
|
||||
constexpr int Size = 128, Count = Size * Size;
|
||||
@@ -116,23 +105,18 @@ void lcViewSphere::CreateResources(lcContext* Context)
|
||||
Image TextureImage;
|
||||
TextureImage.Allocate(SourceCellSize, SourceCellSize, lcPixelFormat::A8);
|
||||
QFont LabelFont = Font;
|
||||
if (UseSDF)
|
||||
{
|
||||
// The shader displays the middle 80% of each cell. Leave six pixels
|
||||
// on either side for the SDF halo, including for translated labels.
|
||||
constexpr int MaxLabelWidth = 90;
|
||||
while (LabelFont.pointSize() > 1 && QFontMetrics(LabelFont).horizontalAdvance(ViewNames[ViewIdx]) > MaxLabelWidth)
|
||||
LabelFont.setPointSize(LabelFont.pointSize() - 1);
|
||||
}
|
||||
// The shader displays the middle 80% of each cell. Leave six pixels
|
||||
// on either side for the SDF halo, including for translated labels.
|
||||
constexpr int MaxLabelWidth = 90;
|
||||
while (LabelFont.pointSize() > 1 && QFontMetrics(LabelFont).horizontalAdvance(ViewNames[ViewIdx]) > MaxLabelWidth)
|
||||
LabelFont.setPointSize(LabelFont.pointSize() - 1);
|
||||
|
||||
Painter.begin(&PainterImage);
|
||||
Painter.setRenderHint(QPainter::TextAntialiasing, UseSDF);
|
||||
Painter.setRenderHint(QPainter::TextAntialiasing);
|
||||
Painter.fillRect(0, 0, PainterImage.width(), PainterImage.height(), QColor(0, 0, 0));
|
||||
Painter.setBrush(QColor(255, 255, 255));
|
||||
Painter.setPen(QColor(255, 255, 255));
|
||||
Painter.setFont(LabelFont);
|
||||
if (!UseSDF)
|
||||
Painter.setTransform(BitmapTransforms[ViewIdx]);
|
||||
Painter.drawText(0, 0, PainterImage.width(), PainterImage.height(), Qt::AlignCenter, ViewNames[ViewIdx]);
|
||||
Painter.end();
|
||||
|
||||
@@ -143,27 +127,19 @@ void lcViewSphere::CreateResources(lcContext* Context)
|
||||
for (int x = 0; x < SourceCellSize; x++)
|
||||
*Dest++ = qRed(PainterImage.pixel(x, y));
|
||||
}
|
||||
if (UseSDF)
|
||||
{
|
||||
ConvertToSDF(TextureImage);
|
||||
// Keep the middle band and its SDF margin in a vertical atlas.
|
||||
const int AtlasY = ViewIdx * CellHeight;
|
||||
for (int y = 0; y < CellHeight; y++)
|
||||
memcpy(AtlasImage.mData + (AtlasY + y) * AtlasWidth,
|
||||
TextureImage.mData + (CellBottom + y) * SourceCellSize, SourceCellSize);
|
||||
}
|
||||
else
|
||||
BitmapFaces.emplace_back(std::move(TextureImage));
|
||||
ConvertToSDF(TextureImage);
|
||||
// Keep the middle band and its SDF margin in a vertical atlas.
|
||||
const int AtlasY = ViewIdx * CellHeight;
|
||||
for (int y = 0; y < CellHeight; y++)
|
||||
memcpy(AtlasImage.mData + (AtlasY + y) * AtlasWidth,
|
||||
TextureImage.mData + (CellBottom + y) * SourceCellSize, SourceCellSize);
|
||||
}
|
||||
|
||||
if (UseSDF)
|
||||
mTexture->SetImage(std::move(AtlasImage), LC_TEXTURE_LINEAR);
|
||||
else
|
||||
mTexture->SetImage(std::move(BitmapFaces), LC_TEXTURE_CUBEMAP | LC_TEXTURE_LINEAR);
|
||||
mTexture->SetImage(std::move(AtlasImage), LC_TEXTURE_LINEAR);
|
||||
|
||||
const int SphereVertexCount = (mSubdivisions + 1) * (mSubdivisions + 1) * 6;
|
||||
mSphereIndexCount = mSubdivisions * mSubdivisions * 6 * 6;
|
||||
std::vector<float> Verts(SphereVertexCount * (UseSDF ? 6 : 3));
|
||||
std::vector<float> Verts(SphereVertexCount * 6);
|
||||
std::vector<GLushort> Indices(mSphereIndexCount);
|
||||
|
||||
lcMatrix44 Transforms[6] =
|
||||
@@ -197,12 +173,9 @@ void lcViewSphere::CreateResources(lcContext* Context)
|
||||
*CurVert++ = SphereVert.x;
|
||||
*CurVert++ = SphereVert.y;
|
||||
*CurVert++ = SphereVert.z;
|
||||
if (UseSDF)
|
||||
{
|
||||
*CurVert++ = x / static_cast<float>(mSubdivisions);
|
||||
*CurVert++ = y / static_cast<float>(mSubdivisions);
|
||||
*CurVert++ = static_cast<float>(FaceIdx);
|
||||
}
|
||||
*CurVert++ = x / static_cast<float>(mSubdivisions);
|
||||
*CurVert++ = y / static_cast<float>(mSubdivisions);
|
||||
*CurVert++ = static_cast<float>(FaceIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,10 +235,7 @@ void lcViewSphere::Draw()
|
||||
Context->EnableCullFace(true);
|
||||
|
||||
Context->SetVertexBuffer(mVertexBuffer);
|
||||
if (gSupportsShaderObjects)
|
||||
Context->SetVertexFormat(0, 3, 0, 3, 0, false);
|
||||
else
|
||||
Context->SetVertexFormatPosition(3);
|
||||
Context->SetVertexFormat(0, 3, 0, 3, 0, false);
|
||||
Context->SetIndexBuffer(mIndexBuffer);
|
||||
|
||||
Context->SetMaterial(lcMaterialType::UnlitColor);
|
||||
@@ -279,10 +249,7 @@ void lcViewSphere::Draw()
|
||||
Context->DrawIndexedPrimitives(GL_TRIANGLES, mSphereIndexCount, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
Context->SetMaterial(lcMaterialType::UnlitViewSphere);
|
||||
if (gSupportsShaderObjects)
|
||||
Context->BindTexture2D(mTexture);
|
||||
else
|
||||
Context->BindTextureCubeMap(mTexture);
|
||||
Context->BindTexture2D(mTexture);
|
||||
|
||||
Context->SetWorldMatrix(lcMatrix44Identity());
|
||||
Context->SetViewMatrix(GetViewMatrix());
|
||||
|
||||
+11
-130
@@ -2,92 +2,17 @@
|
||||
#include <string.h>
|
||||
#include "texfont.h"
|
||||
#include "lc_context.h"
|
||||
#include "lc_glextensions.h"
|
||||
#include "lc_texture.h"
|
||||
#include "image.h"
|
||||
|
||||
static const unsigned char TextureData[2048] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0xe0, 0x00, 0x18, 0x60, 0x66, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x60, 0x66, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0xb1, 0x03, 0x0f, 0x6e, 0x78, 0xfc, 0xb8, 0xd9, 0x61, 0x66, 0xcc, 0xec, 0x1c, 0x3b, 0x00, 0x0c, 0x73, 0x86, 0x19, 0x73, 0xcc, 0x30, 0xcc, 0x39, 0x63, 0x66, 0xc6, 0x9c, 0x33, 0x67, 0x00,
|
||||
0x00, 0x33, 0xcc, 0x90, 0x61, 0x86, 0x31, 0x86, 0x19, 0x66, 0x66, 0xc3, 0x8c, 0x31, 0xc3, 0x00, 0xe0, 0x33, 0xcc, 0x80, 0x61, 0x86, 0x31, 0x86, 0x19, 0x66, 0xe6, 0xc1, 0x8c, 0x31, 0xc3, 0x00,
|
||||
0x38, 0x33, 0xcc, 0x80, 0x61, 0xfe, 0x31, 0x86, 0x19, 0x66, 0xe6, 0xc1, 0x8c, 0x31, 0xc3, 0x00, 0x0c, 0x33, 0xcc, 0x80, 0x61, 0x06, 0x30, 0x86, 0x19, 0x66, 0x66, 0xc3, 0x8c, 0x31, 0xc3, 0x00,
|
||||
0x0c, 0x33, 0xcc, 0x90, 0x61, 0x06, 0x30, 0x86, 0x19, 0x66, 0x66, 0xc6, 0x8c, 0x31, 0xc3, 0x00, 0x0c, 0x73, 0x86, 0x19, 0x73, 0x8c, 0x31, 0xcc, 0x19, 0x66, 0x66, 0xcc, 0x8c, 0x31, 0xc3, 0x00,
|
||||
0xf8, 0xb6, 0x03, 0x0f, 0x6e, 0xf8, 0x30, 0xb8, 0x19, 0x66, 0x66, 0xd8, 0x8c, 0x31, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0xf0, 0xb0, 0x03, 0x37, 0x3b, 0x9f, 0xdf, 0xb0, 0xc1, 0x03, 0xf0, 0xf0, 0x60, 0x3f, 0x63, 0x00,
|
||||
0x98, 0x71, 0x86, 0x39, 0x8f, 0x31, 0xc6, 0xb0, 0xc1, 0xc3, 0xf0, 0xf0, 0x60, 0x30, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x87, 0x01, 0xc6, 0x30, 0x63, 0xc6, 0x98, 0x99, 0x31, 0x18, 0x63, 0x00,
|
||||
0x0c, 0x33, 0xcc, 0x30, 0x83, 0x03, 0xc6, 0x30, 0x63, 0xe6, 0x19, 0x8f, 0x31, 0x18, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x03, 0x1f, 0xc6, 0x30, 0x63, 0xe6, 0x19, 0x86, 0x31, 0x0c, 0x63, 0x00,
|
||||
0x0c, 0x33, 0xcc, 0x30, 0x03, 0x38, 0xc6, 0x30, 0x36, 0x2c, 0x0d, 0x0f, 0x1b, 0x06, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x03, 0x30, 0xc6, 0x30, 0x36, 0x3c, 0x8f, 0x19, 0x1b, 0x06, 0x63, 0x00,
|
||||
0x98, 0x71, 0x86, 0x39, 0x83, 0x31, 0x86, 0x39, 0x1c, 0x18, 0xc6, 0x30, 0x0e, 0x03, 0x36, 0x00, 0xf0, 0xb0, 0x03, 0x37, 0x03, 0x1f, 0x1c, 0x37, 0x1c, 0x18, 0xc6, 0x30, 0x0e, 0x3f, 0x1c, 0x00,
|
||||
0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0xe1, 0x03, 0xc6, 0x1f, 0x1e, 0x7f, 0x7c, 0xf8, 0x00, 0x01, 0x7f, 0x80, 0x0f, 0x00,
|
||||
0x78, 0x18, 0x33, 0x06, 0xc6, 0x00, 0x03, 0x60, 0xc6, 0x8c, 0x81, 0x03, 0xc3, 0xc0, 0x18, 0x00, 0x60, 0x08, 0x13, 0x06, 0xc7, 0x80, 0x01, 0x60, 0xc6, 0x8c, 0x81, 0x03, 0x83, 0x61, 0x30, 0x00,
|
||||
0x60, 0x00, 0x03, 0x06, 0xc7, 0x80, 0x01, 0x30, 0xc6, 0x8c, 0xc1, 0x06, 0x83, 0x61, 0x30, 0x00, 0x60, 0x00, 0x03, 0x86, 0xc7, 0x8f, 0x01, 0x30, 0xc6, 0x8c, 0xc1, 0x06, 0xc3, 0x30, 0x00, 0x00,
|
||||
0x60, 0x80, 0xc1, 0xc3, 0xc6, 0x98, 0x1f, 0x18, 0x7c, 0x8c, 0x61, 0x0c, 0x7f, 0x30, 0x00, 0x00, 0x60, 0xc0, 0x00, 0xc6, 0x06, 0x98, 0x31, 0x18, 0xc6, 0xf8, 0x61, 0x0c, 0xc3, 0x30, 0x00, 0x00,
|
||||
0x60, 0x60, 0x00, 0x66, 0x06, 0x98, 0x31, 0x18, 0xc6, 0x80, 0x31, 0x18, 0x83, 0x31, 0x00, 0x00, 0x60, 0x30, 0x00, 0xe6, 0x0f, 0x98, 0x31, 0x0c, 0xc6, 0x80, 0xf1, 0x1f, 0x83, 0x61, 0x30, 0x00,
|
||||
0x60, 0x18, 0x10, 0x06, 0x46, 0x98, 0x31, 0x0c, 0xc6, 0x80, 0x19, 0x30, 0x83, 0x61, 0x30, 0x00, 0x60, 0x18, 0x30, 0x06, 0xc6, 0x98, 0x31, 0x0c, 0xc6, 0xc0, 0x18, 0x30, 0xc3, 0xc0, 0x18, 0x00,
|
||||
0x60, 0xf8, 0xe3, 0x03, 0x86, 0x0f, 0x1f, 0x0c, 0x7c, 0x78, 0x18, 0x30, 0x7f, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0x81, 0x7f, 0xfc, 0x83, 0x0f, 0x06, 0x63, 0xc0, 0x18, 0xc6, 0x00, 0x03, 0xc6, 0x60, 0x00, 0x18, 0x83, 0x01, 0x0c, 0xc0, 0x18, 0x06, 0x63, 0xc0, 0x18, 0xc3, 0x00, 0x03, 0xc6, 0x60, 0x00,
|
||||
0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc0, 0x98, 0xc1, 0x00, 0x07, 0xc7, 0x61, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc0, 0xd8, 0xc0, 0x00, 0x07, 0xc7, 0x63, 0x00,
|
||||
0x18, 0x8c, 0x01, 0x0c, 0x30, 0x00, 0x06, 0x63, 0xc0, 0x78, 0xc0, 0x00, 0x8f, 0xc7, 0x67, 0x00, 0x18, 0x8c, 0x3f, 0xfc, 0x31, 0x00, 0xfe, 0x63, 0xc0, 0x38, 0xc0, 0x00, 0x8f, 0xc7, 0x66, 0x00,
|
||||
0x18, 0x8c, 0x01, 0x0c, 0x30, 0x3e, 0x06, 0x63, 0xc0, 0x78, 0xc0, 0x00, 0xdb, 0xc6, 0x6c, 0x00, 0x18, 0x8c, 0x01, 0x0c, 0x30, 0x30, 0x06, 0x63, 0xc0, 0xd8, 0xc0, 0x00, 0xdb, 0xc6, 0x7c, 0x00,
|
||||
0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc6, 0x98, 0xc1, 0x00, 0x73, 0xc6, 0x78, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x38, 0x06, 0x63, 0xc6, 0x18, 0xc3, 0x00, 0x73, 0xc6, 0x70, 0x00,
|
||||
0x18, 0x83, 0x01, 0x0c, 0xc0, 0x38, 0x06, 0x63, 0x6c, 0x18, 0xc6, 0x00, 0x23, 0xc6, 0x60, 0x00, 0xf8, 0x81, 0x7f, 0x0c, 0x80, 0x2f, 0x06, 0x63, 0x38, 0x18, 0xcc, 0x3f, 0x23, 0xc6, 0x60, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x7f, 0xc0, 0x03, 0x7f, 0xc0, 0xe3, 0x7f, 0x06, 0x33, 0xb0, 0x01, 0xd8, 0xc0, 0x00,
|
||||
0x60, 0x06, 0xc3, 0x60, 0x06, 0xc3, 0x60, 0x06, 0x06, 0x06, 0x33, 0xb0, 0x61, 0xd8, 0xc0, 0x00, 0x30, 0x0c, 0x83, 0x31, 0x0c, 0x83, 0x31, 0x0c, 0x06, 0x06, 0x63, 0x98, 0x61, 0x98, 0x61, 0x00,
|
||||
0x30, 0x0c, 0x83, 0x31, 0x0c, 0x83, 0x31, 0x00, 0x06, 0x06, 0x63, 0x18, 0x63, 0x0c, 0x33, 0x00, 0x18, 0x18, 0x83, 0x19, 0x18, 0x83, 0x61, 0x00, 0x06, 0x06, 0x63, 0x18, 0xf3, 0x0c, 0x1e, 0x00,
|
||||
0x18, 0x18, 0xc3, 0x18, 0x18, 0xc3, 0xc0, 0x03, 0x06, 0x06, 0xc3, 0x0c, 0xf3, 0x0c, 0x0c, 0x00, 0x18, 0x18, 0x7f, 0x18, 0x18, 0x7f, 0x00, 0x06, 0x06, 0x06, 0xc3, 0x0c, 0x96, 0x06, 0x0c, 0x00,
|
||||
0x18, 0x18, 0x03, 0x98, 0x19, 0xc3, 0x00, 0x0c, 0x06, 0x06, 0x83, 0x04, 0x9e, 0x07, 0x1e, 0x00, 0x30, 0x0c, 0x03, 0x30, 0x0f, 0x83, 0x01, 0x0c, 0x06, 0x06, 0x83, 0x07, 0x9e, 0x07, 0x33, 0x00,
|
||||
0x30, 0x0c, 0x03, 0x30, 0x0e, 0x83, 0x31, 0x0c, 0x06, 0x06, 0x83, 0x07, 0x0c, 0x83, 0x61, 0x00, 0x60, 0x06, 0x03, 0x60, 0x0e, 0x83, 0x61, 0x06, 0x06, 0x8c, 0x01, 0x03, 0x0c, 0xc3, 0xc0, 0x00,
|
||||
0xc0, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0xc3, 0x03, 0x06, 0xf8, 0x00, 0x03, 0x0c, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0xec, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x80, 0xf1, 0x80, 0x07, 0xf0, 0x03, 0x08, 0x1c, 0x18, 0x0c, 0x0c, 0x30, 0x00, 0x03, 0x00, 0x66, 0x80, 0x99, 0xc1, 0x0c, 0x1c, 0x0e, 0x3e, 0x36, 0x0c,
|
||||
0x18, 0x06, 0x18, 0x00, 0x03, 0x00, 0xc3, 0x80, 0x0d, 0x63, 0x18, 0x06, 0x18, 0x6b, 0x36, 0x06, 0x30, 0x03, 0x0c, 0x00, 0x33, 0x83, 0x81, 0x81, 0x01, 0x63, 0x18, 0xc6, 0x19, 0x6b, 0x36, 0x03,
|
||||
0x30, 0x03, 0x0c, 0x00, 0x33, 0xc3, 0x00, 0xc3, 0x00, 0x63, 0x18, 0x63, 0x33, 0x0b, 0x9c, 0x01, 0xe0, 0x01, 0x06, 0x00, 0x03, 0x60, 0x00, 0xc6, 0x80, 0x61, 0x18, 0x33, 0x33, 0x0b, 0xc0, 0x00,
|
||||
0xe0, 0x01, 0x03, 0x00, 0x03, 0x30, 0x00, 0xcc, 0xc0, 0x60, 0x18, 0x33, 0x33, 0x3e, 0x60, 0x00, 0xc0, 0x80, 0x01, 0x00, 0x03, 0x60, 0x00, 0xc6, 0x60, 0x30, 0x30, 0x33, 0x33, 0x68, 0x30, 0x07,
|
||||
0xc0, 0x80, 0x01, 0x00, 0x03, 0xc0, 0x00, 0x63, 0x60, 0x60, 0x18, 0x33, 0x1b, 0x68, 0x98, 0x0d, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x81, 0x61, 0x00, 0x60, 0x18, 0xe6, 0x0e, 0x6b, 0x8c, 0x0d,
|
||||
0xc0, 0x60, 0x80, 0x19, 0x33, 0x03, 0xc3, 0x60, 0x60, 0x60, 0x18, 0x06, 0x00, 0x6b, 0x86, 0x0d, 0xc0, 0xe0, 0xbf, 0x19, 0x33, 0x03, 0x66, 0x60, 0x60, 0x60, 0x18, 0x1c, 0x00, 0x3e, 0x03, 0x07,
|
||||
0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0xf0, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x60, 0x03, 0x00, 0x66, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x01, 0x33, 0xc3, 0x00, 0x0c, 0x7f, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x1e, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe0, 0x81, 0x7f, 0xc3, 0x80, 0x7f, 0x00, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1b, 0x1e, 0xc3, 0x3e, 0x0c, 0x7f, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0f, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x83, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0f, 0x00, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0d, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xff, 0x0d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const unsigned char GlyphData[] =
|
||||
{
|
||||
0x20, 0x4b, 0x80, 0x04, 0x21, 0x1e, 0x70, 0x05, 0x23, 0x4f, 0x80, 0x09, 0x24, 0x67, 0x70, 0x09, 0x25, 0x70, 0x70, 0x0d, 0x26, 0x03, 0x80, 0x0b, 0x28, 0x17, 0x80, 0x05, 0x29, 0x1c, 0x80, 0x05,
|
||||
0x2a, 0x0e, 0x80, 0x09, 0x2b, 0x26, 0x80, 0x09, 0x2c, 0x16, 0x70, 0x04, 0x2d, 0x21, 0x80, 0x05, 0x2e, 0x1a, 0x70, 0x04, 0x2f, 0x3d, 0x70, 0x04, 0x30, 0x6f, 0x24, 0x09, 0x31, 0x01, 0x37, 0x09,
|
||||
0x32, 0x0a, 0x37, 0x09, 0x33, 0x13, 0x37, 0x09, 0x34, 0x1c, 0x37, 0x09, 0x35, 0x25, 0x37, 0x09, 0x36, 0x2e, 0x37, 0x09, 0x37, 0x37, 0x37, 0x09, 0x38, 0x40, 0x37, 0x09, 0x39, 0x49, 0x37, 0x09,
|
||||
0x3a, 0x27, 0x70, 0x04, 0x3b, 0x23, 0x70, 0x04, 0x3c, 0x2b, 0x70, 0x09, 0x3d, 0x2f, 0x80, 0x09, 0x3e, 0x34, 0x70, 0x09, 0x3f, 0x41, 0x70, 0x0a, 0x40, 0x57, 0x70, 0x10, 0x41, 0x52, 0x37, 0x0c,
|
||||
0x42, 0x5e, 0x37, 0x0c, 0x43, 0x6a, 0x37, 0x0c, 0x44, 0x01, 0x4a, 0x0c, 0x45, 0x0d, 0x4a, 0x0b, 0x46, 0x18, 0x4a, 0x0a, 0x47, 0x22, 0x4a, 0x0d, 0x48, 0x2f, 0x4a, 0x0c, 0x49, 0x3b, 0x4a, 0x05,
|
||||
0x4a, 0x40, 0x4a, 0x09, 0x4b, 0x49, 0x4a, 0x0b, 0x4c, 0x54, 0x4a, 0x0a, 0x4d, 0x5e, 0x4a, 0x0e, 0x4e, 0x6c, 0x4a, 0x0c, 0x4f, 0x01, 0x5d, 0x0d, 0x50, 0x0e, 0x5d, 0x0b, 0x51, 0x19, 0x5d, 0x0d,
|
||||
0x52, 0x26, 0x5d, 0x0c, 0x53, 0x32, 0x5d, 0x0b, 0x54, 0x3d, 0x5d, 0x0a, 0x55, 0x47, 0x5d, 0x0c, 0x56, 0x53, 0x5d, 0x0b, 0x57, 0x5e, 0x5d, 0x0f, 0x58, 0x6d, 0x5d, 0x0b, 0x59, 0x01, 0x70, 0x0b,
|
||||
0x5a, 0x0c, 0x70, 0x0a, 0x5b, 0x41, 0x80, 0x05, 0x5d, 0x46, 0x80, 0x05, 0x5f, 0x38, 0x80, 0x09, 0x61, 0x01, 0x11, 0x0a, 0x62, 0x0b, 0x11, 0x0a, 0x63, 0x15, 0x11, 0x09, 0x64, 0x1e, 0x11, 0x0a,
|
||||
0x65, 0x28, 0x11, 0x0a, 0x66, 0x32, 0x11, 0x06, 0x67, 0x38, 0x11, 0x0a, 0x68, 0x42, 0x11, 0x0a, 0x69, 0x4c, 0x11, 0x04, 0x6a, 0x50, 0x11, 0x04, 0x6b, 0x54, 0x11, 0x09, 0x6c, 0x5d, 0x11, 0x04,
|
||||
0x6d, 0x61, 0x11, 0x0e, 0x6e, 0x6f, 0x11, 0x0a, 0x6f, 0x01, 0x24, 0x0a, 0x70, 0x0b, 0x24, 0x0a, 0x71, 0x15, 0x24, 0x0a, 0x72, 0x1f, 0x24, 0x07, 0x73, 0x26, 0x24, 0x09, 0x74, 0x2f, 0x24, 0x06,
|
||||
0x75, 0x35, 0x24, 0x0a, 0x76, 0x3f, 0x24, 0x09, 0x77, 0x48, 0x24, 0x0e, 0x78, 0x56, 0x24, 0x08, 0x79, 0x5e, 0x24, 0x09, 0x7a, 0x67, 0x24, 0x08, 0x7b, 0x4b, 0x70, 0x06, 0x7d, 0x51, 0x70, 0x06,
|
||||
0x00
|
||||
0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
|
||||
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
|
||||
0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5d, 0x5f, 0x61, 0x62, 0x63, 0x64,
|
||||
0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
|
||||
0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7d
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -105,45 +30,6 @@ bool TexFont::Initialize(lcContext* Context)
|
||||
return true;
|
||||
|
||||
mFontHeight = 16;
|
||||
mSDF = gSupportsShaderObjects;
|
||||
|
||||
// Keep the original binary atlas as a fixed-function fallback. SDF rendering
|
||||
// requires only the shader support LeoCAD already uses for normal rendering.
|
||||
if (!mSDF)
|
||||
{
|
||||
mTextureWidth = 128;
|
||||
mTextureHeight = 128;
|
||||
Image Image;
|
||||
Image.Allocate(mTextureWidth, mTextureHeight, lcPixelFormat::L8A8);
|
||||
for (unsigned int TexelIdx = 0; TexelIdx < sizeof(TextureData) * 8; TexelIdx++)
|
||||
{
|
||||
const unsigned char Texel = TextureData[TexelIdx / 8] & (1 << (TexelIdx % 8)) ? 255 : 0;
|
||||
Image.mData[TexelIdx * 2] = Image.mData[TexelIdx * 2 + 1] = Texel;
|
||||
}
|
||||
|
||||
const unsigned char* Ptr = GlyphData;
|
||||
while (*Ptr)
|
||||
{
|
||||
const unsigned char Glyph = *Ptr++;
|
||||
mGlyphs[Glyph].Left = *Ptr++;
|
||||
mGlyphs[Glyph].Bottom = *Ptr++;
|
||||
mGlyphs[Glyph].Width = *Ptr++;
|
||||
mGlyphs[Glyph].Right = mGlyphs[Glyph].Left + mGlyphs[Glyph].Width;
|
||||
mGlyphs[Glyph].Top = mGlyphs[Glyph].Bottom - mFontHeight;
|
||||
mGlyphs[Glyph].RenderWidth = mGlyphs[Glyph].Width;
|
||||
mGlyphs[Glyph].RenderHeight = mFontHeight;
|
||||
mGlyphs[Glyph].Offset = 0.0f;
|
||||
mGlyphs[Glyph].Left /= mTextureWidth;
|
||||
mGlyphs[Glyph].Right /= mTextureWidth;
|
||||
mGlyphs[Glyph].Top /= mTextureHeight;
|
||||
mGlyphs[Glyph].Bottom /= mTextureHeight;
|
||||
}
|
||||
|
||||
mTexture = new lcTexture();
|
||||
mTexture->SetImage(std::move(Image), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_POINT);
|
||||
mTexture->Upload(Context);
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr int Scale = 4, Padding = 8, TileWidth = 96, TileHeight = 80;
|
||||
mTextureWidth = mTextureHeight = 1024;
|
||||
@@ -156,13 +42,9 @@ bool TexFont::Initialize(lcContext* Context)
|
||||
Font.setStyleStrategy(QFont::PreferAntialias);
|
||||
const QFontMetrics Metrics(Font);
|
||||
|
||||
const unsigned char* Ptr = GlyphData;
|
||||
int GlyphIndex = 0;
|
||||
while (*Ptr)
|
||||
for (const unsigned char Glyph : GlyphData)
|
||||
{
|
||||
const unsigned char Glyph = *Ptr++;
|
||||
Ptr += 2; // Legacy atlas position; metrics now come from the vector font.
|
||||
Ptr++;
|
||||
const int Advance = Metrics.horizontalAdvance(QChar(Glyph));
|
||||
const int TileX = (GlyphIndex % 10) * TileWidth;
|
||||
const int TileY = (GlyphIndex / 10) * TileHeight;
|
||||
@@ -237,7 +119,6 @@ bool TexFont::Initialize(lcContext* Context)
|
||||
void TexFont::Reset()
|
||||
{
|
||||
mTexture = 0;
|
||||
mSDF = false;
|
||||
}
|
||||
|
||||
void TexFont::GetStringDimensions(int* cx, int* cy, const char* Text) const
|
||||
@@ -247,7 +128,7 @@ void TexFont::GetStringDimensions(int* cx, int* cy, const char* Text) const
|
||||
|
||||
while (*Text != 0)
|
||||
{
|
||||
Width += mGlyphs[(int)(*Text)].Width;
|
||||
Width += mGlyphs[static_cast<unsigned char>(*Text)].Width;
|
||||
Text++;
|
||||
}
|
||||
|
||||
@@ -266,7 +147,7 @@ void TexFont::PrintText(lcContext* Context, float Left, float Top, float Z, cons
|
||||
|
||||
while (*Text)
|
||||
{
|
||||
int ch = *Text;
|
||||
const unsigned char ch = static_cast<unsigned char>(*Text);
|
||||
const float GlyphLeft = Left + mGlyphs[ch].Offset;
|
||||
const float GlyphRight = GlyphLeft + mGlyphs[ch].RenderWidth;
|
||||
const float GlyphTop = Top - mGlyphs[ch].Offset;
|
||||
@@ -326,7 +207,7 @@ void TexFont::GetTriangles(const lcMatrix44& Transform, const char* Text, float*
|
||||
|
||||
for (const char* ch = Text; *ch; ch++)
|
||||
{
|
||||
const int Glyph = *ch;
|
||||
const unsigned char Glyph = static_cast<unsigned char>(*ch);
|
||||
Width += mGlyphs[Glyph].Width;
|
||||
}
|
||||
|
||||
@@ -336,7 +217,7 @@ void TexFont::GetTriangles(const lcMatrix44& Transform, const char* Text, float*
|
||||
|
||||
while (*Text)
|
||||
{
|
||||
int ch = *Text;
|
||||
const unsigned char ch = static_cast<unsigned char>(*Text);
|
||||
|
||||
const float GlyphLeft = Left + mGlyphs[ch].Offset;
|
||||
const float GlyphRight = GlyphLeft + mGlyphs[ch].RenderWidth;
|
||||
|
||||
@@ -10,11 +10,6 @@ public:
|
||||
return mTexture != nullptr;
|
||||
}
|
||||
|
||||
bool IsSDF() const
|
||||
{
|
||||
return mSDF;
|
||||
}
|
||||
|
||||
lcTexture* GetTexture() const
|
||||
{
|
||||
return mTexture;
|
||||
@@ -39,7 +34,6 @@ protected:
|
||||
int mTextureWidth;
|
||||
int mTextureHeight;
|
||||
int mFontHeight;
|
||||
bool mSDF = false;
|
||||
};
|
||||
|
||||
extern TexFont gTexFont;
|
||||
@@ -145,12 +145,6 @@ lcPreferencesDialog::lcPreferencesDialog(QWidget* Parent, lcPreferencesDialogOpt
|
||||
ui->edgeLines->setChecked(mOptions->Preferences.mDrawEdgeLines);
|
||||
ui->ConditionalLinesCheckBox->setChecked(mOptions->Preferences.mDrawConditionalLines);
|
||||
|
||||
if (!gSupportsShaderObjects)
|
||||
{
|
||||
ui->ConditionalLinesCheckBox->setChecked(false);
|
||||
ui->ConditionalLinesCheckBox->setEnabled(false);
|
||||
}
|
||||
|
||||
lcViewWidget* Widget = gMainWindow->GetActiveView()->GetWidget();
|
||||
QOpenGLContext* Context = Widget->context();
|
||||
QOpenGLFunctions* Functions = Context->functions();
|
||||
@@ -247,10 +241,36 @@ lcPreferencesDialog::lcPreferencesDialog(QWidget* Parent, lcPreferencesDialogOpt
|
||||
|
||||
ui->studStyleCombo->setCurrentIndex(static_cast<int>(mOptions->StudStyle));
|
||||
|
||||
if (!gSupportsShaderObjects)
|
||||
ui->ShadingMode->removeItem(static_cast<int>(lcShadingMode::DefaultLights));
|
||||
ui->ShadingMode->setCurrentIndex(static_cast<int>(mOptions->Preferences.mShadingMode));
|
||||
|
||||
if (!lcContext::SupportsDefaultLights())
|
||||
{
|
||||
QStandardItemModel* ShadingModel = qobject_cast<QStandardItemModel*>(ui->ShadingMode->model());
|
||||
QStandardItem* DefaultLightsItem = ShadingModel->item(static_cast<int>(lcShadingMode::DefaultLights));
|
||||
DefaultLightsItem->setEnabled(false);
|
||||
|
||||
const QString Message = tr("Default Lights is unavailable. Flat shading is used instead.");
|
||||
DefaultLightsItem->setToolTip(Message);
|
||||
ui->ShadingMode->setToolTip(Message);
|
||||
}
|
||||
|
||||
if (!lcContext::SupportsMaterial(lcMaterialType::UnlitViewSphere))
|
||||
{
|
||||
const std::array<QWidget*, 7> Controls =
|
||||
{
|
||||
ui->ViewSphereSizeCombo, ui->ViewSphereLocationCombo,
|
||||
ui->PreviewViewSphereSizeCombo, ui->PreviewViewSphereLocationCombo,
|
||||
ui->ViewSphereColorButton, ui->ViewSphereTextColorButton, ui->ViewSphereHighlightColorButton
|
||||
};
|
||||
const QString Message = tr("View sphere rendering is unavailable.");
|
||||
|
||||
for (QWidget* Control : Controls)
|
||||
{
|
||||
Control->setEnabled(false);
|
||||
Control->setToolTip(Message);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutlineSupported = false;
|
||||
|
||||
{
|
||||
@@ -710,12 +730,12 @@ void lcPreferencesDialog::GridLinesToggled()
|
||||
|
||||
void lcPreferencesDialog::PreviewViewSphereSizeComboCurrentIndexChanged(int Index)
|
||||
{
|
||||
ui->PreviewViewSphereLocationCombo->setEnabled(Index != 0);
|
||||
ui->PreviewViewSphereLocationCombo->setEnabled(Index != 0 && lcContext::SupportsMaterial(lcMaterialType::UnlitViewSphere));
|
||||
}
|
||||
|
||||
void lcPreferencesDialog::ViewSphereSizeComboCurrentIndexChanged(int Index)
|
||||
{
|
||||
ui->ViewSphereLocationCombo->setEnabled(Index != 0);
|
||||
ui->ViewSphereLocationCombo->setEnabled(Index != 0 && lcContext::SupportsMaterial(lcMaterialType::UnlitViewSphere));
|
||||
}
|
||||
|
||||
void lcPreferencesDialog::AutomateEdgeColorToggled()
|
||||
|
||||
Reference in new issue
Block a user