Implementation of Mesh Primitive Node to draw geometries (replace OBJ).

This commit is contained in:
brunoherbelin
2020-04-12 23:10:29 +02:00
parent bf953b328a
commit df6e2bbe63
18 changed files with 555 additions and 199 deletions

View File

@@ -164,9 +164,9 @@ message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolki
#
# OBJ LOADER
#
set(OBJLOADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/obj)
add_library(OBJLOADER "${CMAKE_CURRENT_SOURCE_DIR}/ext/obj/ObjLoader.cpp")
message(STATUS "Compiling 'ObjLoader' from https://github.com/mortennobel/OpenGL_3_2_Utils -- ${OBJLOADER_INCLUDE_DIR}.")
#set(OBJLOADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/obj)
#add_library(OBJLOADER "${CMAKE_CURRENT_SOURCE_DIR}/ext/obj/ObjLoader.cpp")
#message(STATUS "Compiling 'ObjLoader' from https://github.com/mortennobel/OpenGL_3_2_Utils -- ${OBJLOADER_INCLUDE_DIR}.")
# find_package(PkgConfig REQUIRED)
# pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
@@ -206,6 +206,7 @@ set(VMIX_SRCS
ImageShader.cpp
Scene.cpp
Primitives.cpp
Mesh.cpp
SessionVisitor.cpp
Settings.cpp
Screenshot.cpp
@@ -219,7 +220,6 @@ set(VMIX_SRCS
ImGuiVisitor.cpp
GstToolkit.cpp
tinyxml2Toolkit.cpp
ColladaToolkit.cpp
)
set(VMIX_RSC_FILES
@@ -237,12 +237,11 @@ set(VMIX_RSC_FILES
./rsc/images/busy.png
./rsc/images/icons.dds
./rsc/images/seed_512.jpg
./rsc/models/shadow.png
./rsc/models/square_border.obj
./rsc/models/shadow.mtl
./rsc/models/disk.png
./rsc/models/disk.obj
./rsc/models/disk.mtl
./rsc/images/transparencygrid.png
./rsc/mesh/point.ply
./rsc/mesh/disk.ply
./rsc/mesh/shadow.ply
./rsc/mesh/shadow.png
)
add_executable(${VMIX_BINARY}
@@ -276,7 +275,6 @@ target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
${NFD_LIBRARY}
${PNG_LIBRARY}
${THREAD_LIBRARY}
OBJLOADER
TINYXML2
TINYFD
IMGUI

View File

@@ -80,10 +80,6 @@ void ImGuiVisitor::visit(Primitive &n)
ImGui::PushID(n.id());
ImGui::Text("Primitive");
// test compute coordinate
glm::vec3 center(0.f);
n.getShader()->accept(*this);
ImGui::PopID();
@@ -109,7 +105,11 @@ void ImGuiVisitor::visit(MediaPlayer &n)
void ImGuiVisitor::visit(Shader &n)
{
ImGui::PushID(n.id());
ImGui::ColorEdit3("color", glm::value_ptr(n.color) ) ;
ImGui::PopID();
}
void ImGuiVisitor::visit(ImageShader &n)
@@ -131,9 +131,9 @@ void ImGuiVisitor::visit(LineCircle &n)
ImGui::Text("Circle");
}
void ImGuiVisitor::visit(ObjModel &n)
void ImGuiVisitor::visit(Mesh &n)
{
ImGui::Text("ObjModel");
ImGui::Text("Mesh");
}
void ImGuiVisitor::visit(Scene &n)

View File

@@ -19,7 +19,7 @@ public:
void visit(LineStrip& n) override;
void visit(LineSquare& n) override;
void visit(LineCircle& n) override;
void visit(ObjModel& n) override;
void visit(Mesh& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;

375
Mesh.cpp Normal file
View File

@@ -0,0 +1,375 @@
#include <iostream>
#include <sstream>
#include <istream>
#include <iterator>
#include <vector>
#include <map>
#include <utility>
#include <glad/glad.h>
#include "Resource.h"
#include "ImageShader.h"
#include "Visitor.h"
#include "Log.h"
#include "Mesh.h"
using namespace std;
using namespace glm;
typedef std::vector< std::pair< std::string, int> > plyElement;
typedef struct prop {
std::string name;
bool is_float;
bool is_list;
prop(std::string n, bool t, bool l = false){
name = n;
is_float = t;
is_list = l;
}
} plyProperty;
typedef std::map<std::string, std::vector<plyProperty> > plyElementProperties;
//float parseValue()
template <typename T>
T parseValue(std::istream& istream) {
T v;
char space = ' ';
istream >> v;
if (!istream.eof()) {
istream >> space >> std::ws;
}
return v;
}
/**
* @brief parsePLY
*
* Loosely inspired from libply
* https://web.archive.org/web/20151202190005/http://people.cs.kuleuven.be/~ares.lagae/libply/
*
* @param ascii content of an ascii PLY file
* @param outPositions vertices
* @param outColors colors
* @param outUV texture coordinates
* @param outIndices indices of faces
* @param outPrimitive type of faces (triangles, etc.)
* @return true on success read
*/
bool parsePLY(string ascii,
vector<vec3> &outPositions,
vector<vec4> &outColors,
vector<vec2> &outUV,
vector<uint> &outIndices,
uint &outPrimitive)
{
stringstream istream(ascii);
std::string line;
std::size_t line_number_ = 0;
// magic
char magic[3];
istream.read(magic, 3);
istream.ignore(1);
++line_number_;
if (!istream) {
Log::Warning("Parse error line %d: not ASCII?", line_number_);
return false;
}
if ((magic[0] != 'p') || (magic[1] != 'l') || (magic[2] != 'y')){
Log::Warning("Parse error line %d: not PLY format", line_number_);
return false;
}
plyElement elements;
plyElementProperties elementsProperties;
std::string current_element = "";
// parse header
while (std::getline(istream, line)) {
++line_number_;
std::istringstream stringstream(line);
stringstream.unsetf(std::ios_base::skipws);
stringstream >> std::ws;
if (stringstream.eof()) {
Log::Warning("Ignoring line %d: '%s'", line_number_, line.c_str());
}
else {
std::string keyword;
stringstream >> keyword;
// format
if (keyword == "format") {
std::string format_string, version;
char space_format_format_string, space_format_string_version;
stringstream >> space_format_format_string >> std::ws >> format_string >> space_format_string_version >> std::ws >> version >> std::ws;
if (!stringstream || !stringstream.eof() ||
!std::isspace(space_format_format_string) ||
!std::isspace(space_format_string_version)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
if (format_string != "ascii") {
Log::Warning("Not PLY file format %s", format_string.c_str());
}
if (version != "1.0") {
Log::Warning("Unsupported PLY version %s", version.c_str());
return false;
}
}
// element
else if (keyword == "element") {
std::string name;
std::size_t count;
char space_element_name, space_name_count;
stringstream >> space_element_name >> std::ws >> name >> space_name_count >> std::ws >> count >> std::ws;
if (!stringstream || !stringstream.eof() ||
!std::isspace(space_element_name) ||
!std::isspace(space_name_count)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
current_element = name;
elements.push_back( pair<string, int>{current_element, count} );
}
// property
else if (keyword == "property") {
std::string type_or_list;
char space_property_type_or_list;
stringstream >> space_property_type_or_list >> std::ws >> type_or_list;
if (!stringstream || !std::isspace(space_property_type_or_list)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
// NOT A LIST property : i.e. a type & a name (e.g. 'property float x' )
if (type_or_list != "list") {
std::string name;
std::string& type = type_or_list;
char space_type_name;
stringstream >> space_type_name >> std::ws >> name >> std::ws;
if (!stringstream || !std::isspace(space_type_name)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
bool float_value = ( type == "float" ) | ( type == "double" );
elementsProperties[current_element].push_back(plyProperty(name, float_value));
}
// list property : several types & a name (e.g. 'property list uchar uint vertex_indices')
else {
std::string name;
std::string size_type_string, scalar_type_string;
char space_list_size_type, space_size_type_scalar_type, space_scalar_type_name;
stringstream >> space_list_size_type >> std::ws >> size_type_string >> space_size_type_scalar_type >> std::ws >> scalar_type_string >> space_scalar_type_name >> std::ws >> name >> std::ws;
if (!stringstream || !std::isspace(space_list_size_type) ||
!std::isspace(space_size_type_scalar_type) ||
!std::isspace(space_scalar_type_name)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
elementsProperties[current_element].push_back(plyProperty(name, false, true));
}
}
// end_header
else if (keyword == "end_header") {
break;
}
}
} // end while readline header
uint num_vertex_per_face = 0;
// loop over elements
for (int i=0; i< elements.size(); ++i)
{
std::string elem = elements[i].first;
int num_data = elements[i].second;
// loop over lines of properties of the element
for (int n = 0; n < num_data; ++n )
{
if (!std::getline(istream, line)) {
Log::Warning("Parse error line %d: '%s'", line_number_, line.c_str());
return false;
}
++line_number_;
std::istringstream stringstream(line);
stringstream.unsetf(std::ios_base::skipws);
stringstream >> std::ws;
vec3 point = vec3(0.f, 0.f, 0.f);
vec4 color = vec4(1.f, 1.f, 1.f, 1.f);
vec2 uv = vec2(0.f, 0.f);
bool has_point = false;
bool has_uv = false;
// read each property of the element
for (int j = 0; j < elementsProperties[elem].size(); ++j)
{
plyProperty prop = elementsProperties[elem][j];
// a numerical property
if ( ! prop.is_list ) {
float value;
switch ( prop.name[0] ) {
case 'x':
point.x = parseValue<float>(stringstream);
has_point = true;
break;
case 'y':
point.y = parseValue<float>(stringstream);
has_point = true;
break;
case 'z':
point.z = parseValue<float>(stringstream);
has_point = true;
break;
case 's':
uv.x = parseValue<float>(stringstream);
has_uv = true;
break;
case 't':
uv.y = parseValue<float>(stringstream);
has_uv = true;
break;
case 'r':
color.r = (float) parseValue<int>(stringstream) / 255.f;
break;
case 'g':
color.g = (float) parseValue<int>(stringstream) / 255.f;
break;
case 'b':
color.b = (float) parseValue<int>(stringstream) / 255.f;
break;
case 'a':
color.a = (float) parseValue<int>(stringstream) / 255.f;
break;
default:
// ignore normals or other types
value = parseValue<float>(stringstream);
break;
}
}
// a list property
else {
// how many values in the list of index ?
uint num_index = parseValue<int>(stringstream);
// check that the number of vertex per face is consistent
if (num_vertex_per_face == 0)
num_vertex_per_face = num_index;
else {
if (num_vertex_per_face != num_index) {
Log::Warning("Variable number of vertices per face not supported");
return false;
}
}
// safely append those indices
for (uint k = 0; k < num_vertex_per_face; ++k ){
uint index = parseValue<int>(stringstream);
outIndices.push_back( index );
}
}
}
// ok, we filled some values
if (has_point) {
outPositions.push_back(point);
outColors.push_back(color);
if (has_uv)
outUV.push_back(uv);
}
}
}
switch (num_vertex_per_face) {
case 1:
outPrimitive = GL_POINTS;
break;
case 2:
outPrimitive = GL_LINES;
break;
case 3:
outPrimitive = GL_TRIANGLES;
break;
case 4:
outPrimitive = GL_QUADS;
break;
default:
Log::Warning("Invalid number of vertices per face. Please triangulate your mesh.");
return false;
break;
}
return true;
}
Mesh::Mesh(const std::string& path, const std::string& texture) : Primitive(), resource_(path), texturefilename_(texture), textureindex_(0)
{
if ( !parsePLY( Resource::getText(resource_), points_, colors_, texCoords_, indices_, drawMode_) )
{
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
Log::Warning("Mesh could not be created from %s", path.c_str());
}
}
Mesh::~Mesh()
{
}
void Mesh::init()
{
Primitive::init();
if (!texturefilename_.empty())
{
// create shader for textured image
textureindex_ = Resource::getTextureImage(texturefilename_);
shader_ = new ImageShader();
}
else {
shader_ = new Shader();
}
}
void Mesh::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 Mesh::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}

36
Mesh.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef MESH_H
#define MESH_H
#include <string>
#include <glm/glm.hpp>
#include "Scene.h"
/**
* @brief The Mesh class creates a Primitive node from a PLY File
*
* PLY - Polygon File Format
* Also known as the Stanford Triangle Format
* http://paulbourke.net/dataformats/ply/
*/
class Mesh : public Primitive {
public:
Mesh(const std::string& path, const std::string& texture = "");
~Mesh();
void init () override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
inline std::string getResource() const { return resource_; }
inline std::string getTexture() const { return texturefilename_; }
protected:
std::string resource_;
std::string texturefilename_;
uint textureindex_;
};
#endif // MESH_H

View File

@@ -4,7 +4,6 @@
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
#include "ObjLoader.h"
#include <glad/glad.h>
@@ -20,18 +19,17 @@
#include <glm/gtx/rotate_vector.hpp>
static const std::vector<glm::vec3> square_points { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, 1.f, 0.f ), glm::vec3( 1.f, -1.f, 0.f ),
glm::vec3( -1.f, -1.f, 0.f )};
static uint square_vao = 0;
static uint circle_vao = 0;
static const std::vector<glm::vec3> square_points {
glm::vec3( -0.99f, -1.f, 0.f ), glm::vec3( -1.f, -0.99f, 0.f ),
glm::vec3( -1.f, 0.99f, 0.f ), glm::vec3( -0.99f, 1.f, 0.f ),
glm::vec3( 0.99f, 1.f, 0.f ), glm::vec3( 1.f, 0.99f, 0.f ),
glm::vec3( 1.f, -0.99f, 0.f ), glm::vec3( 0.99f, -1.f, 0.f ),
glm::vec3( -0.99f, -1.f, 0.f )
};
ImageSurface::ImageSurface(const std::string& path) : Primitive(), textureindex_(0)
ImageSurface::ImageSurface(const std::string& path) : Primitive(), resource_(path), textureindex_(0)
{
// for image texture
resource_ = path;
// geometry
points_ = std::vector<glm::vec3> { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) };
@@ -40,7 +38,7 @@ ImageSurface::ImageSurface(const std::string& path) : Primitive(), textureindex_
texCoords_ = std::vector<glm::vec2> { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ),
glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) };
indices_ = std::vector<uint> { 0, 1, 2, 3 };
drawingPrimitive_ = GL_TRIANGLE_STRIP;
drawMode_ = GL_TRIANGLE_STRIP;
}
@@ -54,22 +52,26 @@ void ImageSurface::init()
textureindex_ = Resource::getTextureImage(resource_, &ar);
scale_.x = ar;
}
// create shader for textured image
// a new shader for a new image
shader_ = new ImageShader();
// use static global vertex array object
if (square_vao) {
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// 2. use the global vertex array object
vao_ = square_vao;
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
}
else {
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vertex array object
square_vao = vao_;
// 3. square_vao_ will NOT be deleted because ImageSurface::deleteGLBuffers_() is empty
unique_vao_ = vao_;
unique_drawCount = drawCount_;
// 3. unique_vao_ will NOT be deleted because ImageSurface::deleteGLBuffers_() is empty
}
}
@@ -160,7 +162,7 @@ Points::Points(std::vector<glm::vec3> points, glm::vec4 color, uint pointsize) :
indices_.push_back ( i );
}
drawingPrimitive_ = GL_POINTS;
drawMode_ = GL_POINTS;
pointsize_ = pointsize;
}
@@ -186,7 +188,7 @@ void Points::accept(Visitor& v)
v.visit(*this);
}
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec4 color, uint linewidth) : Primitive()
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec4 color, uint linewidth) : Primitive(), linewidth_(linewidth)
{
for(size_t i = 0; i < points.size(); ++i)
{
@@ -195,8 +197,7 @@ LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec4 color, uint linewi
indices_.push_back ( i );
}
drawingPrimitive_ = GL_LINE_STRIP;
linewidth_ = linewidth;
drawMode_ = GL_LINE_STRIP;
}
void LineStrip::init()
@@ -226,6 +227,38 @@ LineSquare::LineSquare(glm::vec4 color, uint linewidth) : LineStrip(square_point
{
}
void LineSquare::init()
{
// a new shader for a new line
shader_ = new Shader();
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// 2. use the global vertex array object
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
}
else {
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vertex array object
unique_vao_ = vao_;
unique_drawCount = drawCount_;
// 3. unique_vao_ will NOT be deleted because LineCircle::deleteGLBuffers_() is empty
}
}
void LineSquare::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector<glm::vec3>(), color, linewidth)
{
static int N = 72;
@@ -246,21 +279,27 @@ LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector<
void LineCircle::init()
{
// use static global vertex array object
if (circle_vao) {
// a new shader for a new line
shader_ = new Shader();
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// if set, use the global vertex array object
vao_ = square_vao;
// 2. use the global vertex array object
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
}
else {
// 1. init as usual (only once)
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vao
circle_vao = vao_;
// 3. vao_ will not be deleted because deleteGLBuffers_() is empty
// 2. remember global vertex array object
unique_vao_ = vao_;
unique_drawCount = drawCount_;
// 3. unique_vao_ will NOT be deleted because LineCircle::deleteGLBuffers_() is empty
}
shader_ = new Shader();
}
void LineCircle::accept(Visitor& v)
@@ -269,72 +308,3 @@ void LineCircle::accept(Visitor& v)
v.visit(*this);
}
ObjModel::ObjModel(const std::string& path) : Primitive(), textureindex_(0)
{
// for obj model
resource_ = path;
// load geometry
std::vector<glm::vec3> normals; // ignored
std::string material_filename;
bool okay = loadObject( Resource::getText(resource_), points_,
normals, texCoords_, indices_, material_filename );
if ( okay ) {
// prepend path to the name of other files
std::string rsc_path = resource_.substr(0, resource_.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( glm::vec4( material_->diffuse, 1.0) );
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

@@ -99,8 +99,13 @@ public:
class LineSquare : public LineStrip {
void deleteGLBuffers_() override {}
public:
LineSquare(glm::vec4 color, uint linewidth = 1);
void init() override;
void accept(Visitor& v) override;
};
class LineCircle : public LineStrip {
@@ -115,22 +120,5 @@ public:
};
class ObjModel : public Primitive {
public:
ObjModel(const std::string& path = "" );
void init () override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
inline std::string getResource() const { return resource_; }
protected:
std::string resource_;
std::string texture_filename_;
uint textureindex_;
};
#endif // PRIMITIVES_H

View File

@@ -63,10 +63,10 @@ Primitive::~Primitive()
{
deleteGLBuffers_();
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
// points_.clear();
// colors_.clear();
// texCoords_.clear();
// indices_.clear();
}
@@ -115,9 +115,16 @@ void Primitive::init()
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// drawing indications
drawCount_ = indices_.size();
// delete temporary buffers
if ( arrayBuffer_ ) glDeleteBuffers ( 1, &arrayBuffer_);
if ( elementBuffer_ ) glDeleteBuffers ( 1, &elementBuffer_);
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
Node::init();
}
@@ -139,10 +146,12 @@ void Primitive::draw(glm::mat4 modelview, glm::mat4 projection)
//
// draw vertex array object
//
if (drawMode_) {
glBindVertexArray( vao_ );
glDrawElements( drawingPrimitive_, indices_.size(), GL_UNSIGNED_INT, 0 );
glDrawElements( drawMode_, drawCount_, GL_UNSIGNED_INT, 0 );
glBindVertexArray(0);
}
}
}
void Primitive::accept(Visitor& v)

View File

@@ -55,7 +55,7 @@ public:
class Primitive : public Node {
public:
Primitive() : Node(), shader_(nullptr), vao_(0), drawingPrimitive_(0) {}
Primitive() : Node(), shader_(nullptr), vao_(0), drawMode_(0), drawCount_(0) {}
virtual ~Primitive();
virtual void init () override;
@@ -67,8 +67,7 @@ public:
protected:
Shader* shader_;
uint vao_;
uint drawingPrimitive_;
uint vao_, drawMode_, drawCount_;
std::vector<glm::vec3> points_;
std::vector<glm::vec4> colors_;
std::vector<glm::vec2> texCoords_;

View File

@@ -3,6 +3,7 @@
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "Mesh.h"
#include "ImageShader.h"
#include "MediaPlayer.h"
#include "GstToolkit.h"
@@ -166,15 +167,20 @@ void SessionVisitor::visit(LineCircle &n)
xmlCurrent_->InsertEndChild(color);
}
void SessionVisitor::visit(ObjModel &n)
void SessionVisitor::visit(Mesh &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "ObjModel");
xmlCurrent_->SetAttribute("type", "Mesh");
XMLText *filename = xmlDoc_->NewText( n.getResource().c_str() );
XMLElement *obj = xmlDoc_->NewElement("resource");
obj->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(obj);
filename = xmlDoc_->NewText( n.getTexture().c_str() );
XMLElement *tex = xmlDoc_->NewElement("texture");
tex->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(tex);
}
void SessionVisitor::visit(Scene &n)

View File

@@ -26,7 +26,7 @@ public:
void visit(LineStrip& n) override;
void visit(LineSquare&) override;
void visit(LineCircle& n) override;
void visit(ObjModel& n) override;
void visit(Mesh& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;

View File

@@ -7,6 +7,8 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <chrono>
#include <ctime>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
@@ -168,6 +170,10 @@ void ShadingProgram::checkLinkingErr()
Shader::Shader() : blending(BLEND_OPACITY)
{
// create unique id
auto duration = std::chrono::system_clock::now().time_since_epoch();
id_ = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 100000000;
program_ = &simpleShadingProgram;
reset();
}

View File

@@ -37,10 +37,15 @@ private:
class Shader
{
int id_;
public:
Shader();
virtual ~Shader() {}
// unique identifyer generated at instanciation
inline int id () const { return id_; }
virtual void use();
virtual void reset();
virtual void accept(Visitor& v);

View File

@@ -14,7 +14,7 @@ class MediaSurface;
class LineStrip;
class LineSquare;
class LineCircle;
class ObjModel;
class Mesh;
class MediaPlayer;
class Shader;
class ImageShader;
@@ -34,7 +34,7 @@ public:
virtual void visit(LineStrip& n) = 0;
virtual void visit(LineSquare& n) = 0;
virtual void visit(LineCircle& n) = 0;
virtual void visit(ObjModel& n) = 0;
virtual void visit(Mesh& n) = 0;
virtual void visit(MediaPlayer& n) = 0;
virtual void visit(Shader& n) = 0;
virtual void visit(ImageShader& n) = 0;

View File

@@ -36,6 +36,7 @@
#include "MediaPlayer.h"
#include "Scene.h"
#include "Primitives.h"
#include "Mesh.h"
#include "ImGuiVisitor.h"
#include "SessionVisitor.h"
@@ -255,29 +256,32 @@ int main(int, char**)
// init elements to the scene
//testnode3.getShader()->blending = Shader::BLEND_OPACITY;
ObjModel disk("models/disk.obj");
Mesh disk("mesh/disk.ply", "images/transparencygrid.png");
glm::vec4 pink( 0.8f, 0.f, 0.8f, 1.f );
LineCircle circle(pink, 5);
glm::vec4 color( 0.8f, 0.8f, 0.f, 1.f);
LineSquare border(color, 5);
ObjModel shadow("models/square_border.obj");
// ObjModel shadow("models/square_border.obj");
Mesh shadow("mesh/shadow.ply", "mesh/shadow.png");
Group g1;
g1.translation_ = glm::vec3(1.f, 1.f, 0.2f);
g1.scale_ = glm::vec3(1.2f, 1.2f, 1.f);
Group g2;
g2.translation_ = glm::vec3(-1.f, -1.f, 0.4f);
Animation A;
A.speed_ = 0.01f;
A.speed_ = 0.08f;
A.axis_ = glm::vec3(1.f, 1.f, 1.f);
std::vector<glm::vec3> pts = std::vector<glm::vec3> { glm::vec3( 0.f, 0.f, 0.f ) };
Points P(pts, pink);
P.setPointSize(60);
// std::vector<glm::vec3> pts = std::vector<glm::vec3> { glm::vec3( 0.f, 0.f, 0.f ) };
// Points P(pts, pink);
// P.setPointSize(60);
Mesh P("mesh/point.ply");
P.scale_ = glm::vec3(0.05f);
// build tree
scene.root_.addChild(&disk);
@@ -291,10 +295,9 @@ int main(int, char**)
g2.addChild(&shadow);
g2.addChild(&testnode1);
g2.addChild(&border);
scene.root_.addChild(&g2);
// A.addChild(&g2);
A.addChild(&P);
scene.root_.addChild(&A);
// init output FBO

View File

@@ -1,10 +0,0 @@
newmtl Shadow
Ns 323.999994
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd shadow.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1,29 +0,0 @@
mtllib shadow.mtl
o square_border
v -1.000000 -1.000000 0.000000
v -1.400000 -1.400000 0.000000
v 1.000000 -1.000000 0.000000
v 1.400000 -1.400000 0.000000
v -1.000000 1.000000 0.000000
v -1.400000 1.400000 0.000000
v 1.000000 1.000000 0.000000
v 1.400000 1.400000 0.000000
vt 0.2 0.80
vt 1.00 1.00
vt -0.00 1.00
vt 0.80 0.80
vt 1.00 -0.00
vt 0.2 0.2
vt -0.00 -0.00
vt 0.8 0.2
vn 0.0000 0.0000 -1.0000
usemtl Shadow
s off
f 3/1/1 8/2/1 4/3/1
f 7/4/1 6/5/1 8/2/1
f 1/6/1 4/3/1 2/7/1
f 5/8/1 2/7/1 6/5/1
f 3/1/1 7/4/1 8/2/1
f 7/4/1 5/8/1 6/5/1
f 1/6/1 3/1/1 4/3/1
f 5/8/1 1/6/1 2/7/1