Fixed broken draw of Nodes

This commit is contained in:
brunoherbelin
2020-04-08 00:42:18 +02:00
parent 1e9acb544a
commit de08b056fb
12 changed files with 208 additions and 159 deletions

View File

@@ -194,6 +194,7 @@ include_directories(
${TINYFD_INCLUDE_DIR}
${STB_INCLUDE_DIR}
${DIRENT_INCLUDE_DIR}
${OBJLOADER_INCLUDE_DIR}
)
@@ -235,7 +236,7 @@ set(VMIX_RSC_FILES
./rsc/images/busy.png
./rsc/images/icons.dds
./rsc/images/seed_512.jpg
./rsc/images/shadow.jpg
./rsc/models/shadow.png
./rsc/models/square_border.obj
./rsc/models/shadow.mtl
)

View File

@@ -4,6 +4,7 @@
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
#include "ObjLoader.h"
#include <glad/glad.h>
@@ -71,14 +72,14 @@ void ImageSurface::init()
}
}
void ImageSurface::draw(glm::mat4 projection)
void ImageSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
glBindTexture(GL_TEXTURE_2D, textureindex_);
Primitive::draw(projection);
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
@@ -111,7 +112,7 @@ void MediaSurface::init()
mediaplayer_->play(true);
}
void MediaSurface::draw(glm::mat4 projection)
void MediaSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
@@ -121,7 +122,7 @@ void MediaSurface::draw(glm::mat4 projection)
else
glBindTexture(GL_TEXTURE_2D, textureindex_);
Primitive::draw(projection);
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
@@ -130,6 +131,12 @@ void MediaSurface::update( float dt )
{
if ( mediaplayer_->isOpen() ) {
mediaplayer_->update();
if (parent_ != nullptr) {
parent_->transform_ = parent_->transform_ * glm::scale(glm::identity<glm::mat4>(), glm::vec3(mediaplayer_->aspectRatio(), 1.f, 1.f));
scale_.x = 1.0;
}
else
scale_.x = mediaplayer_->aspectRatio();
}
@@ -161,13 +168,14 @@ void LineStrip::init()
shader_ = new Shader();
}
void LineStrip::draw(glm::mat4 projection)
void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
glLineWidth(linewidth_);
Primitive::draw(projection);
Primitive::draw(modelview, projection);
}
void LineStrip::accept(Visitor& v)
@@ -223,3 +231,74 @@ void LineCircle::accept(Visitor& v)
Primitive::accept(v);
v.visit(*this);
}
ObjModel::ObjModel(const std::string& path) : Primitive(), textureindex_(0)
{
// for obj model
filename_ = path;
// load geometry
std::vector<glm::vec3> normals; // ignored
std::string material_filename;
bool okay = loadObject( Resource::getText(filename_), points_, normals, texCoords_, indices_, material_filename, 1.0 );
if ( !okay ) {
Log::Warning("Failed to load OBJ model %s", path.c_str());
}
// prepend path to the name of other files
std::string rsc_path = filename_.substr(0, filename_.rfind('/')) + "/";
// load materials
std::map<std::string,Material*> material_library;
okay = loadMaterialLibrary(Resource::getText( rsc_path + material_filename ), material_library);
if (okay) {
Material *material_ = material_library.begin()->second; // default use first material
// fill colors
for (int i = 0; i < points_.size(); i++)
colors_.push_back(material_->diffuse);
if (!material_->diffuseTexture.empty()) {
texture_filename_ = rsc_path + material_->diffuseTexture;
}
delete material_;
}
drawingPrimitive_ = GL_TRIANGLES;
}
void ObjModel::init()
{
Primitive::init();
if (!texture_filename_.empty())
{
// create shader for textured image
textureindex_ = Resource::getTextureImage(texture_filename_);
shader_ = new ImageShader();
}
else {
shader_ = new Shader();
}
}
void ObjModel::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
if (textureindex_)
glBindTexture(GL_TEXTURE_2D, textureindex_);
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
void ObjModel::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}

View File

@@ -14,10 +14,10 @@ public:
ImageSurface(const std::string& path = "" );
void init () override;
void draw (glm::mat4 projection) override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
std::string getFilename() { return filename_; }
inline std::string getFilename() const { return filename_; }
protected:
std::string filename_;
@@ -37,7 +37,7 @@ public:
~MediaSurface();
void init () override;
void draw (glm::mat4 projection) override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
void update ( float dt ) override;
@@ -67,12 +67,14 @@ public:
LineStrip(std::vector<glm::vec3> points, glm::vec3 color, uint linewidth = 1);
virtual void init() override;
virtual void draw(glm::mat4 projection) override;
virtual void draw(glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override;
std::vector<glm::vec3> getPoints() { return points_; }
glm::vec3 getColor() { return colors_[0]; }
uint getLineWidth() { return linewidth_; }
inline void setLineWidth(uint v) { linewidth_ = v; }
inline uint getLineWidth() const { return linewidth_; }
};
class LineSquare : public LineStrip {
@@ -93,22 +95,23 @@ public:
};
//// Draw a Rectangle (triangle strip) with a texture
//class ObjModel : public Primitive {
// Draw a Rectangle (triangle strip) with a texture
class ObjModel : public Primitive {
//public:
// ObjModel(const std::string& path = "" );
public:
ObjModel(const std::string& path = "" );
// void init () override;
// void draw (glm::mat4 projection) override;
// void accept (Visitor& v) override;
void init () override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
// std::string getFilename() { return filename_; }
inline std::string getFilename() const { return filename_; }
//protected:
// std::string filename_;
// uint textureindex_;
//};
protected:
std::string filename_;
std::string texture_filename_;
uint textureindex_;
};
#endif // PRIMITIVES_H

View File

@@ -225,7 +225,8 @@ uint Resource::getTextureImage(const std::string& path, float *aspect_ratio)
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);
// free memory

View File

@@ -36,9 +36,7 @@ Node::Node() : initialized_(false), parent_(nullptr), visible_(true)
auto duration = std::chrono::system_clock::now().time_since_epoch();
id_ = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 100000000;
localToRender_ = glm::identity<glm::mat4>();
renderToLocal_ = glm::identity<glm::mat4>();
transform_ = glm::identity<glm::mat4>();
scale_ = glm::vec3(1.f);
rotation_ = glm::vec3(0.f);
translation_ = glm::vec3(0.f);
@@ -47,16 +45,8 @@ Node::Node() : initialized_(false), parent_(nullptr), visible_(true)
void Node::update( float dt )
{
// update transform matrix from attributes
glm::mat4 T = transform(translation_, rotation_, scale_);
transform_ = transform(translation_, rotation_, scale_);
if ( parent_ ) {
localToRender_ = parent_->localToRender_ * T;
renderToLocal_ = glm::inverse(T) * parent_->renderToLocal_;
}
else {
localToRender_ = T;
renderToLocal_ = glm::inverse(T);
}
}
@@ -130,7 +120,7 @@ void Primitive::init()
Node::init();
}
void Primitive::draw(glm::mat4 projection)
void Primitive::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
@@ -141,7 +131,7 @@ void Primitive::draw(glm::mat4 projection)
//
if (shader_) {
shader_->projection = projection;
shader_->modelview = localToRender_;
shader_->modelview = modelview * transform_;
shader_->use();
}
//
@@ -194,17 +184,20 @@ void Group::update( float dt )
}
}
void Group::draw(glm::mat4 projection)
void Group::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
if ( visible_ ) {
// append the instance transform to the ctm
glm::mat4 ctm = modelview * transform_;
// draw every child node
for (NodeSet::iterator node = children_.begin();
node != children_.end(); node++) {
(*node)->draw (projection );
(*node)->draw ( ctm, projection );
}
}
}
@@ -256,7 +249,7 @@ void Switch::update( float dt )
(*active_)->update( dt );
}
void Switch::draw(glm::mat4 projection)
void Switch::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
@@ -264,7 +257,7 @@ void Switch::draw(glm::mat4 projection)
if ( visible_ ) {
// draw current child
if (active_ != children_.end())
(*active_)->draw(projection);
(*active_)->draw( modelview * transform_, projection);
}
}

15
Scene.h
View File

@@ -35,7 +35,7 @@ public:
virtual bool initialized () { return initialized_; }
// pure virtual draw : to be instanciated to define node behavior
virtual void draw (glm::mat4 projection) = 0;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) = 0;
// update every frame
virtual void update (float dt);
@@ -47,8 +47,7 @@ public:
Node* parent_;
bool visible_;
glm::mat4 localToRender_;
glm::mat4 renderToLocal_;
glm::mat4 transform_;
glm::vec3 scale_, rotation_, translation_;
};
@@ -83,10 +82,10 @@ public:
virtual void init () override;
virtual void accept (Visitor& v) override;
virtual void draw (glm::mat4 projection) override;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) override;
Shader *getShader() { return shader_; }
void setShader( Shader* e ) { shader_ = e; }
inline Shader *getShader() const { return shader_; }
inline void setShader( Shader* e ) { shader_ = e; }
protected:
Shader* shader_;
@@ -109,7 +108,7 @@ public:
virtual void init () override;
virtual void update (float dt) override;
virtual void accept (Visitor& v) override;
virtual void draw (glm::mat4 projection) override;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) override;
virtual void addChild (Node *child);
virtual void removeChild (Node *child);
@@ -129,7 +128,7 @@ public:
virtual void update (float dt) override;
virtual void accept (Visitor& v) override;
virtual void draw (glm::mat4 projection) override;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) override;
void addChild (Node *child) override;
void removeChild (Node *child) override;

View File

@@ -139,21 +139,11 @@ makeMtlFilename ( std::string mtlfile, std::string objfile )
}
bool loadMaterialLibrary ( string mtlfilename,
string objfilename,
bool loadMaterialLibrary ( string mtlText,
map<string,Material*> &outMaterials)
{
string filename = makeMtlFilename( mtlfilename, objfilename );
string path = filename;
ifstream ifs ( path.c_str(), ifstream::in );
if (!ifs) {
std::cout << "can't open " << filename << std::endl;
// create a default texture
Material *m = new Material();
outMaterials["dummy1"] = m;
return false;
}
Material *mat = nullptr;
stringstream ifs(mtlText);
char buffer[512];
while (ifs.good()) {
ifs.getline(buffer,512);
@@ -161,64 +151,45 @@ bool loadMaterialLibrary ( string mtlfilename,
istringstream iss(line);
string token;
vec3 color;
Material *mat;
iss >> token;
if (token.compare("newmtl") ==0) {
// create a new material and store in map
mat = new Material;
iss >> token;
outMaterials[token] = mat;
} else if (token.compare("Ka") == 0) {
mat->ambient = vec4 ( toVec3 ( iss ), 1.0 );
} else if (token.compare("Kd") == 0) {
mat->diffuse = vec4 ( toVec3 ( iss ), 1.0);
} else if (token.compare("Ks") == 0) {
mat->specular = vec4 ( toVec3 ( iss ), 1.0);
} else if (token.compare("Ns") == 0) {
float shininess;
} else if (token.compare("Ka") == 0 && mat) {
mat->ambient = toVec3 ( iss );
} else if (token.compare("Kd") == 0 && mat) {
mat->diffuse = toVec3 ( iss );
} else if (token.compare("Ks") == 0 && mat) {
mat->specular = toVec3 ( iss );
} else if (token.compare("Ns") == 0 && mat) {
iss >> mat->shininess;
} else if (token.compare("map_Kd") == 0) {
string filename,path;
iss >> filename;
if (filename[0] == '/') {
mat->diffuseTexture = filename; // diffuse in unit 0
} else {
path = makeMtlFilename ( filename, objfilename );
mat->diffuseTexture = path; // diffuse in unit 0
}
if (DEBUG)
std::cout << "map_Kd from " << filename << std::endl;
} else if (token.compare("map_Disp") == 0) {
string filename, path;
iss >> filename;
if ( filename[0] == '/' ) {
mat->bumpTexture = filename; // bump in unit 1
} else {
path = makeMtlFilename ( filename, objfilename );
mat->bumpTexture = path; // diffuse in unit 0
}
} else if (token.compare("map_Kd") == 0 && mat) {
iss >> mat->diffuseTexture;
} else if (token.compare("map_Disp") == 0 && mat) {
iss >> mat->bumpTexture;
}
}
return true;
return (mat != nullptr);
}
bool loadObject(string filename,
bool loadObject(string objText,
vector<vec3> &outPositions,
vector<vec3> &outNormal,
vector<vec2> &outUv,
vector<unsigned int> &outIndices,
Material *outMaterial,
std::string &outMtlfilename,
float scale)
{
vector<vec3> positions;
vector<vec3> normals;
vector<vec2> uvs;
vector<TriangleString> triangles;
ifstream ifs ( filename , ifstream::in );
stringstream ifs(objText);
char buffer[512];
while (ifs.good()){
ifs.getline(buffer,512);
@@ -231,14 +202,8 @@ bool loadObject(string filename,
// does not support multiple objects
} else if (token.compare("g")==0){
} else if (token.compare("mtllib")==0){
// read the .mtl file and create the Materials
map<string,Material*> materials;
string mtlfile;
iss >> mtlfile;
loadMaterialLibrary( mtlfile.c_str(),
filename,
materials);
outMaterial = materials[0];
// read the name of .mtl file
iss >> outMtlfilename;
} else if (token.compare("usemtl")==0){
// does not support multiple materials
} else if (token.compare("v")==0){
@@ -266,8 +231,6 @@ bool loadObject(string filename,
}
}
}
ifs.close();
map<TriangleIndex,int> cache;
for (int i=0;i<triangles.size();i++){
@@ -303,9 +266,9 @@ Material *
makeDefaultMaterial()
{
Material *m = new Material;
m->ambient = vec4 ( 0.1, 0.1, 0.1, 1.0 );
m->diffuse = vec4 ( 0.8, 0.8, 0.8, 1.0 );
m->specular = vec4 ( 1.0, 1.0, 1.0, 1.0 );
m->ambient = vec3 ( 0.1, 0.1, 0.1 );
m->diffuse = vec3 ( 0.8, 0.8, 0.8 );
m->specular = vec3 ( 1.0, 1.0, 1.0 );
m->shininess = 200.0f;
return m;
}
@@ -371,9 +334,9 @@ bool loadObjectGroups ( string filename,
// read the .mtl file and create the Materials
string mtlfile;
iss >> mtlfile;
loadMaterialLibrary( mtlfile.c_str(),
filename,
materials);
// loadMaterialLibrary( mtlfile.c_str(),
// filename,
// materials);
} else if (token.compare("usemtl")==0){
// create group if none exists, or if this is a "usemtl" line without a preceding "g" line
if ( currentGroupName=="" || groups[currentGroupName]->triangles.size() ) {

View File

@@ -34,22 +34,23 @@
#include <string>
#include <vector>
#include <map>
#include <glm/glm.hpp>
struct Material
{
Material() :
ambient (0.1, 0.1, 0.1, 1.0),
diffuse (0.8, 0.8, 0.8, 1.0),
specular(1.0, 1.0, 1.0, 1.0 ),
Material() :
ambient (0.1, 0.1, 0.1),
diffuse (0.8, 0.8, 0.8),
specular(1.0, 1.0, 1.0),
shininess(75.0)
{}
virtual ~Material() { }
glm::vec4 ambient;
glm::vec4 diffuse;
glm::vec4 specular;
glm::vec3 ambient;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
std::string diffuseTexture;
@@ -60,23 +61,28 @@ Material() :
// The original version, modified for glm.
// Load an OBJ model into the out parameters.
// Note only simple OBJ files are supported.
bool loadObject (std::string filename,
bool loadObject (std::string objText,
std::vector<glm::vec3> &outPositions,
std::vector<glm::vec3> &outNormal,
std::vector<glm::vec2> &outUv,
std::vector<int> &outIndices,
Material *outMaterial,
std::vector<unsigned int> &outIndices,
std::string &outMtlfilename,
float scale = 1.0f
);
bool loadMaterialLibrary ( std::string mtlText,
std::map<std::string,Material*> &outMaterials
);
// this tries to handle multiple materials (w/textures) and groups of faces as per pcl_kinfu_largeScale, etc
bool loadObjectGroups (std::string filename,
std::vector<glm::vec3> &outPositions,
std::vector<glm::vec3> &outNormal,
std::vector<glm::vec2> &outUv,
std::vector<std::vector<int> > &outIndices, // per group
std::vector<std::vector<unsigned int> > &outIndices, // per group
std::vector<Material *> &outMaterials, // per group (w/textures)
float scale=1.0f
);
);
#endif

View File

@@ -58,7 +58,7 @@ Scene scene;
FrameBuffer *output;
MediaSurface testnode1("file:///home/bhbn/Videos/iss.mov");
MediaSurface testnode2("file:///home/bhbn/Videos/fish.mp4");
ImageSurface testnode3("images/v-mix_256x256.png");
ImageSurface testnode3("images/seed_512.jpg");
void drawMediaPlayer()
@@ -183,13 +183,14 @@ void drawScene()
scene.root_.update( static_cast<float>( GST_TIME_AS_MSECONDS(dt)) * 0.001f );
// draw in output frame buffer
glm::mat4 MV = glm::identity<glm::mat4>();
glm::mat4 P = glm::scale( glm::ortho(-5.f, 5.f, -5.f, 5.f), glm::vec3(1.f, output->aspectRatio(), 1.f));
output->begin();
scene.root_.draw(P);
scene.root_.draw(MV, P);
output->end();
// draw in main view
scene.root_.draw(Rendering::manager().Projection());
scene.root_.draw(MV, Rendering::manager().Projection());
// draw GUI tree scene
ImGui::Begin(IMGUI_TITLE_MAINWINDOW);
@@ -254,25 +255,28 @@ int main(int, char**)
// init elements to the scene
//testnode3.getShader()->blending = Shader::BLEND_OPACITY;
glm::vec3 color( 1.f, 1.f, 0.f );
LineCircle border(color);
// LineSquare border(color);
glm::vec3 color( 0.8f, 0.8f, 0.f );
// LineCircle border(color);
LineSquare border(color, 2);
ObjModel shadow("models/square_border.obj");
Group g1;
g1.translation_ = glm::vec3(1.f, 1.f, 0.f);
g1.scale_ = glm::vec3(2.f, 2.f, 1.f);
g1.scale_ = glm::vec3(1.2f, 1.2f, 1.f);
Switch g2;
Group g2;
g2.translation_ = glm::vec3(-1.f, -1.f, 0.f);
// g2.rotation_ = glm::vec3(0.0f, 0.0f, 1.0f);
// build tree
g1.addChild(&shadow);
g1.addChild(&testnode3);
g1.addChild(&border);
scene.root_.addChild(&g1);
g2.addChild(&shadow);
g2.addChild(&testnode1);
g2.addChild(&testnode2);
g2.addChild(&border);
scene.root_.addChild(&g2);
// init output FBO

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -7,4 +7,4 @@ Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd images/shadow.png
map_Kd shadow.png

View File

@@ -1,13 +1,13 @@
mtllib shadow.mtl
o square_border
v -1.000000 -1.000000 0.000000
v -1.300000 -1.300000 0.000000
v -1.400000 -1.400000 0.000000
v 1.000000 -1.000000 0.000000
v 1.300000 -1.300000 0.000000
v 1.400000 -1.400000 0.000000
v -1.000000 1.000000 0.000000
v -1.300000 1.300000 0.000000
v -1.400000 1.400000 0.000000
v 1.000000 1.000000 0.000000
v 1.300000 1.300000 0.000000
v 1.400000 1.400000 0.000000
vt 0.2 0.80
vt 1.00 1.00
vt -0.00 1.00