Minimal working shader

master
Jeremy HU 2022-09-20 22:48:22 +10:00
parent 58290a9b21
commit e3a412df3c
10 changed files with 101 additions and 32 deletions

View File

@ -0,0 +1,7 @@
#version 330
uniform vec4 defaultColor;
out vec4 fragColor;
void main()
{
fragColor = defaultColor;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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();

View File

@ -48,4 +48,5 @@ void ModelOffscreenRender::updateMesh(Model *mesh)
QImage ModelOffscreenRender::toImage(const QSize &size)
{
// TODO
return QImage();
}

View File

@ -1,3 +1,4 @@
#include <dust3d/base/debug.h>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#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);
}

View File

@ -1,5 +1,6 @@
#include <QOpenGLFunctions>
#include <QFile>
#include <dust3d/base/debug.h>
#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;
}

View File

@ -2,15 +2,20 @@
#define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
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<std::string, int> m_uniformLocationMap;
};
#endif

View File

@ -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 : "<Unknown>";
const char *shadingLanguageVersion = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
m_openGLShadingLanguageVersion = nullptr != shadingLanguageVersion ? shadingLanguageVersion : "<Unknown>";
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<ModelOpenGLProgram>();
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<ModelOpenGLProgram>();
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<ModelOpenGLObject>();
m_openglObject->update(std::unique_ptr<Model>(mesh));
if (!m_openGLObject)
m_openGLObject = std::make_unique<ModelOpenGLObject>();
m_openGLObject->update(std::unique_ptr<Model>(mesh));
emit renderParametersChanged();
update();
}

View File

@ -8,6 +8,7 @@
#include <QMutex>
#include <QVector2D>
#include <QTimer>
#include <QString>
#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<ModelOpenGLProgram> m_openglProgram;
std::unique_ptr<ModelOpenGLObject> m_openglObject;
std::unique_ptr<ModelOpenGLProgram> m_openGLProgram;
std::unique_ptr<ModelOpenGLObject> 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<QVector3D, QVector3D> 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