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

@ -1,5 +1,5 @@
// This source code is property of the Computer Graphics and Visualization // This source code is property of the Computer Graphics and Visualization
// chair of the TU Dresden. Do not distribute! // chair of the TU Dresden. Do not distribute!
// Copyright (C) CGV TU Dresden - All Rights Reserved // Copyright (C) CGV TU Dresden - All Rights Reserved
// //
#include "Mesh.h" #include "Mesh.h"
@ -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;
@ -51,7 +59,7 @@ Mesh::Mesh()
glBindVertexArray(vao); glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, boneWeightBuffer); glBindBuffer(GL_ARRAY_BUFFER, boneWeightBuffer);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
@ -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);
@ -121,18 +129,16 @@ bool Mesh::read_obj(const char* filename)
} }
f.close(); f.close();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(cgv::math::fvec<float, 3>), &positions[0], GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(cgv::math::fvec<float, 3>), &positions[0], GL_STATIC_DRAW);
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];
@ -179,7 +229,7 @@ void Mesh::draw(cgv::render::context& ctx)
Mat4 modelview(mv); Mat4 modelview(mv);
Mat4 projm(proj); Mat4 projm(proj);
Mat4 mvp = projm * modelview; Mat4 mvp = projm * modelview;
prog.set_uniform(ctx, "modelviewproj", mvp); prog.set_uniform(ctx, "modelviewproj", mvp);
@ -192,7 +242,7 @@ void Mesh::draw(cgv::render::context& ctx)
if (has_attachment) if (has_attachment)
{ {
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
GLint program; GLint program;
glGetIntegerv(GL_CURRENT_PROGRAM, &program); glGetIntegerv(GL_CURRENT_PROGRAM, &program);
@ -203,7 +253,7 @@ void Mesh::draw(cgv::render::context& ctx)
{ {
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2); glDisableVertexAttribArray(2);
} }
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

View file

@ -1,5 +1,5 @@
// This source code is property of the Computer Graphics and Visualization // This source code is property of the Computer Graphics and Visualization
// chair of the TU Dresden. Do not distribute! // chair of the TU Dresden. Do not distribute!
// Copyright (C) CGV TU Dresden - All Rights Reserved // Copyright (C) CGV TU Dresden - All Rights Reserved
// //
// The main file of the plugin. It defines a global register variable // The main file of the plugin. It defines a global register variable
@ -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