Box/Quad clone methods

Phong lighting shaders
using multi draw indirect rendering
This commit is contained in:
devZoGok
2026-06-26 09:40:46 +03:00
parent 02c0c3b3fc
commit cc59f9160c
22 changed files with 873 additions and 168 deletions
+10 -4
View File
@@ -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);
}
}
+5 -1
View File
@@ -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
View File
@@ -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();
+2 -2
View File
@@ -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
View File
@@ -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();
}
}
}
+16 -23
View File
@@ -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;
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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&);
};
}
+1 -2
View File
@@ -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();
+1
View File
@@ -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
View File
@@ -1,5 +1,5 @@
#include <algorithm>
#include "glad.h"
#include <glad.h>
#include <glfw3.h>
#include <cstdlib>
#include <ext.hpp>
Executable
+196
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+11 -8
View File
@@ -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
+5 -1
View File
@@ -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;
+317 -47
View File
@@ -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]){
+61 -11
View File
@@ -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
View File
@@ -1,4 +1,4 @@
#include "glad.h"
#include <glad.h>
#include <glfw3.h>
#include <iostream>
+1 -1
View File
@@ -8,7 +8,7 @@
#include "assetManager.h"
#include "imageAsset.h"
#include "glad.h"
#include <glad.h>
#include <glfw3.h>
#include <iostream>
+3
View File
@@ -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;