mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
Box/Quad clone methods
Phong lighting shaders using multi draw indirect rendering
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
#include "box.h"
|
||||
#include "root.h"
|
||||
|
||||
namespace vb01{
|
||||
Box::Box(Vector3 size){
|
||||
setSize(size);
|
||||
Box::Box(Vector3 sz) : size(sz){
|
||||
init();
|
||||
}
|
||||
|
||||
void Box::setSize(Vector3 size){
|
||||
this->size = size;
|
||||
Box::Box(Box *b){
|
||||
size = b->getSize();
|
||||
meshBase = b->getMeshBase();
|
||||
}
|
||||
|
||||
void Box::init(){
|
||||
Vector3 *pos = new Vector3[8];
|
||||
pos[0] = Vector3(size.x / 2, size.y / 2, size.z / 2);
|
||||
pos[1] = Vector3(-size.x / 2, size.y / 2, size.z / 2);
|
||||
@@ -67,5 +71,7 @@ namespace vb01{
|
||||
}
|
||||
|
||||
meshBase = MeshData(pos, nullptr, nullptr, nullptr, 8, norm, vertices, indices, numTris);
|
||||
Root *root = Root::getSingleton();
|
||||
root->initVertexDataOnGpu(meshBase, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,13 @@ namespace vb01{
|
||||
class Box : public Mesh{
|
||||
public:
|
||||
Box(Vector3);
|
||||
void setSize(Vector3);
|
||||
inline Box* clone(){return new Box(this);}
|
||||
inline void setSize(Vector3 size){this->size = size;}
|
||||
inline Vector3 getSize(){return size;}
|
||||
private:
|
||||
Box(Box*);
|
||||
void init();
|
||||
|
||||
Vector3 size;
|
||||
};
|
||||
}
|
||||
|
||||
+7
-7
@@ -121,13 +121,13 @@ int main(){
|
||||
* The AnimationController plays the animations set in the AnimationChannel objects.
|
||||
* AnimationChannel objects require an animation and animatable objects, e.g. textures to work.
|
||||
*/
|
||||
AnimationController *controller = AnimationController::getSingleton();
|
||||
controller->addAnimation(anim);
|
||||
AnimationChannel *channel = new AnimationChannel();
|
||||
controller->addAnimationChannel(channel);
|
||||
channel->addAnimatable(driver);
|
||||
channel->setAnimationName(animName);
|
||||
channel->setLoop(true);
|
||||
//AnimationController *controller = AnimationController::getSingleton();
|
||||
//controller->addAnimation(anim);
|
||||
//AnimationChannel *channel = new AnimationChannel();
|
||||
//controller->addAnimationChannel(channel);
|
||||
//channel->addAnimatable(driver);
|
||||
//channel->setAnimationName(animName);
|
||||
//channel->setLoop(true);
|
||||
|
||||
while(true){
|
||||
root->update();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "material.h"
|
||||
#include "mesh.h"
|
||||
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <ext.hpp>
|
||||
#include <iostream>
|
||||
@@ -174,7 +174,7 @@ namespace vb01{
|
||||
else
|
||||
depthMapShader->setMat4(proj * view, "lightMat");
|
||||
|
||||
mesh->render();
|
||||
//mesh->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,4 +1,5 @@
|
||||
#include "lineRenderer.h"
|
||||
#include "camera.h"
|
||||
#include "root.h"
|
||||
|
||||
#include "glad.h"
|
||||
@@ -41,10 +42,10 @@ namespace vb01{
|
||||
shader->setMat4(proj, "proj");
|
||||
shader->setMat4(view, "view");
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(l.start.x, l.start.y, l.start.z);
|
||||
glVertex3f(l.end.x, l.end.y, l.end.z);
|
||||
glEnd();
|
||||
//glBegin(GL_LINES);
|
||||
//glVertex3f(l.start.x, l.start.y, l.start.z);
|
||||
//glVertex3f(l.end.x, l.end.y, l.end.z);
|
||||
//glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
#include "node.h"
|
||||
#include "box.h"
|
||||
#include "quad.h"
|
||||
#include "camera.h"
|
||||
#include "texture.h"
|
||||
#include "skeleton.h"
|
||||
#include "animation.h"
|
||||
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
@@ -50,11 +51,11 @@ namespace vb01{
|
||||
}
|
||||
|
||||
void Mesh::updateVerts(MeshData meshData){
|
||||
glBindBuffer(GL_ARRAY_BUFFER, meshData.VBO);
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, meshData.VBO);
|
||||
|
||||
MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::GpuVertex) * meshBase.numTris, glVertData);
|
||||
delete glVertData;
|
||||
//MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
|
||||
//glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::GpuVertex) * meshBase.numTris, glVertData);
|
||||
//delete glVertData;
|
||||
}
|
||||
|
||||
void Mesh::update(){
|
||||
@@ -89,12 +90,12 @@ namespace vb01{
|
||||
Shader *shader = material->getShader();
|
||||
material->update();
|
||||
|
||||
shader->setBool(castShadow, "castShadow");
|
||||
shader->setBool(skeleton, "animated");
|
||||
shader->setMat4(view, "view");
|
||||
shader->setMat4(proj, "proj");
|
||||
shader->setVec3(camPos, "camPos");
|
||||
shader->setMat4(model, "model");
|
||||
//shader->setBool(castShadow, "castShadow");
|
||||
//shader->setBool(skeleton, "animated");
|
||||
//shader->setMat4(view, "view");
|
||||
//shader->setMat4(proj, "proj");
|
||||
//shader->setVec3(camPos, "camPos");
|
||||
//shader->setMat4(model, "model");
|
||||
|
||||
if(skeleton)
|
||||
updateSkeleton(shader);
|
||||
@@ -111,8 +112,6 @@ namespace vb01{
|
||||
if(node)
|
||||
shader->setVec3(pos, "pos");
|
||||
}
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
void Mesh::updateShapeKeys(Shader *shader){
|
||||
@@ -228,7 +227,7 @@ namespace vb01{
|
||||
if(skybox) {
|
||||
glDepthMask(GL_FALSE);
|
||||
glCullFace(GL_FRONT);
|
||||
skybox->render();
|
||||
//root->renderMesh(skybox);
|
||||
glDepthMask(GL_TRUE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
@@ -261,7 +260,7 @@ namespace vb01{
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glCullFace(GL_FRONT);
|
||||
root->getIblBox()->render();
|
||||
//root->renderMesh(root->getIblBox());
|
||||
glDepthMask(GL_TRUE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
@@ -301,7 +300,7 @@ namespace vb01{
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glCullFace(GL_FRONT);
|
||||
root->getIblBox()->render();
|
||||
//root->getIblBox()->renderMesh();
|
||||
glDepthMask(GL_TRUE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
@@ -326,7 +325,7 @@ namespace vb01{
|
||||
brdfIntegrationShader->setUnsignedInt(numSamples, "numSamples");
|
||||
|
||||
Root *root = Root::getSingleton();
|
||||
root->getBrdfLutPlane()->render();
|
||||
//root->renderMesh(root->getBrdfLutPlane());
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *root->getRBO());
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, *root->getFBO());
|
||||
@@ -356,12 +355,6 @@ namespace vb01{
|
||||
postfilterMap->select(postFilterId);
|
||||
}
|
||||
|
||||
void Mesh::render(){
|
||||
glBindVertexArray(meshBase.VAO);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL);
|
||||
glDrawElements(GL_TRIANGLES, 3 * meshBase.numTris, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
void Mesh::setReflect(bool reflect){
|
||||
this->reflect = reflect;
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace vb01{
|
||||
~Mesh();
|
||||
void updateVerts(MeshData);
|
||||
virtual void update();
|
||||
void render();
|
||||
void setReflect(bool);
|
||||
inline void setMaterial(Material *mat){this->material = mat;}
|
||||
inline void setCastShadow(bool castShadow){this->castShadow = castShadow;}
|
||||
inline void setReflective(bool r){this->reflective = r;}
|
||||
inline void setWireframe(bool w){this->wireframe = w;}
|
||||
inline bool isWireframe(){return wireframe;}
|
||||
inline void setSkeleton(Skeleton *sk){this->skeleton = sk;}
|
||||
inline Material* getMaterial(){return material;}
|
||||
inline bool isReflective(){return reflective;}
|
||||
@@ -38,7 +38,7 @@ namespace vb01{
|
||||
inline Texture* getIrradianceMap(){return irradianceMap;}
|
||||
inline Texture* getPostfilterMap(){return postfilterMap;}
|
||||
inline Texture* getBrdfIntegrationMap(){return brdfIntegrationMap;}
|
||||
inline MeshData getMeshBase(){return meshBase;}
|
||||
inline MeshData& getMeshBase(){return meshBase;}
|
||||
private:
|
||||
void initFramebuffer(u32&, u32&, int);
|
||||
void updateSkeleton(Shader*);
|
||||
@@ -61,6 +61,7 @@ namespace vb01{
|
||||
Skeleton *skeleton = nullptr;
|
||||
protected:
|
||||
Mesh(){}
|
||||
virtual void init(){}
|
||||
|
||||
MeshData meshBase;
|
||||
int numShapeKeys = 0;
|
||||
|
||||
+31
-50
@@ -1,6 +1,7 @@
|
||||
#include "meshData.h"
|
||||
#include "root.h"
|
||||
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
@@ -40,43 +41,7 @@ namespace vb01{
|
||||
fullSkeletonName(fsn),
|
||||
shapeKeys(sk),
|
||||
numShapeKeys(nsk)
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
u32 size = sizeof(MeshData::GpuVertex);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
MeshData::GpuVertex *glVertData = toGpuVerts();
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * numTris * size, glVertData, GL_DYNAMIC_DRAW);
|
||||
delete glVertData;
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * numTris * sizeof(u32), indices, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size, (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, norm)));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, uv)));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, tan)));
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, biTan)));
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, weights)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, boneIndices)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
for(int i = 0; i < numShapeKeys; i++){
|
||||
glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, shapeKeyOffsets) + 3 * i * sizeof(float)));
|
||||
glEnableVertexAttribArray(7 + i);
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
void MeshData::ShapeKey::animate(float value, KeyframeChannel keyframeChannel){
|
||||
switch(keyframeChannel.type){
|
||||
@@ -92,29 +57,45 @@ namespace vb01{
|
||||
}
|
||||
}
|
||||
|
||||
MeshData::GpuVertex* MeshData::toGpuVerts(){
|
||||
//TODO replace number of max bone influences literal
|
||||
vector<MeshData::GpuVertex> MeshData::toGpuVerts(){
|
||||
int numVertices = 3 * numTris;
|
||||
GpuVertex *vertData = new GpuVertex[numVertices];
|
||||
vector<GpuVertex> vertData;
|
||||
|
||||
for(int i = 0; i < numVertices; i++){
|
||||
vertData[i].pos = *vertices[i].pos;
|
||||
vertData[i].norm = *vertices[i].norm;
|
||||
vertData[i].tan = vertices[i].tan;
|
||||
vertData[i].biTan = vertices[i].biTan;
|
||||
vertData[i].uv = vertices[i].uv;
|
||||
MeshData::GpuVertex gpuVert;
|
||||
gpuVert.pos = *vertices[i].pos;
|
||||
gpuVert.norm = *vertices[i].norm;
|
||||
gpuVert.tan = vertices[i].tan;
|
||||
gpuVert.biTan = vertices[i].biTan;
|
||||
gpuVert.uv = vertices[i].uv;
|
||||
|
||||
if(weights){
|
||||
for(int j = 0; j < 4; j++){
|
||||
vertData[i].weights[j] = vertices[i].weights[j];
|
||||
vertData[i].boneIndices[j] = vertices[i].boneIndices[j];
|
||||
gpuVert.weights[j] = vertices[i].weights[j];
|
||||
gpuVert.boneIndices[j] = vertices[i].boneIndices[j];
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
if(shapeKeyOffsets)
|
||||
for(int j = 0; j < 100; j++)
|
||||
vertData[i].shapeKeyOffsets[j] = vertices[i].shapeKeyOffsets[j];
|
||||
*/
|
||||
if(shapeKeyOffsets){
|
||||
const int MAX_NUM_SHAPE_KEYS = Root::getSingleton()->getMaxNumShapeKeys();
|
||||
|
||||
for(int j = 0; j < MAX_NUM_SHAPE_KEYS; j++)
|
||||
gpuVert.shapeKeyOffsets[j] = vertices[i].shapeKeyOffsets[j];
|
||||
}
|
||||
|
||||
vertData.push_back(gpuVert);
|
||||
}
|
||||
|
||||
return vertData;
|
||||
}
|
||||
|
||||
bool MeshData::operator==(MeshData &meshData){
|
||||
bool samePos = (positions == meshData.positions);
|
||||
bool sameNorm = (normals == meshData.normals);
|
||||
bool sameSkOffsets = (shapeKeyOffsets == meshData.shapeKeyOffsets);
|
||||
return samePos && sameNorm && sameSkOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -24,7 +24,7 @@ namespace vb01{
|
||||
Vector2 uv;
|
||||
float weights[4]{0, 0, 0, 0};
|
||||
int boneIndices[4]{-1, -1, -1, -1};
|
||||
Vector3 shapeKeyOffsets[100];
|
||||
Vector3 shapeKeyOffsets[5];
|
||||
};
|
||||
|
||||
struct Vertex{
|
||||
@@ -35,7 +35,7 @@ namespace vb01{
|
||||
Vector3 *shapeKeyOffsets = nullptr;
|
||||
};
|
||||
|
||||
GpuVertex* toGpuVerts();
|
||||
std::vector<GpuVertex> toGpuVerts();
|
||||
|
||||
Vector3 *positions = nullptr, *normals = nullptr, **shapeKeyOffsets = nullptr;
|
||||
float **weights = nullptr;
|
||||
@@ -43,12 +43,13 @@ namespace vb01{
|
||||
Vertex *vertices;
|
||||
std::string *vertexGroups = nullptr;
|
||||
ShapeKey *shapeKeys = nullptr;
|
||||
u32 *indices, VAO, VBO, EBO;
|
||||
u32 *indices;
|
||||
int numPos, numTris, numVertexGroups = 0, numShapeKeys = 0;
|
||||
std::string attachableName = "", fullSkeletonName = "";
|
||||
|
||||
MeshData(){}
|
||||
MeshData(Vector3*, float**, int**, Vector3**, int, Vector3*, Vertex*, u32*, int, std::string = "", std::string *vg = nullptr, int = 0, std::string = "", ShapeKey *sk = nullptr, int = 0);
|
||||
bool operator==(MeshData&);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -62,8 +62,7 @@ namespace vb01{
|
||||
l->update(render);
|
||||
|
||||
if(render){
|
||||
for(Mesh *m : meshes)
|
||||
m->update();
|
||||
//for(Mesh *m : meshes) m->update();
|
||||
|
||||
for(Text *t : texts)
|
||||
t->update();
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace vb01{
|
||||
inline std::vector<Text*>& getTexts(){return texts;}
|
||||
inline std::vector<Mesh*>& getMeshes(){return meshes;}
|
||||
inline std::vector<Skeleton*>& getSkeletons(){return skeletons;}
|
||||
inline std::vector<ParticleEmitter*>& getParticleEmitters(){return emitters;}
|
||||
inline Mesh* getMesh(int i){return meshes[i];}
|
||||
inline int getNumMeshes(){return meshes.size();}
|
||||
inline ParticleEmitter* getParticleEmitter(int i){return emitters[i];}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <cstdlib>
|
||||
#include <ext.hpp>
|
||||
|
||||
Executable
+196
@@ -0,0 +1,196 @@
|
||||
#version 460 core
|
||||
const int numLights=1;
|
||||
const bool checkLights=false;
|
||||
|
||||
in flat int drawId, instanceId;
|
||||
in vec3 fragPos;
|
||||
in vec3 tan;
|
||||
in vec3 biTan;
|
||||
in vec3 norm;
|
||||
in vec2 texCoords;
|
||||
in vec4 lightSpaceFragPos;
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
layout (location = 1) out vec4 BrightColor;
|
||||
|
||||
//0-POINT,1-DIRECTIONAL,2-SPOT
|
||||
|
||||
struct Light{
|
||||
bool useAngle, additive, render;
|
||||
int type, attenuation;
|
||||
vec3 pos, color, direction;
|
||||
float innerAngle, outerAngle;
|
||||
float a, b, c, near, far, radius;
|
||||
//sampler2D depthMap;
|
||||
//samplerCube depthMapCube;
|
||||
mat4 lightMat;
|
||||
};
|
||||
|
||||
struct Texture{
|
||||
float mixRatio;
|
||||
sampler2D pastTexture, nextTexture;
|
||||
bool animated;
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) readonly buffer lightsSSBO {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
struct ObjectFragData{
|
||||
bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled;
|
||||
vec4 diffuseColor, specularColor;
|
||||
float shinyness, specularStrength;
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) buffer objFragSSBO {
|
||||
//vec3 camPos;
|
||||
ObjectFragData objData[];
|
||||
};
|
||||
|
||||
uniform Texture textures[4];
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
float linDepth(float depth, int i){
|
||||
float z = depth * 2 - 1, near = lights[i].near, far = lights[i].far;
|
||||
return (2 * near * far) / (far + near - z * (far - near));
|
||||
}
|
||||
|
||||
float getShadow(int id){
|
||||
int type = lights[id].type;
|
||||
|
||||
float shadow = 0, closestDepth = 0, currentDepth = 0, bias = .005, val = .7;
|
||||
|
||||
/*
|
||||
if(type == 0){
|
||||
vec3 projDir = fragPos - lights[id].pos;
|
||||
closestDepth = texture(lights[id].depthMapCube, projDir).r * lights[id].far;
|
||||
currentDepth = length(projDir);
|
||||
shadow = (currentDepth - bias > closestDepth) ? val : 0;
|
||||
}
|
||||
else{
|
||||
vec4 lightSpaceFragPos = lights[id].lightMat * vec4(fragPos, 1);
|
||||
vec3 projCoords = (lightSpaceFragPos.xyz / lightSpaceFragPos.w) * .5 + .5;
|
||||
closestDepth = texture(lights[id].depthMap, projCoords.xy).r;
|
||||
currentDepth = projCoords.z;
|
||||
|
||||
if(type == 2)
|
||||
closestDepth = linDepth(closestDepth, id); currentDepth = linDepth(currentDepth, id);
|
||||
|
||||
shadow = (currentDepth - bias > closestDepth) ? val : 0;
|
||||
|
||||
if(projCoords.z > 1)
|
||||
shadow = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec4 finalColor = objData[drawId + instanceId].diffuseColor;
|
||||
|
||||
/*
|
||||
if(texturingEnabled){
|
||||
vec4 textureColor = texture(textures[0].pastTexture, texCoords);
|
||||
vec4 mixedTexColor = mix(textureColor, texture(textures[0].nextTexture, texCoords), textures[0].mixRatio);
|
||||
finalColor = (textures[0].animated ? mix(textureColor, texture(textures[0].nextTexture, texCoords), textures[0].mixRatio) : textureColor);
|
||||
}
|
||||
*/
|
||||
|
||||
vec3 normal = norm;
|
||||
|
||||
/*
|
||||
if(lightingEnabled){
|
||||
if(normalMapEnabled){
|
||||
vec3 n = normalize(vec3(texture(textures[1].pastTexture, texCoords)) * 2 - 1);
|
||||
|
||||
if(textures[1].animated)
|
||||
n = mix(n, normalize(texture(textures[1].nextTexture, texCoords).rgb * 2 - 1), textures[1].mixRatio);
|
||||
|
||||
normal = mat3(tan, biTan, norm) * n;
|
||||
}
|
||||
|
||||
vec3 diffuseCol = vec3(0), specularCol = vec3(0);
|
||||
|
||||
if(checkLights){
|
||||
bool addedLighting = false;
|
||||
|
||||
for(int i = 0; i < numLights; i++){
|
||||
if(!lights[i].render) continue;
|
||||
|
||||
vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos);
|
||||
float attenuation = 1, coef = 1;
|
||||
float factor = 0;
|
||||
bool canAdd = false;
|
||||
|
||||
if(lights[i].type == 0){
|
||||
lightDir = normalize(lights[i].pos - fragPos);
|
||||
float dist = length(lights[i].pos - fragPos), radius = lights[i].radius;
|
||||
|
||||
if(lights[i].attenuation == 0){
|
||||
float a = lights[i].a, b = lights[i].b, c = lights[i].c;
|
||||
attenuation = 1.0 / (a * dist * dist + b * dist + c);
|
||||
factor = (lights[i].useAngle ? max(dot(lightDir, normalize(normal)), 0.) : 1) * attenuation;
|
||||
}
|
||||
else if(lights[i].attenuation == 1 && dist < radius && radius > 0){
|
||||
canAdd = !lights[i].additive;
|
||||
factor = 1.0 - dist / lights[i].radius;
|
||||
}
|
||||
else if(lights[i].attenuation == 2 && dist < radius && radius > 0){
|
||||
canAdd = !lights[i].additive;
|
||||
factor = 1;
|
||||
}
|
||||
}
|
||||
else if(lights[i].type == 1){
|
||||
lightDir = -normalize(lights[i].direction);
|
||||
factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation;
|
||||
}
|
||||
else if(lights[i].type == 2){
|
||||
lightDir = normalize(lights[i].pos - fragPos);
|
||||
float innerAngle = lights[i].innerAngle;
|
||||
float angle = acos(dot(-lightDir, lights[i].direction));
|
||||
float outerAngle = lights[i].outerAngle;
|
||||
|
||||
if(lights[i].innerAngle <= angle && angle <= lights[i].outerAngle)
|
||||
coef = (angle - outerAngle) / (innerAngle - outerAngle);
|
||||
|
||||
if(angle > lights[i].outerAngle)
|
||||
continue;
|
||||
|
||||
factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef;
|
||||
}
|
||||
else factor = 1;
|
||||
|
||||
|
||||
if(lights[i].additive)
|
||||
diffuseCol += lights[i].color * factor;
|
||||
else if(!lights[i].additive && constLightingEnabled && !addedLighting && canAdd){
|
||||
addedLighting = true;
|
||||
diffuseCol += lights[i].color * factor;
|
||||
}
|
||||
|
||||
if(specularMapEnabled){
|
||||
float specularSample = texture(textures[2].pastTexture, texCoords).r;
|
||||
vec3 halfwayVec = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(normal, halfwayVec), 0), shinyness);
|
||||
specularCol += specularStrength * spec * specularSample * lights[i].color;
|
||||
}
|
||||
|
||||
if(castShadow)
|
||||
diffuseCol *= (1.0 - getShadow(i));
|
||||
}
|
||||
}
|
||||
|
||||
finalColor *= vec4(diffuseCol + specularCol, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
if(brightness > 1)
|
||||
BrightColor = vec4(finalColor.rgb, 1);
|
||||
|
||||
//FragColor = vec4(fragPos,1);
|
||||
FragColor = vec4(1,1,0,1);
|
||||
//FragColor = finalColor;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#version 430 core
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
in VS_OUT{
|
||||
vec2 tCoords;
|
||||
}gs_in[];
|
||||
|
||||
out vec4 FragPos;
|
||||
out vec2 texCoords;
|
||||
|
||||
uniform mat4 shadowMat[6];
|
||||
uniform bool environment;
|
||||
|
||||
void main(){
|
||||
/*
|
||||
if(environment)
|
||||
for(int i = 0; i < 6; i++){
|
||||
gl_Layer = i;
|
||||
for(int j = 0; j < 3; j++){
|
||||
FragPos = gl_in[j].gl_Position;
|
||||
gl_Position = shadowMat[i] * FragPos;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
*/
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
texCoords = gs_in[0].tCoords;
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[1].gl_Position;
|
||||
texCoords = gs_in[1].tCoords;
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[2].gl_Position;
|
||||
texCoords = gs_in[2].tCoords;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
Executable
+153
@@ -0,0 +1,153 @@
|
||||
#version 460 core
|
||||
|
||||
const int numBones = 1;
|
||||
const int numVertGroups = 0;
|
||||
const int numMaxInfluences = 4;
|
||||
const int numShapeKeys = 4;
|
||||
|
||||
mat4 transform[numBones];
|
||||
mat4 poseTransform[numBones];
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNorm;
|
||||
layout (location = 2) in vec2 aTexCoords;
|
||||
layout (location = 3) in vec3 aTan;
|
||||
layout (location = 4) in vec3 aBiTan;
|
||||
layout (location = 5) in vec4 aWeight;
|
||||
layout (location = 6) in ivec4 aBoneIndices;
|
||||
//layout (location = 7) in vec3 aShapeKeyOffsets[numShapeKeys];
|
||||
|
||||
out vec3 fragPos, norm, tan, biTan;
|
||||
out vec2 texCoords;
|
||||
out int drawId, instanceId;
|
||||
|
||||
struct Bone{
|
||||
float angle;
|
||||
vec3 pos, trans, rotAxis, scale;
|
||||
int vertGroup, parent;
|
||||
};
|
||||
|
||||
struct ObjectVertData{
|
||||
float shapeKeyFactors[24];
|
||||
mat4 viewProj, model, bones[256];
|
||||
//bool animated;
|
||||
};
|
||||
|
||||
layout(std430, binding = 0) readonly restrict buffer objVertSSBO {
|
||||
ObjectVertData objData[];
|
||||
};
|
||||
|
||||
mat4 createTranslationMatrix(vec3 trans){
|
||||
mat4 transMat;
|
||||
transMat[0] = vec4(1, 0, 0, trans.x);
|
||||
transMat[1] = vec4(0, 1, 0, trans.y);
|
||||
transMat[2] = vec4(0, 0, 1, trans.z);
|
||||
transMat[3] = vec4(0, 0, 0, 1);
|
||||
return transpose(transMat);
|
||||
}
|
||||
|
||||
mat4 createRotationMatrix(float angle, vec3 axis){
|
||||
mat4 rotMat;
|
||||
|
||||
float s = sin(-angle);
|
||||
float c = cos(-angle);
|
||||
float oc = 1.0 - c;
|
||||
|
||||
rotMat[0] = vec4(oc * axis.x * axis.x + c,oc * axis.x * axis.y + axis.z * s,oc * axis.z * axis.x - axis.y * s, 0.0);
|
||||
rotMat[1] = vec4(oc * axis.x * axis.y - axis.z * s,oc * axis.y * axis.y + c,oc * axis.y * axis.z + axis.x * s, 0.0);
|
||||
rotMat[2] = vec4(oc * axis.z * axis.x + axis.y * s,oc * axis.y * axis.z - axis.x * s,oc * axis.z * axis.z + c, 0.0);
|
||||
rotMat[3] = vec4(0, 0, 0, 1);
|
||||
|
||||
return transpose(rotMat);
|
||||
}
|
||||
|
||||
mat4 createScaleMatrix(vec3 scale){
|
||||
mat4 scaleMat;
|
||||
scaleMat[0] = vec4(scale.x, 0, 0, 0);
|
||||
scaleMat[1] = vec4(0, scale.y, 0, 0);
|
||||
scaleMat[2] = vec4(0, 0, scale.z, 0);
|
||||
scaleMat[3] = vec4(0, 0, 0, 1);
|
||||
return scaleMat;
|
||||
}
|
||||
|
||||
float getWeight(Bone bone){
|
||||
float weight = 0;
|
||||
for(int i = 0; i < numMaxInfluences; i++){
|
||||
if(bone.vertGroup == aBoneIndices[i])
|
||||
weight = aWeight[i];
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec4 vertPos = vec4(aPos, 1);
|
||||
bool anyWeights = false;
|
||||
|
||||
//int id = 0;
|
||||
int id = gl_DrawID + gl_InstanceID;
|
||||
mat4 model = objData[id].model;
|
||||
mat3 normalMat = mat3(transpose(inverse(model)));
|
||||
norm = (normalMat * aNorm);
|
||||
tan = (normalMat * aTan);
|
||||
biTan = (normalMat * aBiTan);
|
||||
|
||||
for(int i = 0; i < numMaxInfluences; i++)
|
||||
if(aWeight[i] > 0)
|
||||
anyWeights = true;
|
||||
/*
|
||||
|
||||
for(int i = 0; i < numShapeKeys; i++){
|
||||
vertPos.xyz += aShapeKeyOffsets[i] * shapeKeyFactors[i];
|
||||
}
|
||||
if(animated && anyWeights){
|
||||
for(int i = 0; i < numBones; i++){
|
||||
transform[i] = createTranslationMatrix(bones[i].pos);
|
||||
vec3 trans = bones[i].trans;
|
||||
float angle = bones[i].angle;
|
||||
vec3 axis = bones[i].rotAxis;
|
||||
vec3 scale = bones[i].scale;
|
||||
mat4 animTransform = createTranslationMatrix(trans) * createRotationMatrix(angle, axis) * createScaleMatrix(scale);
|
||||
poseTransform[i] = transform[i] * animTransform;
|
||||
}
|
||||
|
||||
for(int i = 1; i < numBones; i++){
|
||||
mat4 localTransform = inverse(transform[bones[i].parent]) * poseTransform[i];
|
||||
poseTransform[i] = poseTransform[bones[i].parent] * localTransform;
|
||||
}
|
||||
|
||||
vec3 v0 = vec3(0), n0 = vec3(0), t0 = vec3(0), b0 = vec3(0);
|
||||
for(int i = 0; i < numBones; i++){
|
||||
float weight = getWeight(bones[i]);
|
||||
mat4 inverseTransform = inverse(transform[i]);
|
||||
vec4 boneLocalVert = inverseTransform * vertPos;
|
||||
vec4 boneLocalNorm = inverseTransform * vec4(aNorm, 0);
|
||||
vec4 boneLocalTan = inverseTransform * vec4(aTan, 0);
|
||||
vec4 boneLocalBiTan = inverseTransform * vec4(aBiTan, 0);
|
||||
|
||||
v0 += (weight * poseTransform[i] * boneLocalVert).xyz;
|
||||
mat4 normalPoseTrans = transpose(inverse(poseTransform[i]));
|
||||
n0 += (weight * normalPoseTrans * boneLocalNorm).xyz;
|
||||
t0 += (weight * normalPoseTrans * boneLocalTan).xyz;
|
||||
b0 += (weight * normalPoseTrans * boneLocalBiTan).xyz;
|
||||
|
||||
}
|
||||
vertPos.xyz = v0;
|
||||
norm = n0;
|
||||
tan = t0;
|
||||
biTan = b0;
|
||||
}
|
||||
*/
|
||||
|
||||
norm = normalize(normalMat * norm);
|
||||
tan = normalize(normalMat * tan);
|
||||
biTan = normalize(normalMat * biTan);
|
||||
|
||||
mat4 viewProj = objData[id].viewProj;
|
||||
mat4 rotMat = createRotationMatrix(.3, normalize(vec3(1,1,1)));
|
||||
|
||||
gl_Position = viewProj * model * vertPos;
|
||||
fragPos = vec3(model * vertPos);
|
||||
texCoords = aTexCoords;
|
||||
drawId = gl_DrawID;
|
||||
instanceId = gl_InstanceID;
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
#include "quad.h"
|
||||
#include "root.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace vb01{
|
||||
using namespace std;
|
||||
|
||||
Quad::Quad(Vector3 size, bool spatial, int numVertDiv, int numHorDiv){
|
||||
this->spatial = spatial;
|
||||
this->numVertDiv = numVertDiv;
|
||||
this->numHorDiv = numHorDiv;
|
||||
Quad::Quad(Vector3 sz, bool sp, int nvd, int nhd) : size(sz), spatial(sp), numVertDiv(nvd), numHorDiv(nhd){
|
||||
init();
|
||||
}
|
||||
|
||||
setSize(size);
|
||||
Quad::Quad(Quad *q){
|
||||
size = q->getSize();
|
||||
numVertDiv = q->getNumVertSubquads() - 1;
|
||||
numHorDiv = q->getNumHorSubquads() - 1;
|
||||
meshBase = q->getMeshBase();
|
||||
}
|
||||
|
||||
void Quad::setSize(Vector3 size){
|
||||
this->size = size;
|
||||
|
||||
void Quad::init(){
|
||||
const int numHorQuads = numVertDiv + 1, numVertQuads = numHorDiv + 1;
|
||||
const int numVertPos = (numHorQuads + 1) * (numVertQuads + 1), numTris = 2 * numHorQuads * numVertQuads, numVerts = 3 * numTris;
|
||||
Vector2 subQuadSize = Vector2(size.x / numHorQuads, size.y / numVertQuads);
|
||||
@@ -84,6 +86,7 @@ namespace vb01{
|
||||
}
|
||||
|
||||
meshBase = MeshData(faceVertPos, nullptr, nullptr, nullptr, 6, norm, vertices, indices, numTris);
|
||||
//Root::getSingleton()->initVertexDataOnGpu(meshBase);
|
||||
}
|
||||
|
||||
//TODO improve functionality for GUI quads
|
||||
|
||||
@@ -8,14 +8,18 @@ namespace vb01{
|
||||
class Quad : public Mesh{
|
||||
public:
|
||||
Quad(Vector3, bool = true, int numVertDiv = 0, int numHorDiv = 0);
|
||||
void setSize(Vector3);
|
||||
Vector3 getSubquadCorner(int, int, int, int, bool, bool);
|
||||
Vector2 getSubquadIds(int, int, Vector3, Vector3);
|
||||
inline Quad* clone(){return new Quad(this);}
|
||||
inline void setSize(Vector3 size){this->size = size;}
|
||||
inline Vector3 getSize(){return size;}
|
||||
inline Vector2 getSubquadSize(){return Vector2(size.x / (numHorDiv + 1), size.y / (numVertDiv + 1));}
|
||||
inline int getNumHorSubquads(){return numHorDiv + 1;}
|
||||
inline int getNumVertSubquads(){return numVertDiv + 1;}
|
||||
private:
|
||||
Quad(Quad*);
|
||||
void init();
|
||||
|
||||
Vector3 size;
|
||||
bool spatial;
|
||||
int numVertDiv, numHorDiv;
|
||||
|
||||
@@ -4,17 +4,23 @@
|
||||
#include "shader.h"
|
||||
#include "box.h"
|
||||
#include "quad.h"
|
||||
#include "camera.h"
|
||||
#include "lineRenderer.h"
|
||||
#include "assetManager.h"
|
||||
#include "animationController.h"
|
||||
|
||||
#include "glad.h"
|
||||
#include <glfw3.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <glfw3.h>
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace glm;
|
||||
|
||||
namespace vb01{
|
||||
static Root *root = nullptr;
|
||||
@@ -49,12 +55,111 @@ namespace vb01{
|
||||
this->height = height;
|
||||
this->libPath = libPath;
|
||||
|
||||
AssetManager::getSingleton()->load(Root::getSingleton()->getLibPath());
|
||||
AssetManager::getSingleton()->load(libPath);
|
||||
|
||||
initWindow(name);
|
||||
|
||||
brdfLutPlane = new Quad(Vector3(1, 1, 1) * 2);
|
||||
iblBox = new Box(Vector3::VEC_IJK);
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &NUM_MAX_TEXTURE_ARRAY_SIZE);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &NUM_MAX_TEXTURE_UNITS);
|
||||
|
||||
glGenBuffers(1, &drawCmdBuffer);
|
||||
glGenBuffers(1, &objVertBuffer);
|
||||
glGenBuffers(1, &objFragBuffer);
|
||||
|
||||
initMeshRendering(meshVAO, meshVBO, meshEBO);
|
||||
initParticleRendering();
|
||||
initGuiRendering();
|
||||
initPostProcessing();
|
||||
initMainFramebuffer(pingPongTextures[0], nullptr);
|
||||
initGuiPlane();
|
||||
}
|
||||
|
||||
void Root::initMeshRendering(u32 &VAO, u32 &VBO, u32 &EBO){
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
u32 size = sizeof(MeshData::GpuVertex);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size, (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, norm)));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, uv)));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, tan)));
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, biTan)));
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, weights)));
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, boneIndices)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
/*
|
||||
for(int i = 0; i < MAX_NUM_SHAPE_KEYS; i++){
|
||||
glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, shapeKeyOffsets) + 3 * i * sizeof(float)));
|
||||
cout << glGetError() << "\n";
|
||||
glEnableVertexAttribArray(7 + i);
|
||||
cout << glGetError() << "\n";
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Root::initVertexDataOnGpu(MeshData &meshData, u32 &VAO, u32 &VBO, u32 &EBO, bool updateDrawCommands){
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
vector<MeshData::GpuVertex> glVertData = meshData.toGpuVerts();
|
||||
u32 vertSize = sizeof(MeshData::GpuVertex), indexSize = sizeof(u32);
|
||||
|
||||
if(updateDrawCommands){
|
||||
DrawElementsIndirectCommand drawCmd;
|
||||
drawCmd.count = 3 * meshData.numTris;
|
||||
drawCmd.instanceCount = 0;
|
||||
drawCmd.firstIndex = currentIndices.size();
|
||||
drawCmd.baseVertex = currentGpuVertices.size();
|
||||
drawCmd.baseInstance = 0;
|
||||
drawCmds.push_back(drawCmd);
|
||||
drawCmdMeshes.push_back(&meshData);
|
||||
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawCmdBuffer);
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * drawCmds.size(), drawCmds.data(), GL_DYNAMIC_DRAW);
|
||||
|
||||
int currNumIndices = currentIndices.size();
|
||||
|
||||
for(int i = 0; i < 3 * meshData.numTris; i++)
|
||||
currentIndices.push_back(meshData.indices[i] + currNumIndices);
|
||||
|
||||
currentGpuVertices.insert(currentGpuVertices.end(), glVertData.begin(), glVertData.end());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, currentGpuVertices.size() * vertSize, currentGpuVertices.data(), GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, currentIndices.size() * indexSize, currentIndices.data(), GL_DYNAMIC_DRAW);
|
||||
}
|
||||
else{
|
||||
u32 numVerts = 3 * meshData.numTris, numIndexes = 3 * meshData.numTris;
|
||||
glBufferData(GL_ARRAY_BUFFER, numVerts * vertSize, glVertData.data(), GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndexes * indexSize, meshData.indices, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
void Root::initParticleRendering(){
|
||||
}
|
||||
|
||||
void Root::initGuiRendering(){
|
||||
}
|
||||
|
||||
void Root::initPostProcessing(){
|
||||
//brdfLutPlane = new Quad(Vector3(1, 1, 1) * 2);
|
||||
//iblBox = new Box(Vector3::VEC_IJK);
|
||||
|
||||
blurShader = new Shader(libPath + "blur");
|
||||
shader = new Shader(Root::getSingleton()->getLibPath() + "line3D");
|
||||
@@ -64,9 +169,18 @@ namespace vb01{
|
||||
|
||||
Texture *fragTexture = new Texture(width, height, false);
|
||||
Texture *brightTexture = new Texture(width, height, false);
|
||||
}
|
||||
|
||||
initMainFramebuffer(fragTexture, nullptr);
|
||||
initGuiPlane(fragTexture, brightTexture);
|
||||
void Root::addMeshes(Node *rootNode){
|
||||
vector<Node*> descendants;
|
||||
rootNode->getDescendants(descendants);
|
||||
|
||||
vector<Mesh*> meshes;
|
||||
|
||||
for(Node *desc : descendants){
|
||||
vector<Mesh*> m = desc->getMeshes();
|
||||
meshes.insert(meshes.end(), m.begin(), m.end());
|
||||
}
|
||||
}
|
||||
|
||||
void Root::toggleHDR(bool hdr){
|
||||
@@ -156,11 +270,15 @@ namespace vb01{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Root::initGuiPlane(Texture *fragTexture, Texture *brightTexture){
|
||||
void Root::initGuiPlane(){
|
||||
guiPlane = new Quad(Vector3(width, height, -1), false);
|
||||
|
||||
initMeshRendering(guiPlaneVAO, guiPlaneVBO, guiPlaneEBO);
|
||||
initVertexDataOnGpu(guiPlane->getMeshBase(), guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, false);
|
||||
|
||||
Material *mat = new Material(libPath + "postProcess");
|
||||
mat->addTexUniform("frag", fragTexture, false);
|
||||
mat->addTexUniform("bright", brightTexture, false);
|
||||
mat->addTexUniform("frag", pingPongTextures[0], false);
|
||||
mat->addTexUniform("bright", pingPongTextures[1], false);
|
||||
guiPlane->setMaterial(mat);
|
||||
}
|
||||
|
||||
@@ -174,16 +292,29 @@ namespace vb01{
|
||||
if(skybox){
|
||||
glDepthMask(GL_FALSE);
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
skybox->update();
|
||||
renderMesh(skybox, meshVAO);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
AnimationController::getSingleton()->update();
|
||||
|
||||
updateNodeTree(rootNode, false);
|
||||
Vector3 camPos = camera->getPosition();
|
||||
|
||||
LineRenderer::getSingleton()->drawLines();
|
||||
Vector3 dir = camera->getDirection(), up = camera->getUp();
|
||||
mat4 view = lookAt(vec3(camPos.x, camPos.y, camPos.z), vec3(camPos.x + dir.x, camPos.y + dir.y, camPos.z + dir.z), vec3(up.x, up.y, up.z));
|
||||
|
||||
float fov = camera->getFov(), nearPlane = camera->getNearPlane(), farPlane = camera->getFarPlane();
|
||||
mat4 proj = perspective(radians(fov), (float)width / height, nearPlane, farPlane);
|
||||
|
||||
mat4 projView = proj * view;
|
||||
|
||||
updateNodeTree(rootNode, projView, false);
|
||||
|
||||
//LineRenderer::getSingleton()->drawLines();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
@@ -196,60 +327,199 @@ namespace vb01{
|
||||
updateGuiPlane();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
updateNodeTree(guiNode, true);
|
||||
//updateNodeTree(guiNode, true);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
void Root::renderMesh(Mesh *mesh, u32 &vao){
|
||||
MeshData meshData = mesh->getMeshBase();
|
||||
glBindVertexArray(vao);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, mesh->isWireframe() ? GL_LINE : GL_FILL);
|
||||
glDrawElements(GL_TRIANGLES, 3 * meshData.numTris, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
void Root::renderMeshes(){
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, objVertBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(ObjectVertexData) * objVertData.size(), objVertData.data(), GL_DYNAMIC_DRAW);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, objVertBuffer);
|
||||
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, objFragBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(ObjectFragmentData) * objFragData.size(), objFragData.data(), GL_DYNAMIC_DRAW);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, objFragBuffer);
|
||||
|
||||
/*
|
||||
glNamedBufferSubData(objFragBuffer, 0, sizeof(ObjectFragmentData) * objFragData.size(), objFragData.data());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, objFragBuffer);
|
||||
*/
|
||||
|
||||
glBindVertexArray(meshVAO);
|
||||
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawCmdBuffer);
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * drawCmds.size(), drawCmds.data(), GL_DYNAMIC_DRAW);
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, NULL, drawCmds.size(), 0);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Root::renderParticles(vector<ParticleEmitter*> &particleEmitters){
|
||||
}
|
||||
|
||||
void Root::renderGui(vector<Mesh*> &meshes){
|
||||
}
|
||||
|
||||
void Root::updateNode(Node *node, mat4 &proj, mat4 &view, bool gui){
|
||||
Quaternion orient = Quaternion::QUAT_W;
|
||||
Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK;
|
||||
|
||||
if(!gui){
|
||||
pos = node->localToGlobalPosition(Vector3::VEC_ZERO);
|
||||
orient = node->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
scale = node->getScale();
|
||||
}
|
||||
|
||||
Vector3 rotAxis = orient.getAxis();
|
||||
|
||||
if(rotAxis == Vector3::VEC_ZERO)
|
||||
rotAxis = Vector3::VEC_I;
|
||||
|
||||
mat4 model = mat4(1.);
|
||||
model = translate(model, vec3(pos.x, pos.y, pos.z));
|
||||
model = rotate(model, orient.getAngle(), vec3(rotAxis.x, rotAxis.y, rotAxis.z));
|
||||
model = glm::scale(model, vec3(scale.x, scale.y, scale.z));
|
||||
|
||||
vector<Mesh*> mesh = node->getMeshes();
|
||||
vector<ParticleEmitter*> pe = node->getParticleEmitters();
|
||||
|
||||
/*
|
||||
for(Mesh *m : mesh){
|
||||
}
|
||||
*/
|
||||
|
||||
//meshes.insert(meshes.end(), mesh.begin(), mesh.end());
|
||||
//particleEmitters.insert(particleEmitters.end(), pe.begin(), pe.end());
|
||||
|
||||
node->update();
|
||||
}
|
||||
|
||||
//TODO replace sorting algorithm
|
||||
//TODO specify differentiation of nodes with translucent meshes AND texts
|
||||
void Root::updateNodeTree(Node *node, bool gui){
|
||||
vector<Node*> descendants, opaqueNodes, transparentNodes;
|
||||
node->getDescendants(descendants);
|
||||
void Root::updateNodeTree(Node *node, mat4 &projView, bool gui){
|
||||
objVertData.clear();
|
||||
objFragData.clear();
|
||||
|
||||
for(Node *desc : descendants){
|
||||
if(!desc->getMeshes().empty())
|
||||
for(Mesh *mesh : desc->getMeshes()){
|
||||
(mesh->getMaterial()->isTransparent() ? transparentNodes : opaqueNodes).push_back(desc);
|
||||
break;
|
||||
}
|
||||
else if(!desc->getTexts().empty())
|
||||
transparentNodes.push_back(desc);
|
||||
else
|
||||
opaqueNodes.push_back(desc);
|
||||
}
|
||||
for(DrawElementsIndirectCommand &cmd : drawCmds)
|
||||
cmd.instanceCount = 0;
|
||||
|
||||
for(Node *node : opaqueNodes)
|
||||
node->update();
|
||||
vector<Node*> descendants, opaqueNodes, transparentNodes;
|
||||
node->getDescendants(descendants);
|
||||
|
||||
int numNodes = transparentNodes.size();
|
||||
for(Node *desc : descendants){
|
||||
if(!desc->isVisible()) continue;
|
||||
|
||||
for(int i = 0; i < numNodes; i++){
|
||||
float d1 = transparentNodes[i]->getPosition().z;
|
||||
if(!desc->getMeshes().empty()){
|
||||
Quaternion orient = Quaternion::QUAT_W;
|
||||
Vector3 pos = Vector3::VEC_ZERO, scale = Vector3::VEC_IJK;
|
||||
|
||||
if(!gui){
|
||||
Vector3 v1 = transparentNodes[i]->getPosition() - camera->getPosition();
|
||||
float a1 = v1.norm().getAngleBetween(camera->getDirection());
|
||||
d1 = v1.getLength() * cos(a1);
|
||||
pos = desc->localToGlobalPosition(Vector3::VEC_ZERO);
|
||||
orient = desc->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
scale = desc->getScale();
|
||||
}
|
||||
|
||||
for(int j = i; j < numNodes; j++){
|
||||
float d2 = transparentNodes[j]->getPosition().z;
|
||||
Vector3 rotAxis = orient.getAxis();
|
||||
|
||||
if(!gui){
|
||||
Vector3 v2 = transparentNodes[j]->getPosition() - camera->getPosition();
|
||||
float a2 = v2.norm().getAngleBetween(camera->getDirection());
|
||||
d2 = v2.getLength() * cos(a2);
|
||||
if(rotAxis == Vector3::VEC_ZERO)
|
||||
rotAxis = Vector3::VEC_I;
|
||||
|
||||
mat4 model = mat4(1.);
|
||||
model = translate(model, vec3(pos.x, pos.y, pos.z));
|
||||
model = rotate(model, orient.getAngle(), vec3(rotAxis.x, rotAxis.y, rotAxis.z));
|
||||
model = glm::scale(model, vec3(scale.x, scale.y, scale.z));
|
||||
|
||||
for(Mesh *mesh : desc->getMeshes()){
|
||||
if(mesh->getMaterial()->isTransparent()){
|
||||
transparentNodes.push_back(desc);
|
||||
}
|
||||
else{
|
||||
mesh->getMaterial()->getShader()->use();
|
||||
ObjectVertexData ovd;
|
||||
ovd.viewProj = projView;
|
||||
ovd.model = model;
|
||||
//ovd.animated = 0;
|
||||
//ovd.bones[0];
|
||||
MeshData &meshData = mesh->getMeshBase();
|
||||
|
||||
if(d1 > d2)
|
||||
swap(transparentNodes[i], transparentNodes[j]);
|
||||
for(int i = 0; i < drawCmdMeshes.size(); i++)
|
||||
if(*(drawCmdMeshes[i]) == meshData)
|
||||
drawCmds[i].instanceCount++;
|
||||
/*
|
||||
*/
|
||||
|
||||
//for(int i = 0; i < meshData.numShapeKeys; i++) ovd.shapeKeyFactors[i] = meshData.shapeKeys[i].value;
|
||||
|
||||
objVertData.push_back(ovd);
|
||||
|
||||
ObjectFragmentData ofd;
|
||||
ofd.diffuseColor = Vector4::VEC_IJKL;
|
||||
ofd.specularColor;
|
||||
ofd.shinyness;
|
||||
ofd.specularStrength;
|
||||
ofd.lightingEnabled = false,
|
||||
ofd.constLightingEnabled = false,
|
||||
ofd.texturingEnabled = false,
|
||||
ofd.normalMapEnabled = false,
|
||||
ofd.specularMapEnabled = false,
|
||||
ofd.castShadow = false,
|
||||
ofd.environmentMapEnabled = false;
|
||||
objFragData.push_back(ofd);
|
||||
|
||||
//updateNode(desc, projView, gui);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(!desc->getTexts().empty())
|
||||
transparentNodes.push_back(desc);
|
||||
else{
|
||||
//updateNode(desc, proj, view, gui);
|
||||
//opaqueNodes.push_back(desc);
|
||||
}
|
||||
}
|
||||
|
||||
for(Node *node : transparentNodes)
|
||||
node->update();
|
||||
int numNodes = transparentNodes.size();
|
||||
|
||||
for(int i = 0; i < numNodes; i++){
|
||||
float d1 = transparentNodes[i]->getPosition().z;
|
||||
|
||||
if(!gui){
|
||||
Vector3 v1 = transparentNodes[i]->getPosition() - camera->getPosition();
|
||||
float a1 = v1.norm().getAngleBetween(camera->getDirection());
|
||||
d1 = v1.getLength() * cos(a1);
|
||||
}
|
||||
|
||||
for(int j = i; j < numNodes; j++){
|
||||
float d2 = transparentNodes[j]->getPosition().z;
|
||||
|
||||
if(!gui){
|
||||
Vector3 v2 = transparentNodes[j]->getPosition() - camera->getPosition();
|
||||
float a2 = v2.norm().getAngleBetween(camera->getDirection());
|
||||
d2 = v2.getLength() * cos(a2);
|
||||
}
|
||||
|
||||
if(d1 > d2)
|
||||
swap(transparentNodes[i], transparentNodes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if(gui){} //renderGui();
|
||||
else{
|
||||
renderMeshes();
|
||||
//renderParticles(particleEmitters);
|
||||
}
|
||||
}
|
||||
|
||||
void Root::updateBloomFramebuffer(){
|
||||
@@ -266,7 +536,7 @@ namespace vb01{
|
||||
else
|
||||
pingPongTextures[!horizontal]->select();
|
||||
|
||||
guiPlane->render();
|
||||
renderMesh(guiPlane, guiPlaneVAO);
|
||||
horizontal = !horizontal;
|
||||
}
|
||||
|
||||
@@ -292,7 +562,7 @@ namespace vb01{
|
||||
((Material::TextureUniform*)material->getUniform("bright"))->value->select(1);
|
||||
}
|
||||
|
||||
guiPlane->render();
|
||||
renderMesh(guiPlane, guiPlaneVAO);
|
||||
}
|
||||
|
||||
void Root::createSkybox(string paths[6]){
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
#ifndef ROOT_H
|
||||
#define ROOT_H
|
||||
|
||||
#include "camera.h"
|
||||
#include "util.h"
|
||||
#include "meshData.h"
|
||||
|
||||
#include <glm.hpp>
|
||||
|
||||
#include <glad.h>
|
||||
|
||||
#include <glfw3.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -12,19 +19,31 @@ class GLFWwindow;
|
||||
namespace vb01{
|
||||
void foo();
|
||||
|
||||
class Camera;
|
||||
class Mesh;
|
||||
class Box;
|
||||
class Quad;
|
||||
class Node;
|
||||
class Texture;
|
||||
class Shader;
|
||||
class ParticleEmitter;
|
||||
|
||||
class Root{
|
||||
public:
|
||||
static Root* getSingleton();
|
||||
void update();
|
||||
void start(int, int, std::string, std::string);
|
||||
void toggleHDR(bool);
|
||||
void toggleBloom(bool);
|
||||
void addMeshes(Node*);
|
||||
void createSkybox(std::string[6]);
|
||||
void createSkybox(vb01::Texture*);
|
||||
void removeSkybox();
|
||||
void initVertexDataOnGpu(MeshData&, u32&, u32&, u32&, bool);
|
||||
inline u32& getMeshVAO(){return meshVAO;}
|
||||
inline u32& getMeshVBO(){return meshVBO;}
|
||||
inline u32& getMeshEBO(){return meshEBO;}
|
||||
inline const int getMaxNumShapeKeys(){return MAX_NUM_SHAPE_KEYS;}
|
||||
inline Camera* getCamera(){return camera;}
|
||||
inline Node* getRootNode(){return rootNode;}
|
||||
inline Node* getGuiNode(){return guiNode;}
|
||||
@@ -39,38 +58,69 @@ namespace vb01{
|
||||
inline Box* getSkybox(){return skybox;}
|
||||
inline Box* getIblBox(){return iblBox;}
|
||||
inline Quad* getBrdfLutPlane(){return brdfLutPlane;}
|
||||
void createSkybox(std::string[6]);
|
||||
void createSkybox(vb01::Texture*);
|
||||
void removeSkybox();
|
||||
static Root* getSingleton();
|
||||
inline void shiftNumLights(bool increase){numLights += (increase ? 1 : -1);}
|
||||
inline int getNumLights(){return numLights;}
|
||||
inline std::string getLibPath(){return libPath;}
|
||||
private:
|
||||
int numLights = 0;
|
||||
struct DrawElementsIndirectCommand {
|
||||
u32 count = 0;
|
||||
u32 instanceCount = 0;
|
||||
u32 firstIndex = 0;
|
||||
int baseVertex = 0;
|
||||
u32 baseInstance = 0;
|
||||
};
|
||||
struct ObjectVertexData {
|
||||
float shapeKeyFactors[24];
|
||||
glm::mat4 viewProj, model, bones[256];
|
||||
//bool animated;
|
||||
};
|
||||
struct ObjectFragmentData {
|
||||
Vector4 diffuseColor, specularColor;
|
||||
float shinyness, specularStrength;
|
||||
bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled;
|
||||
};
|
||||
|
||||
const int MAX_NUM_SHAPE_KEYS = 5;
|
||||
int NUM_MAX_TEXTURE_UNITS = 0, NUM_MAX_TEXTURE_ARRAY_SIZE = 0, numLights = 0, width, height, blurLevel = 10, currNumVerts = 0, currNumIndexes = 0;
|
||||
u32 meshVAO, meshVBO, meshEBO, particleVAO, particleVBO, guiPlaneVAO, guiPlaneVBO, guiPlaneEBO, FBO, RBO, pingpongBuffers[2], drawCmdBuffer = -1, objVertBuffer = -1, objFragBuffer = -1;
|
||||
bool bloom = false, hdr = false;
|
||||
float exposure = 1, gamma = 1;
|
||||
Box *skybox = nullptr, *iblBox = nullptr;
|
||||
Quad *guiPlane = nullptr, *brdfLutPlane = nullptr;
|
||||
int width, height, blurLevel = 10;
|
||||
u32 FBO, RBO, pingpongBuffers[2];
|
||||
GLFWwindow *window;
|
||||
Node *rootNode, *guiNode;
|
||||
Camera *camera;
|
||||
Shader *blurShader;
|
||||
Texture *pingPongTextures[2];
|
||||
std::vector<MeshData*> drawCmdMeshes;
|
||||
std::vector<MeshData::GpuVertex> currentGpuVertices;
|
||||
std::vector<u32> currentIndices;
|
||||
std::vector<Mesh*> meshes;
|
||||
std::vector<DrawElementsIndirectCommand> drawCmds;
|
||||
std::vector<ObjectVertexData> objVertData;
|
||||
std::vector<ObjectFragmentData> objFragData;
|
||||
std::string libPath;
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow*, int, int);
|
||||
Root();
|
||||
void framebuffer_size_callback(GLFWwindow*, int, int);
|
||||
void renderMeshes();
|
||||
void renderParticles(std::vector<ParticleEmitter*>&);
|
||||
void renderGui(std::vector<Mesh*>&);
|
||||
void initWindow(std::string);
|
||||
void initMainFramebuffer(Texture*, Texture*);
|
||||
void initBloomFramebuffer();
|
||||
void initGuiPlane(Texture*, Texture*);
|
||||
void initGuiPlane();
|
||||
void updateBloomFramebuffer();
|
||||
void updateGuiPlane();
|
||||
void updateNodeTree(vb01::Node*, bool);
|
||||
void updateNodeTree(vb01::Node*, glm::mat4&, bool);
|
||||
void updateNode(vb01::Node*, glm::mat4&, glm::mat4&, bool);
|
||||
void renderMesh(Mesh*, u32&);
|
||||
protected:
|
||||
virtual void initMeshRendering(u32 &vao, u32 &vbo, u32 &ebo);
|
||||
virtual void initParticleRendering();
|
||||
virtual void initGuiRendering();
|
||||
virtual void initPostProcessing();
|
||||
virtual void postProcess(){}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
#include "assetManager.h"
|
||||
#include "imageAsset.h"
|
||||
|
||||
#include "glad.h"
|
||||
#include <glad.h>
|
||||
#include <glfw3.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -207,6 +207,9 @@ namespace vb01{
|
||||
shapeKeys,
|
||||
numShapeKeys
|
||||
);
|
||||
|
||||
Root *root = Root::getSingleton();
|
||||
root->initVertexDataOnGpu(meshData, root->getMeshVAO(), root->getMeshVBO(), root->getMeshEBO(), true);
|
||||
Mesh *mesh = new Mesh(meshData);
|
||||
|
||||
return mesh;
|
||||
|
||||
Reference in New Issue
Block a user