Merge pull request #105 from devZoGok/develop

Develop
This commit is contained in:
devZoGok
2026-01-03 10:16:59 +00:00
committed by GitHub
24 changed files with 447 additions and 235 deletions
+1 -1
View File
@@ -11,6 +11,7 @@ namespace vb01{
class AssetManager{
public:
static AssetManager* getSingleton();
void readDir(std::string, std::vector<std::string>&, bool);
void load(std::string, bool = false);
void editAsset(std::string, Asset&);
Asset* getAsset(std::string);
@@ -19,7 +20,6 @@ namespace vb01{
inline int getNumAssets(){return assets.size();}
private:
AssetManager(){}
void readDir(std::string, std::vector<std::string>&, bool);
std::vector<Asset*> assets;
};
-1
View File
@@ -3,7 +3,6 @@
namespace vb01{
Box::Box(Vector3 size){
setSize(size);
construct();
}
void Box::setSize(Vector3 size){
+6 -7
View File
@@ -35,11 +35,12 @@ namespace vb01Gui{
mat->addVec4Uniform(diffColUni, color);
}
else{
mat->addBoolUniform(texUni, true);
string frame[]{imagePath};
Texture *tex = new Texture(frame, 1, false);
mat->addTexUniform("diffuseMap", tex, false);
textures.push_back(tex);
mat->addTexUniform("diffuseMap", tex, false);
mat->addBoolUniform(texUni, true);
}
rect->setMaterial(mat);
@@ -130,15 +131,13 @@ namespace vb01Gui{
if(textures[i]->getPath()[0] == image)
texId = i;
/*
if(texId == -1){
string p[]{image};
textures.push_back(new Texture(p, 1));
mat->setDiffuseMap(textures[textures.size() - 1], 0);
textures.push_back(new Texture(p, 1, false));
mat->setTexUniform("diffuseMap", textures[textures.size() - 1], false);
}
else
mat->setDiffuseMap(textures[texId], 0);
*/
mat->setTexUniform("diffuseMap", textures[texId], false);
this->imagePath = image;
}
+11 -3
View File
@@ -3,10 +3,18 @@
#include "asset.h"
#include <vector>
#include <utility>
#include <ft2build.h>
#include FT_FREETYPE_H
namespace vb01{
struct FontAsset : public Asset{
FT_Face face;
};
class Texture;
struct FontAsset : public Asset{
FT_Face face;
std::vector<std::pair<int, Texture*>> glyphTextures;
};
}
#endif
+1
View File
@@ -184,6 +184,7 @@ namespace vb01{
}
//TODO replace depth map id literals
//TODO implement logic to skip lighting if the material has lighting disabled
void Light::updateShader(vector<Material*> materials, int thisId, mat4 &proj, mat4 &view){
Vector3 position = node->localToGlobalPosition(Vector3::VEC_ZERO), direction = node->getGlobalAxis(2);
+3 -1
View File
@@ -35,6 +35,8 @@ namespace vb01Gui{
void scrollToHeight(float);
virtual void onOpen(){}
virtual void onClose(){}
inline void setName(std::string n){this->name = n;}
inline std::string getName(){return name;}
inline int getScrollOffset(){return scrollOffset;}
inline float getLineHeight(){return lineHeight;}
inline bool isOpen(){return open;}
@@ -60,7 +62,7 @@ namespace vb01Gui{
float lineHeight;
int maxDisplay, scrollOffset = 0;
bool open = false, closeable = false;
std::string fontPath;
std::string fontPath, name;
vb01::Vector3 pos, textOffset;
vb01::Vector2 size;
ListboxButton *listboxButton;
+11 -55
View File
@@ -30,51 +30,7 @@ namespace vb01{
for(Mesh *m : meshes)
delete m;
if(material)
delete material;
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &EBO);
glDeleteBuffers(1, &VBO);
}
//TODO allow to init meshes to be drawn statically or dynamically
void Mesh::construct(){
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
u32 size = sizeof(MeshData::GpuVertex);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
glBufferData(GL_ARRAY_BUFFER, 3 * meshBase.numTris * size, glVertData, GL_DYNAMIC_DRAW);
delete glVertData;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * meshBase.numTris * sizeof(u32), meshBase.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 < meshBase.numShapeKeys; i++){
glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, shapeKeyOffsets) + 3 * i * sizeof(float)));
glEnableVertexAttribArray(7 + i);
}
if(material) delete material;
}
void Mesh::initFramebuffer(u32 &framebuffer, u32 &renderbuffer, int width){
@@ -94,7 +50,7 @@ namespace vb01{
}
void Mesh::updateVerts(MeshData meshData){
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ARRAY_BUFFER, meshData.VBO);
MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::GpuVertex) * meshBase.numTris, glVertData);
@@ -130,8 +86,15 @@ namespace vb01{
float fov = cam->getFov(), width = root->getWidth(), height = root->getHeight(), nearPlane = cam->getNearPlane(), farPlane = cam->getFarPlane();
mat4 proj = perspective(radians(fov), width / height, nearPlane, farPlane);
material->update();
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");
if(skeleton)
updateSkeleton(shader);
@@ -142,13 +105,6 @@ namespace vb01{
if(reflect)
updateReflection(pos);
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(shader->getName() == "gui"){
shader->setVec2(Vector2((float)width, (float)height), "screen");
@@ -401,7 +357,7 @@ namespace vb01{
}
void Mesh::render(){
glBindVertexArray(VAO);
glBindVertexArray(meshBase.VAO);
glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL);
glDrawElements(GL_TRIANGLES, 3 * meshBase.numTris, GL_UNSIGNED_INT, 0);
}
-2
View File
@@ -20,7 +20,6 @@ namespace vb01{
public:
Mesh(MeshData);
~Mesh();
void construct();
void updateVerts(MeshData);
virtual void update();
void render();
@@ -67,7 +66,6 @@ namespace vb01{
int numShapeKeys = 0;
MeshData::ShapeKey *shapeKeys = nullptr;
bool castShadow = false, reflect = false, reflective = false, wireframe = false;
u32 VAO, VBO, EBO;
};
}
+75
View File
@@ -1,8 +1,83 @@
#include "meshData.h"
#include "glad.h"
#include <glfw3.h>
#include <glm.hpp>
#include <ext.hpp>
using namespace std;
namespace vb01{
//TODO allow to init meshes to be drawn statically or dynamically
MeshData::MeshData(
Vector3 *pos,
float **w,
int **bi,
Vector3 **sko,
int np,
Vector3 *norm,
Vertex *vert,
u32 *ind,
int nt,
std::string an,
std::string *vg,
int nvg,
std::string fsn,
ShapeKey *sk,
int nsk
) :
positions(pos),
weights(w),
boneIndices(bi),
shapeKeyOffsets(sko),
numPos(np),
normals(norm),
vertices(vert),
indices(ind),
numTris(nt),
vertexGroups(vg),
numVertexGroups(nvg),
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){
case KeyframeChannel::SHAPE_KEY_MIN:
+40 -55
View File
@@ -9,62 +9,47 @@
#include "animatable.h"
namespace vb01{
struct MeshData{
struct ShapeKey : public Animatable{
std::string name;
float minValue, value, maxValue;
ShapeKey(std::string n, float v, float mnv, float mxv) : name(n), value(v), minValue(mnv), maxValue(mxv), Animatable(Animatable::SHAPE_KEY, n){}
ShapeKey() : Animatable(Animatable::SHAPE_KEY){}
void animate(float, KeyframeChannel);
};
struct GpuVertex{
Vector3 pos, norm, tan, biTan;
Vector2 uv;
float weights[4]{0, 0, 0, 0};
int boneIndices[4]{-1, -1, -1, -1};
Vector3 shapeKeyOffsets[100];
};
struct Vertex{
Vector3 *pos = nullptr, *norm = nullptr, tan, biTan;
Vector2 uv;
float *weights = nullptr;
int *boneIndices = nullptr;
Vector3 *shapeKeyOffsets = nullptr;
};
GpuVertex* toGpuVerts();
Vector3 *positions = nullptr, *normals = nullptr, **shapeKeyOffsets = nullptr;
float **weights = nullptr;
int **boneIndices = nullptr;
Vertex *vertices;
std::string *vertexGroups = nullptr;
ShapeKey *shapeKeys = nullptr;
u32 *indices, VAO, VBO, EBO;
int numPos, numTris, numVertexGroups = 0, numShapeKeys = 0;
std::string attachableName = "", fullSkeletonName = "";
MeshData(){}
MeshData(Vector3 *pos, float **w, int **bi, Vector3 **sko, int np, Vector3 *norm, Vertex *vert, u32 *ind, int nt, std::string an = "", std::string *vg = nullptr, int nvg = 0, std::string fsn = "", ShapeKey *sk = nullptr, int nsk = 0) :
positions(pos),
weights(w),
boneIndices(bi),
shapeKeyOffsets(sko),
numPos(np),
normals(norm),
vertices(vert),
indices(ind),
numTris(nt),
vertexGroups(vg),
numVertexGroups(nvg),
fullSkeletonName(fsn),
shapeKeys(sk),
numShapeKeys(nsk)
{}
struct MeshData{
struct ShapeKey : public Animatable{
std::string name;
float minValue, value, maxValue;
ShapeKey(std::string n, float v, float mnv, float mxv) : name(n), value(v), minValue(mnv), maxValue(mxv), Animatable(Animatable::SHAPE_KEY, n){}
ShapeKey() : Animatable(Animatable::SHAPE_KEY){}
void animate(float, KeyframeChannel);
};
struct GpuVertex{
Vector3 pos, norm, tan, biTan;
Vector2 uv;
float weights[4]{0, 0, 0, 0};
int boneIndices[4]{-1, -1, -1, -1};
Vector3 shapeKeyOffsets[100];
};
struct Vertex{
Vector3 *pos = nullptr, *norm = nullptr, tan, biTan;
Vector2 uv;
float *weights = nullptr;
int *boneIndices = nullptr;
Vector3 *shapeKeyOffsets = nullptr;
};
GpuVertex* toGpuVerts();
Vector3 *positions = nullptr, *normals = nullptr, **shapeKeyOffsets = nullptr;
float **weights = nullptr;
int **boneIndices = nullptr;
Vertex *vertices;
std::string *vertexGroups = nullptr;
ShapeKey *shapeKeys = nullptr;
u32 *indices, VAO, VBO, EBO;
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);
};
}
#endif
+6 -10
View File
@@ -14,17 +14,13 @@ using namespace std;
namespace vb01{
Model::Model(string path) : Node(){
ModelAsset *asset = ((ModelAsset*)AssetManager::getSingleton()->getAsset(path));
Node *clonedRoot = asset->rootNode->clone();
vector<Node*> descendants = vector<Node*>{clonedRoot};
clonedRoot->getDescendants(descendants);
ModelAsset *asset = ((ModelAsset*)AssetManager::getSingleton()->getAsset(path));
Node *clonedRoot = asset->rootNode->clone();
vector<Node*> descendants = vector<Node*>{clonedRoot};
clonedRoot->getDescendants(descendants);
for(Node *desc : descendants)
for(Mesh *mesh : desc->getMeshes())
mesh->construct();
for(Node *child : clonedRoot->getChildren())
attachChild(child);
for(Node *child : clonedRoot->getChildren())
attachChild(child);
}
Model::~Model(){
+27 -27
View File
@@ -393,51 +393,51 @@ namespace vb01{
return Vector3(local.x, local.y, local.z);
}
Quaternion Node::adjustRot(vector<Node*> ancestors, Quaternion adjustableRot, bool localToGlobal){
Quaternion rOrigin = adjustableRot;
Quaternion Node::adjustRot(Quaternion adjustableRot, bool localToGlobal){
vector<Node*> ancestors = getAncestors();
Quaternion rOrigin = (localToGlobal ? Quaternion::QUAT_W : adjustableRot);
while(!ancestors.empty()){
int id = localToGlobal ? 0 : ancestors.size() - 1;
int id = (localToGlobal ? ancestors.size() - 1 : 0);
Node *node = ancestors[id], *nodePar = node->getParent();
float angle = ancestors[id]->getOrientation().getAngle();
Vector3 axis = ancestors[id]->getOrientation().getAxis();
Vector3 parAxis[]{
nodePar ? nodePar->getGlobalAxis(0) : Vector3::VEC_I,
nodePar ? nodePar->getGlobalAxis(1) : Vector3::VEC_J,
nodePar ? nodePar->getGlobalAxis(2) : Vector3::VEC_K
};
Vector3 axis = node->getOrientation().getAxis();
axis = (parAxis[0] * axis.x + parAxis[1] * axis.y + parAxis[2] * axis.z).norm();
float angle = node->getOrientation().getAngle();
Quaternion o;
if(localToGlobal){
Node *par = ancestors[id]->getParent();
Vector3 parAxis[]{
par ? par->getGlobalAxis(0) : Vector3::VEC_I,
par ? par->getGlobalAxis(1) : Vector3::VEC_J,
par ? par->getGlobalAxis(2) : Vector3::VEC_K
};
rOrigin = Quaternion(angle, axis) * rOrigin;
ancestors.pop_back();
axis = (parAxis[0] * axis.x + parAxis[1] * axis.y + parAxis[2] * axis.z).norm();
o = Quaternion(angle, axis);
rOrigin = rOrigin * o;
ancestors.erase(ancestors.begin());
if(ancestors.empty()){
Vector3 ax = adjustableRot.getAxis();
ax = (globalAxis[0] * ax.x + globalAxis[1] * ax.y + globalAxis[2] * ax.z).norm();
return Quaternion(adjustableRot.getAngle(), ax) * rOrigin;
}
}
else{
o = Quaternion(angle, axis).conj();
rOrigin = rOrigin * o;
rOrigin = rOrigin * Quaternion(angle, axis).conj();
ancestors.pop_back();
if(ancestors.empty())
return rOrigin;
}
}
return rOrigin;
}
Quaternion Node::localToGlobalOrientation(Quaternion localRot){
vector<Node*> ancestors = getAncestors();
Quaternion origin = adjustRot(ancestors, Quaternion::QUAT_W, true);
return localRot * origin;
return adjustRot(localRot, true);
}
Quaternion Node::globalToLocalOrientation(Quaternion globalRot){
vector<Node*> ancestors = getAncestors();
Quaternion origin = adjustRot(ancestors, globalRot, false);
return origin;
return adjustRot(globalRot, false);
}
Node* Node::findDescendant(string name, bool allDescendants){
+1 -1
View File
@@ -81,7 +81,7 @@ namespace vb01{
void adjustDir(Vector3);
void updateShaders();
Quaternion adjustRot(std::vector<Node*>, Quaternion, bool);
Quaternion adjustRot(Quaternion, bool);
std::vector<Driver*> drivers;
protected:
virtual void animate(float, KeyframeChannel);
+18 -1
View File
@@ -11,7 +11,6 @@ namespace vb01{
this->numHorDiv = numHorDiv;
setSize(size);
Mesh::construct();
}
void Quad::setSize(Vector3 size){
@@ -86,4 +85,22 @@ namespace vb01{
meshBase = MeshData(faceVertPos, nullptr, nullptr, nullptr, 6, norm, vertices, indices, numTris);
}
//TODO improve functionality for GUI quads
Vector2 Quad::getSubquadIds(int numVertDiv, int numHorDiv, Vector3 pos, Vector3 size){
const int numHorQuads = numVertDiv + 1, numVertQuads = numHorDiv + 1;
Vector2 subQuadSize = Vector2(size.x / numHorQuads, size.z / numVertQuads);
return Vector2(int((.5 * size.x + pos.x) / subQuadSize.x), int((.5 * size.z + pos.z) / subQuadSize.y));
}
Vector3 Quad::getSubquadCorner(int xId, int yId, int numVertDiv, int numHorDiv, bool top, bool right){
const int numHorQuads = numVertDiv + 1, numVertQuads = numHorDiv + 1;
int vertPosId = 6 * xId * numVertQuads + 6 * yId;
if(top && !right) return meshBase.positions[vertPosId];
else if(top && right) return meshBase.positions[vertPosId + 4];
else if(!top && !right) return meshBase.positions[vertPosId + 1];
else if(!top && right) return meshBase.positions[vertPosId + 3];
}
}
+5
View File
@@ -9,7 +9,12 @@ namespace vb01{
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 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:
Vector3 size;
bool spatial;
+53 -24
View File
@@ -56,14 +56,49 @@ namespace vb01{
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");
for(int i = 0; i < 2; i++)
pingPongTextures[i] = new Texture(width, height, false);
Texture *fragTexture = new Texture(width, height, false);
Texture *brightTexture = new Texture(width, height, false);
initMainFramebuffer(fragTexture, brightTexture);
initBloomFramebuffer();
initMainFramebuffer(fragTexture, nullptr);
initGuiPlane(fragTexture, brightTexture);
}
shader = new Shader(Root::getSingleton()->getLibPath() + "line3D");
void Root::toggleHDR(bool hdr){
glDeleteFramebuffers((hdr ? 2 : 1), &FBO);
glDeleteRenderbuffers(1, &RBO);
Texture *fragTexture = ((Material::TextureUniform*)guiPlane->getMaterial()->getUniform("frag"))->value;
Texture *brightTexture = ((Material::TextureUniform*)guiPlane->getMaterial()->getUniform("bright"))->value;
initMainFramebuffer(fragTexture, (hdr ? brightTexture : nullptr));
this->hdr = hdr;
}
void Root::initBloomFramebuffer(){
glGenFramebuffers(2, pingpongBuffers);
for(int i = 0; i < 2; i++){
glBindFramebuffer(GL_FRAMEBUFFER, pingpongBuffers[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *(pingPongTextures[i]->getTexture()), 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "Not complete\n";
}
}
void Root::toggleBloom(bool bloom){
this->bloom = bloom;
if(bloom)
initBloomFramebuffer();
else
glDeleteFramebuffers(2, pingpongBuffers);
}
void Root::initWindow(string name){
@@ -101,11 +136,14 @@ namespace vb01{
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
u32 colorAttachments[]{GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[0], GL_TEXTURE_2D, *fragTexture->getTexture(), 0);
for(int i = 0; i < 2; i++)
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D, *((i == 0 ? fragTexture : brightTexture)->getTexture()), 0);
glDrawBuffers(2, colorAttachments);
if(brightTexture){
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[1], GL_TEXTURE_2D, *brightTexture->getTexture(), 0);
glDrawBuffers(2, colorAttachments);
}
else
glDrawBuffers(1, colorAttachments);
glGenRenderbuffers(1, &RBO);
glBindRenderbuffer(GL_RENDERBUFFER, RBO);
@@ -118,20 +156,6 @@ namespace vb01{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Root::initBloomFramebuffer(){
blurShader = new Shader(libPath + "blur");
glGenFramebuffers(2, pingpongBuffers);
for(int i = 0; i < 2; i++){
glBindFramebuffer(GL_FRAMEBUFFER, pingpongBuffers[i]);
pingPongTextures[i] = new Texture(width, height, false);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *(pingPongTextures[i]->getTexture()), 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "Not complete\n";
}
}
void Root::initGuiPlane(Texture *fragTexture, Texture *brightTexture){
guiPlane = new Quad(Vector3(width, height, -1), false);
Material *mat = new Material(libPath + "postProcess");
@@ -167,7 +191,8 @@ namespace vb01{
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
updateBloomFramebuffer();
if(bloom) updateBloomFramebuffer();
updateGuiPlane();
glEnable(GL_DEPTH_TEST);
@@ -259,10 +284,14 @@ namespace vb01{
shader->setFloat(exposure, "exposure");
shader->setFloat(gamma, "gamma");
shader->setInt(0, "frag");
shader->setInt(1, "bright");
((Material::TextureUniform*)material->getUniform("frag"))->value->select(0);
((Material::TextureUniform*)material->getUniform("bright"))->value->select(1);
if(hdr){
shader->setInt(1, "bright");
((Material::TextureUniform*)material->getUniform("bright"))->value->select(1);
}
guiPlane->render();
}
+2 -2
View File
@@ -23,6 +23,8 @@ namespace vb01{
public:
void update();
void start(int, int, std::string, std::string);
void toggleHDR(bool);
void toggleBloom(bool);
inline Camera* getCamera(){return camera;}
inline Node* getRootNode(){return rootNode;}
inline Node* getGuiNode(){return guiNode;}
@@ -31,10 +33,8 @@ namespace vb01{
inline u32* getFBO(){return &FBO;}
inline u32* getRBO(){return &RBO;}
inline GLFWwindow* getWindow(){return window;}
inline void setHDREnabled(bool hdr){this->hdr = hdr;}
inline void setExposure(float exposure){this->exposure = exposure;}
inline void setGamma(float gamma){this->gamma = gamma;}
inline void setBloom(bool bloom){this->bloom = bloom;}
inline void setBlurLevel(bool level){this->blurLevel = level;}
inline Box* getSkybox(){return skybox;}
inline Box* getIblBox(){return iblBox;}
+24 -23
View File
@@ -4,7 +4,6 @@
#include "texture.h"
#include "node.h"
#include "material.h"
#include "fontAsset.h"
#include "assetManager.h"
#include "glad.h"
@@ -23,17 +22,20 @@ namespace vb01{
}
Text::~Text(){
clearFont();
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
}
//TODO ensure destruction of textures when unloading the asset
void Text::applyFont(string fontPath, u16 firstChar, u16 lastChar){
clearFont();
characters.clear();
FontAsset *font = (FontAsset*)AssetManager::getSingleton()->getAsset(fontPath);
font = (FontAsset*)AssetManager::getSingleton()->getAsset(fontPath);
FT_Face face = font->face;
vector<int> keys;
for (pair<int, Texture*> p : font->glyphTextures)
keys.push_back(p.first);
for(u16 i = firstChar; i < lastChar; i++){
if(FT_Load_Char(face, i, FT_LOAD_RENDER)){
@@ -43,21 +45,18 @@ namespace vb01{
Glyph c;
c.ch = i;
c.texture = new Texture(face);
c.size = Vector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
c.bearing = Vector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
c.advance = face->glyph->advance.x;
c.texId = i;
if(find(keys.begin(), keys.end(), i) == keys.end())
font->glyphTextures.push_back(make_pair(i, new Texture(face)));
characters.push_back(c);
}
}
void Text::clearFont(){
while(!characters.empty()){
delete characters[characters.size() - 1].texture;
characters.pop_back();
}
}
void Text::update(){
Root *root = Root::getSingleton();
int width = root->getWidth(), height = root->getHeight();
@@ -72,11 +71,17 @@ namespace vb01{
for(int i = (leftToRight ? 0 : entry.length() - 1); (leftToRight ? (i < entry.length()) : (i >= 0)); (leftToRight ? i++ : i--)){
Glyph *glyphPtr = getGlyph(entry[i]);
if(!glyphPtr)
continue;
if(!glyphPtr) continue;
int glyphTexId = -1;
for(int j = 0; j < font->glyphTextures.size(); j++)
if(font->glyphTextures[j].first == glyphPtr->texId){
glyphTexId = j;
break;
}
Glyph glyph = *glyphPtr;
prepareGlyphs(glyph, advanceOffset);
prepareGlyphs(glyph, glyphTexId, advanceOffset);
Vector2 size = glyph.size, bearing = glyph.bearing;
if(horizontal)
@@ -86,7 +91,7 @@ namespace vb01{
}
}
void Text::prepareGlyphs(Glyph glyph, Vector2 advanceOffset){
void Text::prepareGlyphs(Glyph glyph, int glyphTexId, Vector2 advanceOffset){
Vector3 nodePos = node->getPosition();
Vector2 origin = Vector2(nodePos.x, nodePos.y) + (advanceOffset * scale);
Vector3 scale = node->getScale();
@@ -104,17 +109,13 @@ namespace vb01{
origin.x + bearing.x, origin.y - bearing.y, 0, 0
};
renderGlyphs(glyph, data, sizeof(data));
}
void Text::renderGlyphs(Glyph glyph, float data[], u32 dataSize){
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, data);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data);
int id = 2;
material->getShader()->setInt(id, "textures[1].pastTexture");
glyph.texture->select(id);
font->glyphTextures[glyphTexId].second->select(id);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
+4 -4
View File
@@ -4,13 +4,13 @@
#include <string>
#include <vector>
#include "fontAsset.h"
#include "attachable.h"
#include "vector.h"
#include "util.h"
namespace vb01{
class Node;
class Texture;
class Shader;
class Material;
@@ -18,7 +18,7 @@ namespace vb01{
public:
struct Glyph{
u16 ch;
Texture *texture = nullptr;
int texId;
u32 advance;
Vector2 size, bearing;
};
@@ -41,9 +41,9 @@ namespace vb01{
private:
void applyFont(std::string, u16, u16 = 256);
void clearFont();
void prepareGlyphs(Glyph, Vector2);
void renderGlyphs(Glyph, float[], u32);
void prepareGlyphs(Glyph, int, Vector2);
FontAsset *font = nullptr;
Material *material = nullptr;
std::wstring entry;
std::vector<Glyph> characters;
+6 -5
View File
@@ -15,7 +15,7 @@
using namespace std;
namespace vb01{
Texture::Texture(int width, int height, bool shadowMap) : Animatable(Animatable::TEXTURE){
Texture::Texture(int width, int height, bool shadowMap, bool hiRes) : Animatable(Animatable::TEXTURE){
this->width = width;
this->height = height;
texture = new u32;
@@ -33,8 +33,7 @@ namespace vb01{
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
}
else{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
//glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
glTexImage2D(GL_TEXTURE_2D, 0, (hiRes ? GL_RGB16F : GL_RGB), width, height, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -60,7 +59,9 @@ namespace vb01{
}
}
void Texture::loadImageData(ImageAsset *asset, int i){
void Texture::loadImageData(ImageAsset *asset, bool creating, int i){
if(!creating) glDeleteTextures(1, &texture[i]);
width = asset->width;
height = asset->height;
@@ -79,7 +80,7 @@ namespace vb01{
if(paths[i].substr(length - 4, string::npos) == ".png")
png = true;
loadImageData((ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]));
loadImageData((ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]), true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+2 -2
View File
@@ -15,14 +15,14 @@ namespace vb01{
class Texture : public Animatable{
public:
~Texture();
Texture(int, int, bool = true);
Texture(int, int, bool = true, bool = false);
Texture(std::string[], int, bool, int = 0, bool = false, std::string = "");
Texture(int, bool = true, int = 0, std::string = "");
Texture(FT_Face);
void select(int = 0, int = 0);
void update(int = 0);
void animate(float, KeyframeChannel);
void loadImageData(ImageAsset*, int = 0);
void loadImageData(ImageAsset*, bool, int = 0);
inline u32* getTexture(int i = 0){return &(texture[i]);}
inline std::string* getPath(){return paths;}
inline int getNumFrames(){return numFrames;}
+130 -10
View File
@@ -7,20 +7,140 @@
using namespace std;
namespace vb01{
double *x = nullptr, *y = nullptr;
double *x = nullptr, *y = nullptr;
Vector2 getCursorPos()
{
if(!x)
x = new double;
Vector2 getCursorPos() {
if(!x) x = new double;
if(!y)
y = new double;
glfwGetCursorPos(Root::getSingleton()->getWindow(), x, y);
return Vector2(*x, *y);
if(!y) y = new double;
glfwGetCursorPos(Root::getSingleton()->getWindow(), x, y);
return Vector2(*x, *y);
}
bool rectInter(Vector2 rp1, Vector2 rd1, Vector2 rps1, Vector2 p2[]){
for(int i = 0; i < 4; i++){
Vector2 pv = p2[i] - rp1;
float pd = pv.getLength(), angle = rd1.getAngleBetween(pv.norm());
angle = (angle > PI / 2 ? PI - angle : angle);
bool b1 = (pd * sin(angle) <= .5 * rps1.x);
bool b2 = (pd * cos(angle) <= .5 * rps1.y);
if(b1 && b2) return true;
}
return false;
}
bool segmInter(Vector2 p1[], Vector2 p2[]){
pair<Vector2, Vector2> e1[]{
make_pair(p1[0], p1[1]),
make_pair(p1[1], p1[2]),
make_pair(p1[2], p1[3]),
make_pair(p1[3], p1[0])
};
pair<Vector2, Vector2> e2[]{
make_pair(p2[0], p2[1]),
make_pair(p2[1], p2[2]),
make_pair(p2[2], p2[3]),
make_pair(p2[3], p2[0])
};
for(int i = 0; i < 4; i++){
//float a = hypVec.z / hypVec.x;
//float b = pos.z - a * pos.x;
Vector2 e1Vec = e1[i].second - e1[i].first;
float a1, b1, x1;
bool vert1 = true;
if(e1Vec.x != 0){
vert1 = false;
a1 = e1Vec.y / e1Vec.x;
b1 = e1[i].second.y - a1 * e1[i].second.x;
}
else x1 = e1[i].first.x;
for(int j = 0; j < 4; j++){
Vector2 e2Vec = e2[j].second - e2[j].first;
float a2, b2, x2;
bool vert2 = true;
if(e2Vec.x != 0){
vert2 = false;
a2 = e2Vec.y / e2Vec.x;
b2 = e2[j].second.y - a2 * e2[j].second.x;
}
else x2 = e2[j].first.x;
if(!vert1 && !vert2){
if(a1 - a2 == 0) continue;
float x = (b1 - b2) / (a1 - a2);
float y = a1 * x + b1;
if(
(e1[i].first.x < x && x < e1[i].second.x) &&
(e1[i].first.y < y && y < e1[i].second.y)
){
return true;
}
}
else if(!vert1 && vert2){
float minX = e1[i].first.x, maxX = e1[i].second.x;
float minY = e2[i].first.y, maxY = e2[i].second.y;
if(minX > maxX) swap(minY, maxY);
if(minY > maxY) swap(minY, maxY);
float y = a1 * x2 + b1;
if((minX < x2 && x2 < maxX) && (minY < y && y < maxY)){
return true;
}
}
else if(vert1 && !vert2){
float minX = e2[j].first.x, maxX = e2[j].second.x;
float minY = e1[j].first.y, maxY = e1[j].second.y;
if(minX > maxX) swap(minY, maxY);
if(minY > maxY) swap(minY, maxY);
float y = a2 * x1 + b2;
if((minX < x1 && x1 < maxX) && (minY < y && y < maxY)){
return true;
}
}
}
}
return false;
}
bool rectanglesIntersect(Vector2 rp1, Vector2 rd1, Vector2 rdl1, Vector2 rps1, Vector2 rp2, Vector2 rd2, Vector2 rdl2, Vector2 rps2){
Vector2 p1[]{
rp1 + .5 * (rdl1 * rps1.x + rd1 * rps1.y),
rp1 + .5 * (-rdl1 * rps1.x + rd1 * rps1.y),
rp1 + .5 * (-rdl1 * rps1.x - rd1 * rps1.y),
rp1 + .5 * (rdl1 * rps1.x - rd1 * rps1.y)
};
Vector2 p2[]{
rp2 + .5 * (rdl2 * rps2.x + rd2 * rps2.y),
rp2 + .5 * (-rdl2 * rps2.x + rd2 * rps2.y),
rp2 + .5 * (-rdl2 * rps2.x - rd2 * rps2.y),
rp2 + .5 * (rdl2 * rps2.x - rd2 * rps2.y)
};
if(rectInter(rp1, rd1, rps1, p2)) return true;
if(rectInter(rp2, rd2, rps2, p1)) return true;
if(segmInter(p1, p2)) return true;
return false;
}
void readFile(string path, vector<string> &lines, int firstLine, int lastLine){
string l;
std::ifstream inFile(path);
+3
View File
@@ -21,6 +21,9 @@ namespace vb01{
static const float PI = 4 * atan(1);
bool rectInter(Vector2, Vector2, Vector2, Vector2[]);
bool segmInter(Vector2[], Vector2[]);
bool rectanglesIntersect(Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector2, Vector2);
void readFile(std::string, std::vector<std::string>&, int = 0, int = -1);
void getLineData(std::string, std::string[], int, int = 0);
int findNthOccurence(std::string&, std::string, int, bool = true);
+18 -1
View File
@@ -190,7 +190,24 @@ namespace vb01{
const char *fullSkeletonName = meshEl->Attribute("skeleton");
string name = string(meshEl->Parent()->ToElement()->Attribute("name")) + string(meshEl->Attribute("name"));
Mesh *mesh = new Mesh(MeshData(vertPos, weights, boneIndices, shapeKeyOffsets, numVertPos, normals, vertices, indices, numVertices / 3, name, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys));
MeshData meshData = MeshData(
vertPos,
weights,
boneIndices,
shapeKeyOffsets,
numVertPos,
normals,
vertices,
indices,
numVertices / 3,
name,
vertexGroups,
numVertexGroups,
(fullSkeletonName ? fullSkeletonName : ""),
shapeKeys,
numShapeKeys
);
Mesh *mesh = new Mesh(meshData);
return mesh;
}