From e3a412df3c74f1b96c8521dbf4331e54044e4cfc Mon Sep 17 00:00:00 2001 From: Jeremy HU Date: Tue, 20 Sep 2022 22:48:22 +1000 Subject: [PATCH] Minimal working shader --- application/shaders/model_core.frag | 7 +++ application/shaders/model_core.vert | 16 +++++ application/sources/about_widget.cc | 3 +- application/sources/main.cc | 4 +- application/sources/model_offscreen_render.cc | 1 + application/sources/model_opengl_object.cc | 2 + application/sources/model_opengl_program.cc | 26 +++++++-- application/sources/model_opengl_program.h | 5 ++ application/sources/model_widget.cc | 58 ++++++++++++------- application/sources/model_widget.h | 11 +++- 10 files changed, 101 insertions(+), 32 deletions(-) diff --git a/application/shaders/model_core.frag b/application/shaders/model_core.frag index e69de29b..f50d46e2 100644 --- a/application/shaders/model_core.frag +++ b/application/shaders/model_core.frag @@ -0,0 +1,7 @@ +#version 330 +uniform vec4 defaultColor; +out vec4 fragColor; +void main() +{ + fragColor = defaultColor; +} \ No newline at end of file diff --git a/application/shaders/model_core.vert b/application/shaders/model_core.vert index e69de29b..13829aeb 100644 --- a/application/shaders/model_core.vert +++ b/application/shaders/model_core.vert @@ -0,0 +1,16 @@ +#version 330 +layout(location = 0) in vec4 vertex; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec3 color; +layout(location = 3) in vec2 texCoord; +layout(location = 4) in float metalness; +layout(location = 5) in float roughness; +layout(location = 6) in vec3 tangent; +layout(location = 7) in float alpha; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; +void main() +{ + gl_Position = projectionMatrix * viewMatrix * modelMatrix * vertex; +} \ No newline at end of file diff --git a/application/sources/about_widget.cc b/application/sources/about_widget.cc index 0d4be99e..58285361 100644 --- a/application/sources/about_widget.cc +++ b/application/sources/about_widget.cc @@ -4,11 +4,12 @@ #include "about_widget.h" #include "version.h" +#include "model_widget.h" AboutWidget::AboutWidget() { QTextEdit *versionInfoLabel = new QTextEdit; - versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg((char *)glGetString(GL_VERSION)).arg((char *)glGetString(GL_SHADING_LANGUAGE_VERSION)).arg(QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile ? "true" : "false")); + versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg(ModelWidget::m_openGLVersion).arg(ModelWidget::m_openGLShadingLanguageVersion).arg(ModelWidget::m_openGLIsCoreProfile ? "true" : "false")); versionInfoLabel->setReadOnly(true); QVBoxLayout *mainLayout = new QVBoxLayout; diff --git a/application/sources/main.cc b/application/sources/main.cc index 463f0cf5..f7423862 100644 --- a/application/sources/main.cc +++ b/application/sources/main.cc @@ -22,8 +22,8 @@ int main(int argc, char *argv[]) QCoreApplication::setOrganizationName(APP_COMPANY); QCoreApplication::setOrganizationDomain(APP_HOMEPAGE_URL); - freopen("dust3d.log", "w", stdout); - setvbuf(stdout, 0, _IONBF, 0); + //freopen("dust3d.log", "w", stdout); + //setvbuf(stdout, 0, _IONBF, 0); DocumentWindow *firstWindow = DocumentWindow::createDocumentWindow(); diff --git a/application/sources/model_offscreen_render.cc b/application/sources/model_offscreen_render.cc index aae31935..299e38eb 100644 --- a/application/sources/model_offscreen_render.cc +++ b/application/sources/model_offscreen_render.cc @@ -48,4 +48,5 @@ void ModelOffscreenRender::updateMesh(Model *mesh) QImage ModelOffscreenRender::toImage(const QSize &size) { // TODO + return QImage(); } diff --git a/application/sources/model_opengl_object.cc b/application/sources/model_opengl_object.cc index a32692e5..14b1f4c3 100644 --- a/application/sources/model_opengl_object.cc +++ b/application/sources/model_opengl_object.cc @@ -1,3 +1,4 @@ +#include #include #include #include "model_opengl_object.h" @@ -15,6 +16,7 @@ void ModelOpenGLObject::draw() if (0 == m_meshTriangleVertexCount) return; QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); f->glDrawArrays(GL_TRIANGLES, 0, m_meshTriangleVertexCount); } diff --git a/application/sources/model_opengl_program.cc b/application/sources/model_opengl_program.cc index 10d2fae1..7c5f8f19 100644 --- a/application/sources/model_opengl_program.cc +++ b/application/sources/model_opengl_program.cc @@ -1,5 +1,6 @@ #include #include +#include #include "model_opengl_program.h" static const QString &loadShaderSource(const QString &name) @@ -16,6 +17,12 @@ static const QString &loadShaderSource(const QString &name) return insertResult.first->second; } +void ModelOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName) +{ + if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) + dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); +} + void ModelOpenGLProgram::load(bool isCoreProfile) { if (m_isLoaded) @@ -23,11 +30,11 @@ void ModelOpenGLProgram::load(bool isCoreProfile) m_isCoreProfile = isCoreProfile; if (m_isCoreProfile) { - addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/model_core.vert")); - addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/model_core.frag")); + addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/model_core.vert"); + addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/model_core.frag"); } else { - addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/model.vert")); - addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/model.frag")); + addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/model.vert"); + addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/model.frag"); } bindAttributeLocation("vertex", 0); bindAttributeLocation("normal", 1); @@ -39,6 +46,15 @@ void ModelOpenGLProgram::load(bool isCoreProfile) bindAttributeLocation("alpha", 7); link(); bind(); - m_isLoaded = true; } + +int ModelOpenGLProgram::getUniformLocationByName(const char *name) +{ + auto findLocation = m_uniformLocationMap.find(name); + if (findLocation != m_uniformLocationMap.end()) + return findLocation->second; + int location = uniformLocation(name); + m_uniformLocationMap.insert({std::string(name), location}); + return location; +} diff --git a/application/sources/model_opengl_program.h b/application/sources/model_opengl_program.h index 2edd1be6..86cdd022 100644 --- a/application/sources/model_opengl_program.h +++ b/application/sources/model_opengl_program.h @@ -2,15 +2,20 @@ #define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ #include +#include class ModelOpenGLProgram: public QOpenGLShaderProgram { public: void load(bool isCoreProfile=false); + int getUniformLocationByName(const char *name); private: + void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName); + bool m_isLoaded = false; bool m_isCoreProfile = false; + std::map m_uniformLocationMap; }; #endif diff --git a/application/sources/model_widget.cc b/application/sources/model_widget.cc index 7c18d148..2f96026f 100644 --- a/application/sources/model_widget.cc +++ b/application/sources/model_widget.cc @@ -13,6 +13,9 @@ int ModelWidget::m_defaultXRotation = 30 * 16; int ModelWidget::m_defaultYRotation = -45 * 16; int ModelWidget::m_defaultZRotation = 0; QVector3D ModelWidget::m_defaultEyePosition = QVector3D(0, 0, -2.5); +QString ModelWidget::m_openGLVersion = ""; +QString ModelWidget::m_openGLShadingLanguageVersion = ""; +bool ModelWidget::m_openGLIsCoreProfile = false; ModelWidget::ModelWidget(QWidget *parent) : QOpenGLWidget(parent) @@ -111,19 +114,14 @@ void ModelWidget::setZRotation(int angle) void ModelWidget::cleanup() { - if (!m_openglProgram) + if (!m_openGLProgram) return; makeCurrent(); - m_openglObject.reset(); - m_openglProgram.reset(); + m_openGLObject.reset(); + m_openGLProgram.reset(); doneCurrent(); } -void ModelWidget::initializeGL() -{ - connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup); -} - void ModelWidget::disableCullFace() { m_enableCullFace = false; @@ -134,6 +132,20 @@ void ModelWidget::setMoveToPosition(const QVector3D &moveToPosition) m_moveToPosition = moveToPosition; } +void ModelWidget::initializeGL() +{ + connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup); + + if (m_openGLVersion.isEmpty()) { + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + const char *openGLVersion = (const char *)f->glGetString(GL_VERSION); + m_openGLVersion = nullptr != openGLVersion ? openGLVersion : ""; + const char *shadingLanguageVersion = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + m_openGLShadingLanguageVersion = nullptr != shadingLanguageVersion ? shadingLanguageVersion : ""; + m_openGLIsCoreProfile = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; + } +} + void ModelWidget::paintGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); @@ -157,18 +169,22 @@ void ModelWidget::paintGL() m_camera.setToIdentity(); m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z()); - if (!m_openglProgram) { - m_openglProgram = std::make_unique(); - const char *openglVersion = (const char *)f->glGetString(GL_VERSION); - m_openglProgram->load(nullptr != openglVersion && - '\0' != openglVersion[0] && - format().profile() == QSurfaceFormat::CoreProfile); + if (!m_openGLProgram) { + m_openGLProgram = std::make_unique(); + m_openGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile); } - m_openglProgram->bind(); - if (m_openglObject) - m_openglObject->draw(); - m_openglProgram->release(); + m_openGLProgram->bind(); + + m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("projectionMatrix"), m_projection); + m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("modelMatrix"), m_world); + m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("viewMatrix"), m_camera); + m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("defaultColor"), QVector4D(1.0, 1.0, 1.0, 1.0)); + + if (m_openGLObject) + m_openGLObject->draw(); + + m_openGLProgram->release(); } void ModelWidget::updateProjectionMatrix() @@ -408,9 +424,9 @@ void ModelWidget::setMousePickRadius(float radius) void ModelWidget::updateMesh(Model *mesh) { - if (!m_openglObject) - m_openglObject = std::make_unique(); - m_openglObject->update(std::unique_ptr(mesh)); + if (!m_openGLObject) + m_openGLObject = std::make_unique(); + m_openGLObject->update(std::unique_ptr(mesh)); emit renderParametersChanged(); update(); } diff --git a/application/sources/model_widget.h b/application/sources/model_widget.h index 6c082362..ff8ffde8 100644 --- a/application/sources/model_widget.h +++ b/application/sources/model_widget.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "model.h" #include "model_opengl_program.h" #include "model_opengl_object.h" @@ -55,6 +56,7 @@ public: int zRot(); const QVector3D &eyePosition(); const QVector3D &moveToPosition(); + const QString &openGLVersion(); public slots: void setXRotation(int angle); void setYRotation(int angle); @@ -79,8 +81,8 @@ private: int m_yRot = m_defaultYRotation; int m_zRot = m_defaultZRotation; int m_directionOnMoveStart = 0; - std::unique_ptr m_openglProgram; - std::unique_ptr m_openglObject; + std::unique_ptr m_openGLProgram; + std::unique_ptr m_openGLObject; bool m_moveStarted = false; bool m_moveEnabled = true; bool m_zoomEnabled = true; @@ -104,8 +106,8 @@ private: bool m_moveAndZoomByWindow = true; bool m_enableCullFace = true; bool m_notGraphics = false; + std::pair screenPositionToMouseRay(const QPoint &screenPosition); -private: void updateProjectionMatrix(); void normalizeAngle(int &angle); public: @@ -113,6 +115,9 @@ public: static int m_defaultYRotation; static int m_defaultZRotation; static QVector3D m_defaultEyePosition; + static QString m_openGLVersion; + static QString m_openGLShadingLanguageVersion; + static bool m_openGLIsCoreProfile; }; #endif