karlis 2023-02-23 22:13:32 +08:00
commit abe1ee02c1
18 changed files with 10833 additions and 470 deletions

View File

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

View File

@ -210,6 +210,12 @@
<ClCompile Include="src\Renderer\IblUtils.cpp">
<Filter>Source Files\Renderer</Filter>
</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>
<QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -435,6 +441,9 @@
<ClInclude Include="src\Renderer\Painting\BaseStyle.h">
<Filter>Header Files\Renderer\Painting</Filter>
</ClInclude>
<ClInclude Include="src\Renderer\VirtualTextureManager.h">
<Filter>Header Files\Renderer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<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;
if (data)
{
glGenTextures(1, &hdrTexture);
glBindTexture(GL_TEXTURE_2D, hdrTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data);
glFunc->glGenTextures(1, &hdrTexture);
glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
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_T, 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);

View File

@ -1,74 +1,63 @@
#include "Mesh.h"
#include <qDebug>
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)
, shaderProgram(shaderProgram)
, shadowProgram(shadowProgram)
, VBO(QOpenGLBuffer::VertexBuffer)
, 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()
{
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++)
if (shaderProgram->bind())
{
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
textures[i]->texture.bind();
//qDebug() << name + number;
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
glFunc->glActiveTexture(GL_TEXTURE0);
glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor);
glFunc->glActiveTexture(GL_TEXTURE1);
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);
shaderProgram->setUniformValue("model", model);
EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shaderProgram->release();
}
// 绘制网格
QOpenGLVertexArrayObject::Binder bind(&VAO);
shaderProgram->setUniformValue("model", model);
EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shaderProgram->release();
}
void Mesh::drawShadow()
{
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++)
if (shadowProgram->bind())
{
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
textures[i]->texture.bind();
//qDebug() << name + number;
shadowProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
glFunc->glActiveTexture(GL_TEXTURE0);
glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor);
shadowProgram->setUniformValue("texture_basecolor", 0);
QOpenGLVertexArrayObject::Binder bind(&VAO);
shadowProgram->setUniformValue("model", model);
EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shadowProgram->release();
}
// 绘制网格
QOpenGLVertexArrayObject::Binder bind(&VAO);
shadowProgram->setUniformValue("model", model);
EBO.bind();
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
shadowProgram->release();
}
void Mesh::setupMesh()
{
shaderProgram->bind();
VAO.create();
VAO.bind();
@ -81,23 +70,17 @@ void Mesh::setupMesh()
EBO.bind();
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
shaderProgram->enableAttributeArray(0);
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(1);
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(2);
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));
if (shaderProgram->bind())
{
shaderProgram->enableAttributeArray(0);
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(1);
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
shaderProgram->enableAttributeArray(2);
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
shaderProgram->release();
}
VAO.release();
shaderProgram->release();
}

View File

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

View File

@ -1,5 +1,6 @@
#include "Model.h"
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <QOpenGLTexture>
#include <QOpenGLContext>
#include <QTextCodec>
@ -48,10 +49,6 @@ Model::Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpen
Model::~Model() //销毁对象
{
for (auto& it : textures_loaded) {
it->texture.destroy();
delete it;
}
for (auto& it : meshes) {
delete it;
}
@ -133,9 +130,11 @@ GLuint encodeZIndexAngle(GLuint zIndex, float angle)
{
return GLuint(angle / 360 * 65536 + zIndex * 65536);
}
Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
{
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
QMatrix4x4 modelQ((float*)&model);
aiString str;
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
@ -144,35 +143,21 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
{
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++)
{
PaintingVertex vertex;
vertex.Position = QVector3D(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
minX = std::min(minX, vertex.Position.x());
maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, 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);
if (mesh->mNormals && mesh->mTextureCoords[0])
{
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
minX = std::min(minX, vertex.Position.x());
maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, vertex.Position.z());
maxZ = std::max(maxZ, vertex.Position.z());
m_mesh->vertices.push_back(vertex);
}
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
@ -191,131 +176,64 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
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++)
{
Vertex vertex;
QVector3D vector; //将assimp的数据转化为QtOpenGL支持的数据
// 位置
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());
maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, 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?
if (mesh->mNormals && mesh->mTextureCoords[0])
{
QVector2D vec;
//一个顶点最多可以包含8个不同的纹理坐标。因此我们假设我们不用
//使用一个顶点可以有多个纹理坐标的模型,所以我们总是取第一个集合(0)。
vec.setX(mesh->mTextureCoords[0][i].x);
vec.setY(mesh->mTextureCoords[0][i].y);
vertex.TexCoords = vec;
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
minX = std::min(minX, vertex.Position.x());
maxX = std::max(maxX, vertex.Position.x());
minY = std::min(minY, vertex.Position.y());
maxY = std::max(maxY, vertex.Position.y());
minZ = std::min(minZ, vertex.Position.z());
maxZ = std::max(maxZ, vertex.Position.z());
m_mesh->vertices.push_back(vertex);
}
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);
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
// 将所有面的索引数据添加到索引数组中
for (unsigned int j = 0; j < face.mNumIndices; j++) {
m_mesh->indices.push_back(face.mIndices[j]);
}
}
// 将所有面的索引数据添加到索引数组中
for (auto face = mesh->mFaces; face < mesh->mFaces + mesh->mNumFaces; face++)
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");
for (auto& it : diffuseMaps)
m_mesh->textures.push_back(it);
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->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR);
m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS);
m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS);
m_mesh->setupMesh();
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;
aiString 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();
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
{
//qDebug() << typeName;
aiString str;
mat->GetTexture(type, i, &str);
QImage data(directory.filePath(path.c_str()));
if (data.isNull())
return 0;
// 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理
bool skip = false;
for (unsigned int j = 0; j < textures_loaded.size(); j++)
{
if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0)
{
textures.push_back(textures_loaded[j]);
skip = true;
break;
}
}
if (!skip)
{ // 如果材质还没有加载,加载它
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;
//qDebug() << "Loading" << path.c_str();
auto [it, _] = texturesLoaded.emplace(std::piecewise_construct, std::make_tuple(path), std::make_tuple(QOpenGLTexture::Target2D));
auto& texture = it->second;
texture.create();
texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
texture.setData(data);
return texture.textureId();
}
GLuint Renderer::Model::loadPainting(std::string path)

View File

@ -1,9 +1,9 @@
#pragma once
#include "Mesh.h"
#include "Drawable.h"
#include "Painting/PaintingHelper.h"
#include <QDir>
#include <assimp/scene.h>
namespace Renderer
{
@ -31,7 +31,8 @@ namespace Renderer
/* 模型数据 */
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; //网格
QDir directory; //模型所在路径
@ -49,7 +50,7 @@ namespace Renderer
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);
};

View File

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

View File

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

View File

@ -37,15 +37,15 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
switch (element.type)
{
case QPainterPath::MoveToElement:
qDebug() << "MoveToElement";
qDebug() << element;
//qDebug() << "MoveToElement";
//qDebug() << element;
pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity()));
pathBuffer.push_back(glm::vec2(element.x, element.y));
break;
case QPainterPath::LineToElement:
{
qDebug() << "LineToElement";
qDebug() << element;
//qDebug() << "LineToElement";
//qDebug() << element;
glm::vec2 end = glm::vec2(element.x, element.y);
glm::vec2 mid = (pathBuffer.back() + end) / 2.f;
pathBuffer.push_back(mid);
@ -55,14 +55,14 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
}
case QPainterPath::CurveToElement:
{
qDebug() << "CurveToElement";
qDebug() << element;
//qDebug() << "CurveToElement";
//qDebug() << element;
glm::vec2 p1 = glm::vec2(element.x, element.y);
element = path.elementAt(++i);
qDebug() << element;
//qDebug() << element;
glm::vec2 p2 = glm::vec2(element.x, element.y);
element = path.elementAt(++i);
qDebug() << element;
//qDebug() << element;
glm::vec2 p3 = glm::vec2(element.x, element.y);
if (p3 != pathBuffer.back())
{

View File

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

View File

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

View File

@ -2,26 +2,59 @@
#include <QGuiApplication>
#include <QtWidgets/QApplication>
#include <FramelessHelper/Core/private/framelessconfig_p.h>
#include <iostream>
#include <format>
#include "consoleapi2.h"
extern "C"
{
_declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
_declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
}
FRAMELESSHELPER_USE_NAMESPACE
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
switch (type)
{
case QtInfoMsg:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
break;
case QtDebugMsg:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
break;
case QtWarningMsg:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
break;
case QtCriticalMsg:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
break;
case QtFatalMsg:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
break;
}
std::cout << std::format("{}({},{}) {}\n",
QString(context.file).splitRef("\\").back().toLocal8Bit().data(),
context.line,
QString(context.function).splitRef("(").first().split(" ").back().split(":").back().toLocal8Bit().data(),
msg.toStdString());
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
int main(int argc, char* argv[])
{
//FramelessHelper::Widgets::initialize();
FramelessHelper::Core::initialize();
//QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv);
//FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
MainWindow w;
w.show();
return a.exec();
qInstallMessageHandler(messageHandler);
//FramelessHelper::Widgets::initialize();
FramelessHelper::Core::initialize();
//QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv);
//FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
MainWindow w;
w.show();
return a.exec();
}