Merge branch 'dev-VirtualTexture'

dev-VirtualTexture
wuyize 2023-02-20 22:10:22 +08:00
commit f0ab4115c3
16 changed files with 10779 additions and 449 deletions

View File

@ -117,6 +117,7 @@
<ClCompile Include="src\Editor\ThirdPartyLib\SvgHelper.cpp" /> <ClCompile Include="src\Editor\ThirdPartyLib\SvgHelper.cpp" />
<ClCompile Include="src\Editor\util\PainterPathUtil.cpp" /> <ClCompile Include="src\Editor\util\PainterPathUtil.cpp" />
<ClCompile Include="src\Editor\util\SvgFileLoader.cpp" /> <ClCompile Include="src\Editor\util\SvgFileLoader.cpp" />
<ClCompile Include="src\gl.c" />
<ClCompile Include="src\IconWidget.cpp" /> <ClCompile Include="src\IconWidget.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
<ClCompile Include="src\MainWindow.cpp" /> <ClCompile Include="src\MainWindow.cpp" />
@ -144,6 +145,7 @@
<ClCompile Include="src\Renderer\RendererWidget.cpp" /> <ClCompile Include="src\Renderer\RendererWidget.cpp" />
<ClCompile Include="src\Renderer\Painting\ShortCutTree.cpp" /> <ClCompile Include="src\Renderer\Painting\ShortCutTree.cpp" />
<ClCompile Include="src\Renderer\Painting\StraightLine.cpp" /> <ClCompile Include="src\Renderer\Painting\StraightLine.cpp" />
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
<ClCompile Include="src\SvgParser.cpp" /> <ClCompile Include="src\SvgParser.cpp" />
<ClCompile Include="src\TitleWidget.cpp" /> <ClCompile Include="src\TitleWidget.cpp" />
<QtUic Include="EditorWidget.ui" /> <QtUic Include="EditorWidget.ui" />
@ -205,6 +207,7 @@
<ClInclude Include="src\Renderer\Painting\MaterialStyleStroke.h" /> <ClInclude Include="src\Renderer\Painting\MaterialStyleStroke.h" />
<ClInclude Include="src\Renderer\Painting\Painting.h" /> <ClInclude Include="src\Renderer\Painting\Painting.h" />
<ClInclude Include="src\Renderer\Preview\ElementRenderer.h" /> <ClInclude Include="src\Renderer\Preview\ElementRenderer.h" />
<ClInclude Include="src\Renderer\VirtualTextureManager.h" />
<ClInclude Include="src\SvgParser.h" /> <ClInclude Include="src\SvgParser.h" />
<QtMoc Include="src\TitleWidget.h" /> <QtMoc Include="src\TitleWidget.h" />
<QtMoc Include="src\IconWidget.h" /> <QtMoc Include="src\IconWidget.h" />

View File

@ -210,6 +210,12 @@
<ClCompile Include="src\Renderer\IblUtils.cpp"> <ClCompile Include="src\Renderer\IblUtils.cpp">
<Filter>Source Files\Renderer</Filter> <Filter>Source Files\Renderer</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp">
<Filter>Source Files\Renderer</Filter>
</ClCompile>
<ClCompile Include="src\gl.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h"> <QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -435,6 +441,9 @@
<ClInclude Include="src\Renderer\Painting\BaseStyle.h"> <ClInclude Include="src\Renderer\Painting\BaseStyle.h">
<Filter>Header Files\Renderer\Painting</Filter> <Filter>Header Files\Renderer\Painting</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\Renderer\VirtualTextureManager.h">
<Filter>Header Files\Renderer</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtRcc Include="res\MainWindow.qrc"> <QtRcc Include="res\MainWindow.qrc">

View File

@ -0,0 +1,311 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

File diff suppressed because one or more lines are too long

View File

@ -214,14 +214,14 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL
unsigned int hdrTexture = 0; unsigned int hdrTexture = 0;
if (data) if (data)
{ {
glGenTextures(1, &hdrTexture); glFunc->glGenTextures(1, &hdrTexture);
glBindTexture(GL_TEXTURE_2D, hdrTexture); glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data); glFunc->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data); stbi_image_free(data);
} }
@ -240,7 +240,7 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // enable pre-filter mipmap sampling (combatting visible dots artifact) glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // enable pre-filter mipmap sampling (combatting visible dots artifact)
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

View File

@ -1,38 +1,36 @@
#include "Mesh.h" #include "Mesh.h"
#include <qDebug> #include <qDebug>
using namespace Renderer; using namespace Renderer;
Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model)
Renderer::Vertex::Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords)
: Position(position.x, position.y, position.z)
, Normal(normal.x, normal.y, normal.z)
, TexCoords(texCoords.x, texCoords.y)
{
}
Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model)
: glFunc(glFunc) : glFunc(glFunc)
, shaderProgram(shaderProgram) , shaderProgram(shaderProgram)
, shadowProgram(shadowProgram) , shadowProgram(shadowProgram)
, VBO(QOpenGLBuffer::VertexBuffer) , VBO(QOpenGLBuffer::VertexBuffer)
, EBO(QOpenGLBuffer::IndexBuffer) , EBO(QOpenGLBuffer::IndexBuffer)
, model((float*)&model) , model(model)
{ {
//for (int i = 0; i < 4; i++) {
// for (int j = 0; j < 4; j++) {
// this->model(i, j) = model[i][j];
// }
//}
} }
void Mesh::draw() void Mesh::draw()
{ {
shaderProgram->bind(); if (shaderProgram->bind())
unsigned int diffuseNr = 1;
unsigned int specularNr = 1;
unsigned int normalNr = 1;
unsigned int heightNr = 1;
for (unsigned int i = 0; i < textures.size(); i++)
{ {
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元 glFunc->glActiveTexture(GL_TEXTURE0);
textures[i]->texture.bind(); glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor);
//qDebug() << name + number; glFunc->glActiveTexture(GL_TEXTURE1);
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i); glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness);
} glFunc->glActiveTexture(GL_TEXTURE2);
// 绘制网格 glFunc->glBindTexture(GL_TEXTURE_2D, textureNormal);
shaderProgram->setUniformValue("texture_basecolor", 0);
shaderProgram->setUniformValue("texture_metallic_roughness", 1);
shaderProgram->setUniformValue("texture_normal", 2);
QOpenGLVertexArrayObject::Binder bind(&VAO); QOpenGLVertexArrayObject::Binder bind(&VAO);
shaderProgram->setUniformValue("model", model); shaderProgram->setUniformValue("model", model);
@ -41,23 +39,14 @@ void Mesh::draw()
shaderProgram->release(); shaderProgram->release();
} }
}
void Mesh::drawShadow() void Mesh::drawShadow()
{ {
shadowProgram->bind(); if (shadowProgram->bind())
unsigned int diffuseNr = 1;
unsigned int specularNr = 1;
unsigned int normalNr = 1;
unsigned int heightNr = 1;
for (unsigned int i = 0; i < textures.size(); i++)
{ {
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元 glFunc->glActiveTexture(GL_TEXTURE0);
textures[i]->texture.bind(); glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor);
//qDebug() << name + number; shadowProgram->setUniformValue("texture_basecolor", 0);
shadowProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
}
// 绘制网格
QOpenGLVertexArrayObject::Binder bind(&VAO); QOpenGLVertexArrayObject::Binder bind(&VAO);
shadowProgram->setUniformValue("model", model); shadowProgram->setUniformValue("model", model);
@ -66,9 +55,9 @@ void Mesh::drawShadow()
shadowProgram->release(); shadowProgram->release();
} }
}
void Mesh::setupMesh() void Mesh::setupMesh()
{ {
shaderProgram->bind();
VAO.create(); VAO.create();
VAO.bind(); VAO.bind();
@ -81,23 +70,17 @@ void Mesh::setupMesh()
EBO.bind(); EBO.bind();
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int)); EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
if (shaderProgram->bind())
{
shaderProgram->enableAttributeArray(0); shaderProgram->enableAttributeArray(0);
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex)); shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(1); shaderProgram->enableAttributeArray(1);
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex)); shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(2); shaderProgram->enableAttributeArray(2);
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex)); shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
shaderProgram->enableAttributeArray(3);
shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(Vertex, Tangent), 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(4);
shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(Vertex, Bitangent), 3, sizeof(Vertex));
VAO.release();
shaderProgram->release(); shaderProgram->release();
} }
VAO.release();
}

View File

@ -9,10 +9,9 @@
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <assimp/Importer.hpp> #include <assimp/vector3.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "Drawable.h" #include "Drawable.h"
namespace Renderer namespace Renderer
{ {
struct Vertex struct Vertex
@ -20,8 +19,7 @@ namespace Renderer
QVector3D Position; QVector3D Position;
QVector3D Normal; QVector3D Normal;
QVector2D TexCoords; QVector2D TexCoords;
QVector3D Tangent; Vertex(const aiVector3D& position, const aiVector3D& Normal, const aiVector3D& TexCoords);
QVector3D Bitangent;
}; };
struct Texture struct Texture
@ -40,22 +38,23 @@ namespace Renderer
class Mesh : public Drawable class Mesh : public Drawable
{ {
public: public:
/* 网格数据 */ QVector<Vertex> vertices;
QVector<Vertex> vertices; //顶点数据 QVector<unsigned int> indices;
QVector<unsigned int> indices; //索引数组 //QVector<Texture*> textures;
QVector<Texture*> textures; //纹理数据 GLuint textureBasecolor;
QMatrix4x4 model; //模型矩阵 GLuint textureMetallicRoughness;
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口 GLuint textureNormal;
QOpenGLShaderProgram* shaderProgram, * shadowProgram; //着色器程序
/* 函数 */ QMatrix4x4 model;
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model); QOpenGLFunctions_4_5_Compatibility* glFunc;
QOpenGLShaderProgram* shaderProgram, * shadowProgram;
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model);
void draw() override; void draw() override;
void drawShadow() override; void drawShadow() override;
void setupMesh(); void setupMesh();
private: private:
/* 渲染数据 */
QOpenGLVertexArrayObject VAO; QOpenGLVertexArrayObject VAO;
QOpenGLBuffer VBO, EBO; QOpenGLBuffer VBO, EBO;

View File

@ -1,5 +1,6 @@
#include "Model.h" #include "Model.h"
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QTextCodec> #include <QTextCodec>
@ -48,10 +49,6 @@ Model::Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpen
Model::~Model() //销毁对象 Model::~Model() //销毁对象
{ {
for (auto& it : textures_loaded) {
it->texture.destroy();
delete it;
}
for (auto& it : meshes) { for (auto& it : meshes) {
delete it; delete it;
} }
@ -133,9 +130,11 @@ GLuint encodeZIndexAngle(GLuint zIndex, float angle)
{ {
return GLuint(angle / 360 * 65536 + zIndex * 65536); return GLuint(angle / 360 * 65536 + zIndex * 65536);
} }
Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model) Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
{ {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
QMatrix4x4 modelQ((float*)&model);
aiString str; aiString str;
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str); material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
@ -144,36 +143,22 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
{ {
qDebug() << str.C_Str() << "Replaced"; qDebug() << str.C_Str() << "Replaced";
// 初始化网格 // 初始化网格
PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, shadowProgram, model); PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, shadowProgram, modelQ);
// 遍历网格的每个顶点 // 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++) for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{ {
PaintingVertex vertex; if (mesh->mNormals && mesh->mTextureCoords[0])
vertex.Position = QVector3D(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); {
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
minX = std::min(minX, vertex.Position.x()); minX = std::min(minX, vertex.Position.x());
maxX = std::max(maxX, vertex.Position.x()); maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y()); minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y()); maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, vertex.Position.z()); minZ = std::min(minZ, vertex.Position.z());
maxZ = std::max(maxZ, vertex.Position.z()); maxZ = std::max(maxZ, vertex.Position.z());
// 法向量
if (mesh->mNormals)
vertex.Normal = QVector3D(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
// 纹理坐标
if (mesh->mTextureCoords[0])
vertex.TexCoords = QVector2D(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
if (mesh->mTangents)
vertex.Tangent = QVector3D(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
if (mesh->mBitangents)
vertex.Bitangent = QVector3D(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);;
m_mesh->vertices.push_back(vertex); m_mesh->vertices.push_back(vertex);
} }
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++) for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{ {
@ -191,131 +176,64 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
else else
{ {
// 初始化网格 // 初始化网格
Mesh* m_mesh = new Mesh(glFunc, shaderProgram, shadowProgram, model); Mesh* m_mesh = new Mesh(glFunc, shaderProgram, shadowProgram, modelQ);
// 遍历网格的每个顶点 // 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++) for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{ {
Vertex vertex; if (mesh->mNormals && mesh->mTextureCoords[0])
QVector3D vector; //将assimp的数据转化为QtOpenGL支持的数据 {
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
// 位置
vector.setX(mesh->mVertices[i].x);
vector.setY(mesh->mVertices[i].y);
vector.setZ(mesh->mVertices[i].z);
vertex.Position = vector;
minX = std::min(minX, vertex.Position.x()); minX = std::min(minX, vertex.Position.x());
maxX = std::max(maxX, vertex.Position.x()); maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y()); minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y()); maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, vertex.Position.z()); minZ = std::min(minZ, vertex.Position.z());
maxZ = std::max(maxZ, vertex.Position.z()); maxZ = std::max(maxZ, vertex.Position.z());
// 法向量
if (mesh->mNormals) {
vector.setX(mesh->mNormals[i].x);
vector.setY(mesh->mNormals[i].y);
vector.setZ(mesh->mNormals[i].z);
vertex.Normal = vector;
}
// 纹理坐标
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
{
QVector2D vec;
//一个顶点最多可以包含8个不同的纹理坐标。因此我们假设我们不用
//使用一个顶点可以有多个纹理坐标的模型,所以我们总是取第一个集合(0)。
vec.setX(mesh->mTextureCoords[0][i].x);
vec.setY(mesh->mTextureCoords[0][i].y);
vertex.TexCoords = vec;
}
else {
vertex.TexCoords = QVector2D(0, 0);
}
if (mesh->mTangents) {
// tangent
vector.setX(mesh->mTangents[i].x);
vector.setY(mesh->mTangents[i].y);
vector.setZ(mesh->mTangents[i].z);
vertex.Tangent = vector;
}
if (mesh->mBitangents) {
vector.setX(mesh->mBitangents[i].x);
vector.setY(mesh->mBitangents[i].y);
vector.setZ(mesh->mBitangents[i].z);
vertex.Bitangent = vector;
}
// bitangent
m_mesh->vertices.push_back(vertex); m_mesh->vertices.push_back(vertex);
} }
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
// 将所有面的索引数据添加到索引数组中 // 将所有面的索引数据添加到索引数组中
for (unsigned int j = 0; j < face.mNumIndices; j++) { for (auto face = mesh->mFaces; face < mesh->mFaces + mesh->mNumFaces; face++)
m_mesh->indices.push_back(face.mIndices[j]); for (auto indice = face->mIndices; indice < face->mIndices + face->mNumIndices; indice++)
} m_mesh->indices.push_back(*indice);
}
// 处理材质 // 处理材质
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor"); m_mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR);
for (auto& it : diffuseMaps) m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS);
m_mesh->textures.push_back(it); m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS);
QVector<Texture*> metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
for (auto& it : metalnessMaps)
m_mesh->textures.push_back(it);
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
for (auto& it : normalMaps)
m_mesh->textures.push_back(it);
m_mesh->setupMesh(); m_mesh->setupMesh();
return m_mesh; return m_mesh;
} }
} }
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName) GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type)
{ {
/// MeshÖ»Ö§³Öµ¥ÎÆÀí
if (!mat->GetTextureCount(type))
return 0;
QVector<Texture*> textures;
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
{
//qDebug() << typeName;
aiString str; aiString str;
mat->GetTexture(type, i, &str); mat->GetTexture(type, 0, &str);
const std::string path(str.C_Str());
auto iter = texturesLoaded.find(path);
if (iter != texturesLoaded.end())
return iter->second.textureId();
// 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理 QImage data(directory.filePath(path.c_str()));
bool skip = false; if (data.isNull())
for (unsigned int j = 0; j < textures_loaded.size(); j++) return 0;
{
if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0) //qDebug() << "Loading" << path.c_str();
{ auto [it, _] = texturesLoaded.emplace(std::piecewise_construct, std::make_tuple(path), std::make_tuple(QOpenGLTexture::Target2D));
textures.push_back(textures_loaded[j]); auto& texture = it->second;
skip = true; texture.create();
break; texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
} texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
} texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
if (!skip) texture.setData(data);
{ // 如果材质还没有加载,加载它 return texture.textureId();
Texture* texture = new Texture;
QImage data(directory.filePath(str.C_Str()));
if (!data.isNull()) {
texture->texture.setData(data);
texture->type = typeName;
texture->path = str.C_Str();
textures.push_back(texture);
textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
}
else {
qDebug() << "未能成功加载纹理:" << directory.filePath(str.C_Str());
}
}
}
return textures;
} }
GLuint Renderer::Model::loadPainting(std::string path) GLuint Renderer::Model::loadPainting(std::string path)

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "Mesh.h" #include "Mesh.h"
#include "Drawable.h" #include "Drawable.h"
#include "Painting/PaintingHelper.h" #include "Painting/PaintingHelper.h"
#include <QDir> #include <QDir>
#include <assimp/scene.h>
namespace Renderer namespace Renderer
{ {
@ -31,7 +31,8 @@ namespace Renderer
/* 模型数据 */ /* 模型数据 */
std::unordered_map<std::string, GLuint> paintingLoaded; std::unordered_map<std::string, GLuint> paintingLoaded;
QVector<Texture*> textures_loaded; //纹理 std::unordered_map<std::string, QOpenGLTexture> texturesLoaded;
//std::vector<Texture*> textures_loaded; //ÎÆÀí
QVector<Drawable*> meshes; //网格 QVector<Drawable*> meshes; //网格
QDir directory; //模型所在路径 QDir directory; //模型所在路径
@ -49,7 +50,7 @@ namespace Renderer
Drawable* processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model); Drawable* processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model);
//加载材质纹理 //加载材质纹理
QVector<Texture*> loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName); GLuint loadMaterialTextures(aiMaterial* mat, aiTextureType type);
GLuint loadPainting(std::string path); GLuint loadPainting(std::string path);
}; };

View File

@ -1,36 +1,39 @@
#include "PaintingMesh.h" #include "PaintingMesh.h"
using namespace Renderer; using namespace Renderer;
PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model) PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model)
: glFunc(glFunc) : glFunc(glFunc)
, shaderProgram(shaderProgram) , shaderProgram(shaderProgram)
, shadowProgram(shadowProgram) , shadowProgram(shadowProgram)
, VBO(QOpenGLBuffer::VertexBuffer) , VBO(QOpenGLBuffer::VertexBuffer)
, EBO(QOpenGLBuffer::IndexBuffer) , EBO(QOpenGLBuffer::IndexBuffer)
, model((float*)&model) , model(model)
{ {
} }
void PaintingMesh::draw() void PaintingMesh::draw()
{ {
shaderProgram->bind(); if (shaderProgram->bind())
{
QOpenGLVertexArrayObject::Binder bind(&VAO); QOpenGLVertexArrayObject::Binder bind(&VAO);
shaderProgram->setUniformValue("model", model); shaderProgram->setUniformValue("model", model);
EBO.bind(); EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shaderProgram->release(); shaderProgram->release();
} }
}
void PaintingMesh::drawShadow() void PaintingMesh::drawShadow()
{ {
shadowProgram->bind(); if (shadowProgram->bind())
{
QOpenGLVertexArrayObject::Binder bind(&VAO); QOpenGLVertexArrayObject::Binder bind(&VAO);
shadowProgram->setUniformValue("model", model); shadowProgram->setUniformValue("model", model);
EBO.bind(); EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shadowProgram->release(); shadowProgram->release();
} }
}
void PaintingMesh::setupMesh() void PaintingMesh::setupMesh()
{ {
shaderProgram->bind();
VAO.create(); VAO.create();
VAO.bind(); VAO.bind();
@ -38,30 +41,21 @@ void PaintingMesh::setupMesh()
EBO.create(); EBO.create();
VBO.bind(); VBO.bind();
VBO.allocate(vertices.data(), vertices.size() * sizeof(PaintingVertex)); VBO.allocate(vertices.data(), vertices.size() * sizeof(Vertex));
EBO.bind(); EBO.bind();
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int)); EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
if (shaderProgram->bind())
{
shaderProgram->enableAttributeArray(0); shaderProgram->enableAttributeArray(0);
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(PaintingVertex)); shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(1); shaderProgram->enableAttributeArray(1);
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(PaintingVertex, Normal), 3, sizeof(PaintingVertex)); shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(2); shaderProgram->enableAttributeArray(2);
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(PaintingVertex, TexCoords), 2, sizeof(PaintingVertex)); shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
shaderProgram->release();
shaderProgram->enableAttributeArray(1); }
shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(PaintingVertex, Tangent), 3, sizeof(PaintingVertex));
shaderProgram->enableAttributeArray(1);
shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(PaintingVertex, Bitangent), 3, sizeof(PaintingVertex));
VAO.release(); VAO.release();
shaderProgram->release();
} }

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include <QOpenGLFunctions_4_5_Compatibility> #include <QOpenGLFunctions_4_5_Compatibility>
#include <QString> #include <QString>
#include <QVector> #include <QVector>
@ -10,40 +9,30 @@
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "Drawable.h" #include "Drawable.h"
#include "Mesh.h"
namespace Renderer namespace Renderer
{ {
struct PaintingVertex
{
QVector3D Position;
QVector3D Normal;
QVector2D TexCoords;
QVector3D Tangent;
QVector3D Bitangent;
};
class PaintingMesh : public Drawable class PaintingMesh : public Drawable
{ {
public: public:
/* 网格数据 */ QVector<Vertex> vertices;
QVector<PaintingVertex> vertices; //顶点数据 QVector<GLuint> indices;
QVector<unsigned int> indices; //索引数组 GLuint textureBasecolor;
QMatrix4x4 model; //模型矩阵 GLuint textureMetallicRoughness;
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口 QMatrix4x4 model;
QOpenGLShaderProgram* shaderProgram, * shadowProgram; //着色器程序 QOpenGLFunctions_4_5_Compatibility* glFunc;
QOpenGLShaderProgram* shaderProgram, * shadowProgram;
GLuint paintingIndex; GLuint paintingIndex;
/* 函数 */
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model); PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model);
void draw() override; void draw() override;
void drawShadow() override; void drawShadow() override;
void setupMesh(); void setupMesh();
private: private:
/* 渲染数据 */
QOpenGLVertexArrayObject VAO; QOpenGLVertexArrayObject VAO;
QOpenGLBuffer VBO, EBO; QOpenGLBuffer VBO, EBO;

View File

@ -1,3 +1,4 @@
#include <glad/gl.h>
#include "RendererGLWidget.h" #include "RendererGLWidget.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -102,14 +103,17 @@ QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
void RendererGLWidget::initializeGL() void RendererGLWidget::initializeGL()
{ {
initializeOpenGLFunctions(); gl = std::make_unique<GladGLContext>();
QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>(); if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); }))
qDebug() << "GL_VERSION" << (char*)glGetString(GL_VERSION); qDebug() << "Failed to initialize GLAD";
glEnable(GL_DEPTH_TEST); QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>();
glDepthFunc(GL_LEQUAL); qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION);
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
glClearColor(0, 0, 0, 1); gl->Enable(GL_DEPTH_TEST);
gl->DepthFunc(GL_LEQUAL);
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
gl->ClearColor(0, 0, 0, 1);
shadowProgramPtr = new QOpenGLShaderProgram; shadowProgramPtr = new QOpenGLShaderProgram;
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert")) if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert"))
@ -192,11 +196,11 @@ void RendererGLWidget::initializeGL()
qDebug() << "ERROR:" << skyBoxProgramPtr->log(); qDebug() << "ERROR:" << skyBoxProgramPtr->log();
shadowProgramPtr->bind(); shadowProgramPtr->bind();
glGenBuffers(1, &lightSpaceMatricesUBO); gl->GenBuffers(1, &lightSpaceMatricesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO); gl->BindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(QMatrix4x4) * 16, nullptr, GL_STATIC_DRAW); gl->BufferData(GL_UNIFORM_BUFFER, sizeof(QMatrix4x4) * 16, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, lightSpaceMatricesUBO); gl->BindBufferBase(GL_UNIFORM_BUFFER, 0, lightSpaceMatricesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, 0); gl->BindBuffer(GL_UNIFORM_BUFFER, 0);
shadowProgramPtr->release(); shadowProgramPtr->release();
@ -250,11 +254,11 @@ void RendererGLWidget::initializeGL()
quadVBO.allocate(vertex, sizeof(vertex)); quadVBO.allocate(vertex, sizeof(vertex));
quadVBO.bind(); quadVBO.bind();
glEnableVertexAttribArray(0); gl->EnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), gl->VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
nullptr); nullptr);
glEnableVertexAttribArray(1); gl->EnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), gl->VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
reinterpret_cast<void*>(3 * sizeof(GLfloat))); reinterpret_cast<void*>(3 * sizeof(GLfloat)));
quadVBO.release(); quadVBO.release();
@ -266,7 +270,7 @@ void RendererGLWidget::paintGL()
{ {
QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>(); QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>();
glEnable(GL_CULL_FACE); gl->Enable(GL_CULL_FACE);
light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw))); light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
light.lightDirection.setY(sin(qDegreesToRadians(sunPitch))); light.lightDirection.setY(sin(qDegreesToRadians(sunPitch)));
@ -274,31 +278,31 @@ void RendererGLWidget::paintGL()
light.lightDirection.normalize(); light.lightDirection.normalize();
const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices(); const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices();
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO); gl->BindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
for (size_t i = 0; i < lightMatrices.size(); i++) for (size_t i = 0; i < lightMatrices.size(); i++)
{ {
glBufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data()); gl->BufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data());
} }
glBindBuffer(GL_UNIFORM_BUFFER, 0); gl->BindBuffer(GL_UNIFORM_BUFFER, 0);
{ {
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
glViewport(0, 0, shadowMapResolution, shadowMapResolution); gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
glClear(GL_DEPTH_BUFFER_BIT); gl->Clear(GL_DEPTH_BUFFER_BIT);
//glCullFace(GL_FRONT); //gl->CullFace(GL_FRONT);
if (model != nullptr) if (model != nullptr)
model->drawShadow(); model->drawShadow();
//glCullFace(GL_BACK); //gl->CullFace(GL_BACK);
glBindFramebuffer(GL_FRAMEBUFFER, 0); gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
} }
QMatrix4x4 projection; QMatrix4x4 projection;
projection.perspective(camera.Zoom, camera.Ratio, camera.NearPlane, camera.FarPlane); projection.perspective(camera.Zoom, camera.Ratio, camera.NearPlane, camera.FarPlane);
QMatrix4x4 view = camera.GetViewMatrix(); QMatrix4x4 view = camera.GetViewMatrix();
if (fboPtr->bind()) if (fboPtr->bind())
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, frameWidth, frameHeight); gl->Viewport(0, 0, frameWidth, frameHeight);
modelProgramPtr->bind(); modelProgramPtr->bind();
modelProgramPtr->setUniformValue("projection", projection); modelProgramPtr->setUniformValue("projection", projection);
@ -340,35 +344,35 @@ void RendererGLWidget::paintGL()
} }
GLuint paintingCompQuery; GLuint paintingCompQuery;
glGenQueries(1, &paintingCompQuery); gl->GenQueries(1, &paintingCompQuery);
glBeginQuery(GL_TIME_ELAPSED, paintingCompQuery); gl->BeginQuery(GL_TIME_ELAPSED, paintingCompQuery);
paintingCompProgramPtr->bind(); paintingCompProgramPtr->bind();
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); gl->BindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
glBindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); gl->BindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F); gl->BindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F);
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
paintingCompProgramPtr->release(); paintingCompProgramPtr->release();
glEndQuery(GL_TIME_ELAPSED); gl->EndQuery(GL_TIME_ELAPSED);
depthInitProgramPtr->bind(); depthInitProgramPtr->bind();
glActiveTexture(GL_TEXTURE0); gl->ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gbuffers[6]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]);
glBindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); gl->BindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
glDispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1); gl->DispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1);
depthInitProgramPtr->release(); depthInitProgramPtr->release();
depthMipmapProgramPtr->bind(); depthMipmapProgramPtr->bind();
for (int i = 0; i <= 3; i++) for (int i = 0; i <= 3; i++)
glBindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); gl->BindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
glDispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1); gl->DispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1);
for (int i = 0; i <= 3; i++) for (int i = 0; i <= 3; i++)
glBindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); gl->BindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
glDispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1); gl->DispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1);
depthMipmapProgramPtr->release(); depthMipmapProgramPtr->release();
shadowMappingProgramPtr->bind(); shadowMappingProgramPtr->bind();
@ -382,25 +386,25 @@ void RendererGLWidget::paintGL()
shadowMappingProgramPtr->setUniformValue("camPos", camera.Position); shadowMappingProgramPtr->setUniformValue("camPos", camera.Position);
shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
shadowMappingProgramPtr->setUniformValue("mainLightRadiance", mainLightRadiance); shadowMappingProgramPtr->setUniformValue("mainLightRadiance", mainLightRadiance);
/*glActiveTexture(GL_TEXTURE0); /*gl->ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);*/ gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);*/
glActiveTexture(GL_TEXTURE1); gl->ActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gbuffers[1]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]);
glActiveTexture(GL_TEXTURE2); gl->ActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gbuffers[2]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]);
glActiveTexture(GL_TEXTURE3); gl->ActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, gbuffers[3]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
glActiveTexture(GL_TEXTURE4); gl->ActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
glActiveTexture(GL_TEXTURE5); gl->ActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap); gl->BindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap);
glActiveTexture(GL_TEXTURE6); gl->ActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_CUBE_MAP, prefilterMap); gl->BindTexture(GL_TEXTURE_CUBE_MAP, prefilterMap);
glActiveTexture(GL_TEXTURE7); gl->ActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, brdfLUTTexture); gl->BindTexture(GL_TEXTURE_2D, brdfLUTTexture);
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); gl->BindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
shadowMappingProgramPtr->release(); shadowMappingProgramPtr->release();
/*ssgiProgramPtr->bind(); /*ssgiProgramPtr->bind();
@ -411,46 +415,46 @@ void RendererGLWidget::paintGL()
ssgiProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); ssgiProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
ssgiProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]); ssgiProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
ssgiProgramPtr->setUniformValue("rdSeed", QVector4D(rand(), rand(), rand(), rand())); ssgiProgramPtr->setUniformValue("rdSeed", QVector4D(rand(), rand(), rand(), rand()));
glActiveTexture(GL_TEXTURE0); gl->ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gbuffers[0]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);
glActiveTexture(GL_TEXTURE1); gl->ActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gbuffers[1]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]);
glActiveTexture(GL_TEXTURE2); gl->ActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gbuffers[2]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]);
glActiveTexture(GL_TEXTURE3); gl->ActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, gbuffers[3]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
glActiveTexture(GL_TEXTURE4); gl->ActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, gbuffers[7]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[7]);
glActiveTexture(GL_TEXTURE5); gl->ActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, gbuffers[8]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[8]);
glBindImageTexture(1, gbuffers[9], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); gl->BindImageTexture(1, gbuffers[9], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
ssgiProgramPtr->release();*/ ssgiProgramPtr->release();*/
glViewport(0, 0, frameWidth, frameHeight); gl->Viewport(0, 0, frameWidth, frameHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); //QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
finalProgramPtr->bind(); finalProgramPtr->bind();
finalProgramPtr->setUniformValue("exposure", exposure); finalProgramPtr->setUniformValue("exposure", exposure);
glActiveTexture(GL_TEXTURE0); gl->ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gbuffers[0]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);
quadVAO.bind(); quadVAO.bind();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
quadVAO.release(); quadVAO.release();
finalProgramPtr->release(); finalProgramPtr->release();
skyBoxProgramPtr->bind(); skyBoxProgramPtr->bind();
glDisable(GL_CULL_FACE); gl->Disable(GL_CULL_FACE);
skyBoxProgramPtr->setUniformValue("view", view); skyBoxProgramPtr->setUniformValue("view", view);
skyBoxProgramPtr->setUniformValue("projection", projection); skyBoxProgramPtr->setUniformValue("projection", projection);
skyBoxProgramPtr->setUniformValue("exposure", exposure); skyBoxProgramPtr->setUniformValue("exposure", exposure);
glActiveTexture(GL_TEXTURE0); gl->ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyCubemap); gl->BindTexture(GL_TEXTURE_CUBE_MAP, skyCubemap);
IblUtils::renderCube(glFunc); IblUtils::renderCube(glFunc);
skyBoxProgramPtr->release(); skyBoxProgramPtr->release();
GLuint paintingCompDuration; GLuint paintingCompDuration;
glGetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration); gl->GetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration);
clock_t currentFrame = std::clock(); clock_t currentFrame = std::clock();
deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC; deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC;
@ -495,11 +499,11 @@ void RendererGLWidget::resizeGL(int width, int height)
qDebug() << frameWidth << "x" << frameHeight; qDebug() << frameWidth << "x" << frameHeight;
camera.Ratio = (float)frameWidth / (float)frameHeight; camera.Ratio = (float)frameWidth / (float)frameHeight;
//qDebug() << devicePixelRatioF() << width << height; //qDebug() << devicePixelRatioF() << width << height;
//glViewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height); //gl->Viewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height);
if (fboPtr != nullptr) if (fboPtr != nullptr)
{ {
glDeleteTextures(9, gbuffers + 1); gl->DeleteTextures(9, gbuffers + 1);
delete fboPtr; delete fboPtr;
} }
@ -509,78 +513,78 @@ void RendererGLWidget::resizeGL(int width, int height)
//BaseColor //BaseColor
gbuffers[0] = fboPtr->texture(); gbuffers[0] = fboPtr->texture();
glGenTextures(9, gbuffers + 1); gl->GenTextures(9, gbuffers + 1);
//Normal //Normal
glBindTexture(GL_TEXTURE_2D, gbuffers[1]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0);
//Position //Position
glBindTexture(GL_TEXTURE_2D, gbuffers[2]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
//MetallicRoughness //MetallicRoughness
glBindTexture(GL_TEXTURE_2D, gbuffers[3]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
//gPaintingIndex //gPaintingIndex
glBindTexture(GL_TEXTURE_2D, gbuffers[4]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[4]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0);
//PaintingTexCoord //PaintingTexCoord
glBindTexture(GL_TEXTURE_2D, gbuffers[5]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[5]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, frameWidth, frameHeight, 0, GL_RG, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, frameWidth, frameHeight, 0, GL_RG, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0);
//Depth //Depth
glBindTexture(GL_TEXTURE_2D, gbuffers[6]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, frameWidth, frameHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, frameWidth, frameHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); gl->TexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbuffers[6], 0); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbuffers[6], 0);
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 }; GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
glDrawBuffers(6, attachments); gl->DrawBuffers(6, attachments);
//gbuffers = fboPtr->textures(); //gbuffers = fboPtr->textures();
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
qDebug() << "Framebuffer not complete!"; qDebug() << "Framebuffer not complete!";
//HiZ, not bind to fbo //HiZ, not bind to fbo
depthWidth = ceil(frameWidth / 64.) * 64; depthWidth = ceil(frameWidth / 64.) * 64;
depthHeight = ceil(frameHeight / 64.) * 64; depthHeight = ceil(frameHeight / 64.) * 64;
qDebug() << depthWidth << depthHeight; qDebug() << depthWidth << depthHeight;
glBindTexture(GL_TEXTURE_2D, gbuffers[7]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[7]);
for (int i = 0; i <= 6; i++) for (int i = 0; i <= 6; i++)
glTexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); gl->TexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
//DirectLight //DirectLight
glBindTexture(GL_TEXTURE_2D, gbuffers[8]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[8]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//InDirectLight //InDirectLight
glBindTexture(GL_TEXTURE_2D, gbuffers[9]); gl->BindTexture(GL_TEXTURE_2D, gbuffers[9]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
fboPtr->release(); fboPtr->release();
} }
@ -590,38 +594,38 @@ void RendererGLWidget::resizeGL(int width, int height)
if (shadowFboHandle != 0) if (shadowFboHandle != 0)
{ {
glDeleteTextures(1, &shadowGbuffer); gl->DeleteTextures(1, &shadowGbuffer);
glDeleteFramebuffers(1, &shadowFboHandle); gl->DeleteFramebuffers(1, &shadowFboHandle);
} }
//shadowMapResolution = 1.5 * std::max(frameWidth, frameHeight); //shadowMapResolution = 1.5 * std::max(frameWidth, frameHeight);
shadowMapResolution = 2048; shadowMapResolution = 2048;
glGenFramebuffers(1, &shadowFboHandle); gl->GenFramebuffers(1, &shadowFboHandle);
{ {
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
glGenTextures(1, &shadowGbuffer); gl->GenTextures(1, &shadowGbuffer);
//Depth //Depth
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
glTexImage3D( gl->TexImage3D(
GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, int(light.shadowCascadeLevels.size()), GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, int(light.shadowCascadeLevels.size()),
0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
/*glBindTexture(GL_TEXTURE_2D, shadowGbuffer); /*gl->BindTexture(GL_TEXTURE_2D, shadowGbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, gl->TexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);*/ shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);*/
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); gl->TexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowGbuffer, 0); gl->FramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowGbuffer, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowGbuffer, 0); //gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowGbuffer, 0);
glDrawBuffer(GL_NONE); gl->DrawBuffer(GL_NONE);
glReadBuffer(GL_NONE); gl->ReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
qDebug() << "ShadowFramebuffer not complete!"; qDebug() << "ShadowFramebuffer not complete!";
glBindFramebuffer(GL_FRAMEBUFFER, 0); gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
} }

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
@ -11,9 +10,12 @@
#include "Light.h" #include "Light.h"
#include "Model.h" #include "Model.h"
#include "Painting/PaintingHelper.h" #include "Painting/PaintingHelper.h"
struct GladGLContext;
namespace Renderer namespace Renderer
{ {
class RendererGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Core class RendererGLWidget : public QOpenGLWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -50,6 +52,7 @@ namespace Renderer
int shadowMapResolution; int shadowMapResolution;
float exposure = 0.8; float exposure = 0.8;
std::unique_ptr<GladGLContext> gl;
QOpenGLShaderProgram* shadowProgramPtr = nullptr; QOpenGLShaderProgram* shadowProgramPtr = nullptr;
QOpenGLShaderProgram* plainProgramPtr = nullptr; QOpenGLShaderProgram* plainProgramPtr = nullptr;
QOpenGLShaderProgram* modelProgramPtr = nullptr; QOpenGLShaderProgram* modelProgramPtr = nullptr;

View File

@ -0,0 +1,7 @@
#include "VirtualTextureManager.h"
#include <glad/gl.h>
Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl)
:gl(gl)
{
}

View File

@ -0,0 +1,17 @@
#pragma once
struct GladGLContext;
namespace Renderer
{
class VirtualTextureManager
{
public:
VirtualTextureManager(GladGLContext* gl);
private:
GladGLContext* gl;
};
}

File diff suppressed because it is too large Load Diff