implement 4.5

This commit is contained in:
hodasemi 2018-06-29 17:49:16 +02:00
parent ae74a5d55d
commit da0b6fcfb4
6 changed files with 11120 additions and 38 deletions

View file

@ -15,6 +15,11 @@ void main(void)
if(skinned) if(skinned)
{ {
/*Task: Implement Skinning */ Mat4 m = bone_weights[0] * bone_matrices[bone_indices[0]] +
bone_weights[1] * bone_matrices[bone_indices[1]] +
bone_weights[2] * bone_matrices[bone_indices[2]] +
bone_weights[3] * bone_matrices[bone_indices[3]];
position = m * position;
} }
} }

View file

@ -9,32 +9,40 @@
#include <sstream> #include <sstream>
#include <queue> #include <queue>
bool Mesh::init_shaders(cgv::render::context &ctx)
bool Mesh::init_shaders(cgv::render::context& ctx)
{ {
cgv::render::shader_code vs, fs, gs; cgv::render::shader_code vs, fs, gs;
if (!vs.read_and_compile(ctx, "glsl/skinning.glvs", cgv::render::ST_VERTEX)) { if (!vs.read_and_compile(ctx, "CGII/glsl/skinning.glvs", cgv::render::ST_VERTEX))
std::cout << "error reading vertex shader\n" << vs.last_error.c_str() << std::endl; {
std::cout << "error reading vertex shader\n"
<< vs.last_error.c_str() << std::endl;
return false; return false;
} }
if (!gs.read_and_compile(ctx, "glsl/skinning.glgs", cgv::render::ST_GEOMETRY)) { if (!gs.read_and_compile(ctx, "CGII/glsl/skinning.glgs", cgv::render::ST_GEOMETRY))
std::cout << "error reading geometry shader\n" << gs.last_error.c_str() << std::endl; {
std::cout << "error reading geometry shader\n"
<< gs.last_error.c_str() << std::endl;
return false; return false;
} }
if (!fs.read_and_compile(ctx, "glsl/skinning.glfs", cgv::render::ST_FRAGMENT)) { if (!fs.read_and_compile(ctx, "CGII/glsl/skinning.glfs", cgv::render::ST_FRAGMENT))
std::cout << "error reading fragment shader\n" << vs.last_error.c_str() << std::endl; {
std::cout << "error reading fragment shader\n"
<< vs.last_error.c_str() << std::endl;
return false; return false;
} }
if (!prog.create(ctx)) { if (!prog.create(ctx))
std::cout << "error creating program\n" << prog.last_error.c_str() << std::endl; {
std::cout << "error creating program\n"
<< prog.last_error.c_str() << std::endl;
return false; return false;
} }
prog.attach_code(ctx, vs); prog.attach_code(ctx, vs);
prog.attach_code(ctx, gs); prog.attach_code(ctx, gs);
prog.attach_code(ctx, fs); prog.attach_code(ctx, fs);
if (!prog.link(ctx)) { if (!prog.link(ctx))
std::cout << "link error\n" << prog.last_error.c_str() << std::endl; {
std::cout << "link error\n"
<< prog.last_error.c_str() << std::endl;
return false; return false;
} }
return true; return true;
@ -77,7 +85,7 @@ Mesh::~Mesh()
delete[] skinning_matrices; delete[] skinning_matrices;
} }
bool Mesh::read_obj(const char* filename) bool Mesh::read_obj(const char *filename)
{ {
std::ifstream f(filename); std::ifstream f(filename);
@ -131,8 +139,6 @@ bool Mesh::read_obj(const char* filename)
return true; return true;
} }
void Mesh::read_attachment(std::string filename) void Mesh::read_attachment(std::string filename)
{ {
std::ifstream f(filename); std::ifstream f(filename);
@ -147,6 +153,50 @@ void Mesh::read_attachment(std::string filename)
while (std::getline(f, line)) while (std::getline(f, line))
{ {
/*Task 4.5: Load attachment */ /*Task 4.5: Load attachment */
std::istringstream iss(line);
struct IndexedValue
{
int index;
float value;
};
std::vector<IndexedValue> values;
float value;
while (iss >> value)
{
IndexedValue iv;
iv.index = values.size();
iv.value = value;
values.emplace_back(iv);
}
std::sort(values.begin(), values.end(), [](IndexedValue &iv1, IndexedValue &iv2) -> bool {
return iv1.value > iv2.value;
});
float sum = 0.0f;
for (int i = 0; i < 4; i++)
{
sum += values[i].value;
}
Vec4 weights;
ivec4 indices;
for (int i = 0; i < 4; i++)
{
values[i].value / sum;
indices[i] = values[i].index;
weights[i] = values[i].value;
}
bone_indices.emplace_back(indices);
bone_weights.emplace_back(weights);
} }
glBindBuffer(GL_ARRAY_BUFFER, boneIndexBuffer); glBindBuffer(GL_ARRAY_BUFFER, boneIndexBuffer);
@ -160,7 +210,7 @@ void Mesh::read_attachment(std::string filename)
has_attachment = true; has_attachment = true;
} }
void Mesh::set_skinning_matrices(const std::vector<Mat4>& matrices) void Mesh::set_skinning_matrices(const std::vector<Mat4> &matrices)
{ {
for (size_t i = 0; i < matrices.size(); ++i) for (size_t i = 0; i < matrices.size(); ++i)
{ {
@ -170,7 +220,7 @@ void Mesh::set_skinning_matrices(const std::vector<Mat4>& matrices)
n_bones = matrices.size(); n_bones = matrices.size();
} }
void Mesh::draw(cgv::render::context& ctx) void Mesh::draw(cgv::render::context &ctx)
{ {
GLfloat mv[16]; GLfloat mv[16];
GLfloat proj[16]; GLfloat proj[16];

View file

@ -11,24 +11,28 @@
#include "SkeletonViewer.h" #include "SkeletonViewer.h"
#include "SkinnedMeshViewer.h" #include "SkinnedMeshViewer.h"
#include "IKViewer.h" #include "IKViewer.h"
#include <fstream>
#include "program.h"
using namespace cgv::base; using namespace cgv::base;
struct Initializer struct Initializer
{ {
DataStore* data; DataStore *data;
Initializer() Initializer()
{ {
data = new DataStore(); data = new DataStore();
/*
Program p;
//p.createProgram("CGII/glsl/skinning.glvs", "CGII/glsl/skinning.glgs", "CGII/glsl/skinning.glfs");
*/
register_object(base_ptr(new SkeletonViewer(data)), ""); register_object(base_ptr(new SkeletonViewer(data)), "");
register_object(base_ptr(new IKViewer(data)), ""); register_object(base_ptr(new IKViewer(data)), "");
register_object(base_ptr(new SkinnedMeshViewer(data)), "");
/*register_object(base_ptr(new SkinnedMeshViewer(data)), "");*/
} }
~Initializer() ~Initializer()

134
CGII/src/program.h Normal file
View file

@ -0,0 +1,134 @@
#ifndef PROGRAM
#define PROGRAM
#include <fstream>
#include <iostream>
#include <string>
#include <GL/gl.h>
class Program
{
public:
Program()
{
}
~Program()
{
glDeleteProgram(m_prog);
}
void createProgram(const char *vs, const char *fs)
{
GLuint vert = createShader(vs, GL_VERTEX_SHADER);
GLuint frag = createShader(fs, GL_FRAGMENT_SHADER);
if ((vert == 0) || (frag == 0))
{
return;
}
m_prog = glCreateProgram();
glAttachShader(m_prog, vert);
glAttachShader(m_prog, frag);
glLinkProgram(m_prog);
glDeleteShader(vert);
glDeleteShader(frag);
}
void createProgram(const char *vs, const char *gs, const char *fs)
{
GLuint vert = createShader(vs, GL_VERTEX_SHADER);
GLuint geom = createShader(gs, GL_GEOMETRY_SHADER);
GLuint frag = createShader(fs, GL_FRAGMENT_SHADER);
if ((vert == 0) || (frag == 0) || (geom == 0))
{
return;
}
m_prog = glCreateProgram();
glAttachShader(m_prog, vert);
glAttachShader(m_prog, geom);
glAttachShader(m_prog, frag);
glLinkProgram(m_prog);
glDeleteShader(vert);
glDeleteShader(geom);
glDeleteShader(frag);
}
void createProgram(const std::string vs, const std::string fs)
{
createProgram(vs.c_str(), fs.c_str());
}
GLuint getProgram()
{
return m_prog;
}
private:
inline std::string loadShaderText(const char *path)
{
std::ifstream is(path);
std::string s_save;
if (is.is_open())
{
s_save.assign(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>());
is.close();
}
else
{
std::cout << "could not open " << path << std::endl;
}
return s_save;
}
inline GLuint createShader(const char *path, GLenum shadertype)
{
std::string s_source = loadShaderText(path);
if (s_source.empty())
{
return 0;
}
const char *c_source = s_source.c_str();
GLuint shader = glCreateShader(shadertype);
glShaderSource(shader, 1, (const char **)&c_source, NULL);
glCompileShader(shader);
GLint shaderCompiled = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shaderCompiled);
if (shaderCompiled != GL_TRUE)
{
GLint log_length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
char *log = new char[log_length + 1];
log[log_length] = '\0';
glGetShaderInfoLog(shader, (GLsizei)log_length, NULL, log);
std::cout << "error compiling shader( " << path << " ): " << std::endl
<< log << std::endl;
delete[] log;
glDeleteShader(shader);
shader = 0;
}
return shader;
}
GLuint m_prog;
};
#endif // PROGRAM

10889
spiderman.obj Normal file

File diff suppressed because it is too large Load diff