Last active
December 1, 2016 20:04
-
-
Save ryosuzuki/682a193a53abf3c8080c20447535b433 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "opengl.h" | |
void OpenGL::initBuffers() { | |
glGenVertexArrays(1, &vaoMesh); | |
glBindVertexArray(vaoMesh); | |
glGenBuffers(1, &vboVertices); | |
glGenBuffers(1, &vboNormals); | |
glGenBuffers(1, &vboUVs); | |
glGenBuffers(1, &vboFaces); | |
glGenBuffers(1, &vboAmbient); | |
glGenBuffers(1, &vboDiffuse); | |
glGenBuffers(1, &vboSpecular); | |
} | |
void OpenGL::freeBuffers() { | |
glDeleteVertexArrays(1, &vaoMesh); | |
glDeleteBuffers(1, &vboVertices); | |
glDeleteBuffers(1, &vboNormals); | |
glDeleteBuffers(1, &vboUVs); | |
glDeleteBuffers(1, &vboFaces); | |
glDeleteBuffers(1, &vboAmbient); | |
glDeleteBuffers(1, &vboDiffuse); | |
glDeleteBuffers(1, &vboSpecular); | |
} | |
void OpenGL::setMesh(const Mesh &mesh) { | |
vertices = (mesh.vertices.transpose()).cast<float>(); | |
normals = (mesh.normals.transpose()).cast<float>(); | |
faces = (mesh.faces.transpose()).cast<unsigned>(); | |
uvs = (mesh.uvs.transpose()).cast<float>(); | |
ambient = (mesh.ambient.transpose()).cast<float>(); | |
diffuse = (mesh.diffuse.transpose()).cast<float>(); | |
specular = (mesh.specular.transpose()).cast<float>(); | |
} | |
void OpenGL::bindMesh() { | |
glBindVertexArray(vaoMesh); | |
shaderMesh.bind(); | |
shaderMesh.bindVertexAttribArray("position", vboVertices, vertices, true); | |
shaderMesh.bindVertexAttribArray("normal", vboNormals, normals, true); | |
shaderMesh.bindVertexAttribArray("Ka", vboAmbient, ambient, true); | |
shaderMesh.bindVertexAttribArray("Kd", vboDiffuse, diffuse, true); | |
shaderMesh.bindVertexAttribArray("Ks", vboSpecular, specular, true); | |
shaderMesh.bindVertexAttribArray("texcoord", vboUVs, uvs, true); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboFaces); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned)*faces.size(), faces.data(), GL_DYNAMIC_DRAW); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, vboTextures); | |
// glUniform1i(shaderMesh.uniform("tex"), 0); | |
} | |
void OpenGL::drawMesh(bool solid) { | |
glPolygonMode(GL_FRONT_AND_BACK, solid ? GL_FILL : GL_LINE); | |
if (solid) { | |
glEnable(GL_POLYGON_OFFSET_FILL); | |
glPolygonOffset(1.0, 1.0); | |
} | |
glDrawElements(GL_TRIANGLES, 3*faces.cols(), GL_UNSIGNED_INT, 0); | |
glDisable(GL_POLYGON_OFFSET_FILL); | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
} | |
void OpenGL::init() { | |
std::string meshVertexShaderString = | |
"#version 150\n" | |
"uniform mat4 model;" | |
"uniform mat4 view;" | |
"uniform mat4 proj;" | |
"in vec3 position;" | |
"in vec3 normal;" | |
"out vec3 position_eye;" | |
"out vec3 normal_eye;" | |
"in vec3 Ka;" | |
"in vec3 Kd;" | |
"in vec3 Ks;" | |
"in vec2 texcoord;" | |
"out vec2 texcoordi;" | |
"out vec3 Kai;" | |
"out vec3 Kdi;" | |
"out vec3 Ksi;" | |
"void main()" | |
"{" | |
" position_eye = vec3 (view * model * vec4 (position, 1.0));" | |
" normal_eye = vec3 (view * model * vec4 (normal, 0.0));" | |
" normal_eye = normalize(normal_eye);" | |
" gl_Position = proj * vec4 (position_eye, 1.0);" //proj * view * model * vec4(position, 1.0);" | |
" Kai = Ka;" | |
" Kdi = Kd;" | |
" Ksi = Ks;" | |
" texcoordi = texcoord;" | |
"}"; | |
std::string meshFragmentShaderString = | |
"#version 150\n" | |
"uniform mat4 model;" | |
"uniform mat4 view;" | |
"uniform mat4 proj;" | |
"uniform vec4 fixed_color;" | |
"in vec3 position_eye;" | |
"in vec3 normal_eye;" | |
"uniform vec3 light_position_world;" | |
"vec3 Ls = vec3 (1, 1, 1);" | |
"vec3 Ld = vec3 (1, 1, 1);" | |
"vec3 La = vec3 (1, 1, 1);" | |
"in vec3 Ksi;" | |
"in vec3 Kdi;" | |
"in vec3 Kai;" | |
"in vec2 texcoordi;" | |
"uniform sampler2D tex;" | |
"uniform float specular_exponent;" | |
"uniform float lighting_factor;" | |
"uniform float texture_factor;" | |
"out vec4 outColor;" | |
"void main()" | |
"{" | |
"vec3 Ia = La * Kai;" // ambient intensity | |
"vec3 light_position_eye = vec3 (view * vec4 (light_position_world, 1.0));" | |
"vec3 vector_to_light_eye = light_position_eye - position_eye;" | |
"vec3 direction_to_light_eye = normalize (vector_to_light_eye);" | |
"float dot_prod = dot (direction_to_light_eye, normal_eye);" | |
"float clamped_dot_prod = max (dot_prod, 0.0);" | |
"vec3 Id = Ld * Kdi * clamped_dot_prod;" // Diffuse intensity | |
"vec3 reflection_eye = reflect (-direction_to_light_eye, normal_eye);" | |
"vec3 surface_to_viewer_eye = normalize (-position_eye);" | |
"float dot_prod_specular = dot (reflection_eye, surface_to_viewer_eye);" | |
"dot_prod_specular = float(abs(dot_prod)==dot_prod) * max (dot_prod_specular, 0.0);" | |
"float specular_factor = pow (dot_prod_specular, specular_exponent);" | |
"vec3 Is = Ls * Ksi * specular_factor;" // specular intensity | |
"vec4 color = vec4(lighting_factor * (Is + Id) + Ia, 1.0) + vec4((1.0-lighting_factor) * Kdi,1.0);" | |
"outColor = mix(vec4(1,1,1,1), texture(tex, texcoordi), texture_factor) * color;" | |
"if (fixed_color != vec4(0.0)) outColor = fixed_color;" | |
"}"; | |
initBuffers(); | |
shaderMesh.init(meshVertexShaderString, meshFragmentShaderString, "outColor"); | |
} | |
void OpenGL::free() { | |
shaderMesh.free(); | |
freeBuffers(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <iostream> | |
#include <Eigen/Core> | |
#include <Eigen/Geometry> | |
#include "mesh.h" | |
#include "shader.h" | |
class OpenGL { | |
public: | |
Shader shaderMesh; | |
GLuint vaoMesh; | |
GLuint vboVertices; | |
GLuint vboNormals; | |
GLuint vboUvs; | |
GLuint vboAmbient; | |
GLuint vboDiffuse; | |
GLuint vboSpecular; | |
GLuint vboFaces; | |
Eigen::MatrixXf vertices; | |
Eigen::MatrixXf normals; | |
Eigen::MatrixXf ambient; | |
Eigen::MatrixXf diffuse; | |
Eigen::MatrixXf specular; | |
Eigen::MatrixXf uvs; | |
Eigen::MatrixXi faces; | |
void init(); | |
void initBuffers(); | |
void setMesh(const Mesh &mesh); | |
void bindMesh(); | |
void drawMesh(bool solid = true); | |
void free(); | |
void freeBuffers(); | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "shader.h" | |
bool Shader::init(const std::string &vertexShaderString, | |
const std::string &fragmentShaderString, | |
const std::string &fragmentDataName, | |
const std::string &geometryShaderString, | |
int geometryShaderMaxVertices) | |
{ | |
using namespace std; | |
vertexShader = createShaderHelper(GL_VERTEX_SHADER, vertexShaderString); | |
geometryShader = createShaderHelper(GL_GEOMETRY_SHADER, geometryShaderString); | |
fragmentShader = createShaderHelper(GL_FRAGMENT_SHADER, fragmentShaderString); | |
if (!vertexShader || !fragmentShader) { | |
return false; | |
} | |
programShader = glCreateProgram(); | |
glAttachShader(programShader, vertexShader); | |
glAttachShader(programShader, fragmentShader); | |
if (geometryShader) { | |
glAttachShader(programShader, geometryShader); | |
/* This covers only basic cases and may need to be modified */ | |
glProgramParameteri(programShader, GL_GEOMETRY_INPUT_TYPE, GL_TRIANGLES); | |
glProgramParameteri(programShader, GL_GEOMETRY_OUTPUT_TYPE, GL_TRIANGLES); | |
glProgramParameteri(programShader, GL_GEOMETRY_VERTICES_OUT, geometryShaderMaxVertices); | |
} | |
glBindFragDataLocation(programShader, 0, fragmentDataName.c_str()); | |
glLinkProgram(programShader); | |
GLint status; | |
glGetProgramiv(programShader, GL_LINK_STATUS, &status); | |
if (status != GL_TRUE) { | |
char buffer[512]; | |
glGetProgramInfoLog(programShader, 512, NULL, buffer); | |
std::cerr << "Linker error: " << std::endl << buffer << std::endl; | |
programShader = 0; | |
return false; | |
} | |
return true; | |
} | |
void Shader::bind() { | |
glUseProgram(programShader); | |
} | |
GLint Shader::attrib(const std::string &name) const { | |
return glGetAttribLocation(programShader, name.c_str()); | |
} | |
GLint Shader::uniform(const std::string &name) const { | |
return glGetUniformLocation(programShader, name.c_str()); | |
} | |
GLint Shader::bindVertexAttribArray(const std::string &name, GLuint bufferID, const Eigen::MatrixXf &M, bool refresh) const { | |
GLint id = attrib(name); | |
if (id < 0) { | |
return id; | |
} | |
if (M.size() == 0) { | |
glDisableVertexAttribArray(id); | |
return id; | |
} | |
glBindBuffer(GL_ARRAY_BUFFER, bufferID); | |
if (refresh) { | |
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*M.size(), M.data(), GL_DYNAMIC_DRAW); | |
} | |
glVertexAttribPointer(id, M.rows(), GL_FLOAT, GL_FALSE, 0, 0); | |
glEnableVertexAttribArray(id); | |
return id; | |
} | |
void Shader::free() { | |
if (programShader) { | |
glDeleteProgram(programShader); | |
programShader = 0; | |
} | |
if (vertexShader) { | |
glDeleteShader(vertexShader); | |
vertexShader = 0; | |
} | |
if (fragmentShader) { | |
glDeleteShader(fragmentShader); | |
fragmentShader = 0; | |
} | |
if (geometryShader) { | |
glDeleteShader(geometryShader); | |
geometryShader = 0; | |
} | |
} | |
GLuint Shader::createShaderHelper(GLint type, const std::string &shaderString) { | |
using namespace std; | |
if (shaderString.empty()) { | |
return (GLuint) 0; | |
} | |
GLuint id = glCreateShader(type); | |
const char *shaderStringConst = shaderString.c_str(); | |
glShaderSource(id, 1, &shaderStringConst, NULL); | |
glCompileShader(id); | |
GLint status; | |
glGetShaderiv(id, GL_COMPILE_STATUS, &status); | |
if (status != GL_TRUE) { | |
char buffer[512]; | |
if (type == GL_VERTEX_SHADER) | |
std::cerr << "Vertex shader:" << std::endl; | |
else if (type == GL_FRAGMENT_SHADER) | |
std::cerr << "Fragment shader:" << std::endl; | |
else if (type == GL_GEOMETRY_SHADER) | |
std::cerr << "Geometry shader:" << std::endl; | |
std::cerr << shaderString <<std::endl << std::endl; | |
glGetShaderInfoLog(id, 512, NULL, buffer); | |
std::cerr << "Error: " << std::endl << buffer << std::endl; | |
return (GLuint) 0; | |
} | |
return id; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Eigen/Core> | |
#include <iostream> | |
#include <fstream> | |
#include <nanogui/glutil.h> | |
class Shader { | |
public: | |
GLuint vertexShader; | |
GLuint fragmentShader; | |
GLuint geometryShader; | |
GLuint programShader; | |
bool init(const std::string &vertexShaderString, | |
const std::string &fragmentShaderString, | |
const std::string &fragmentDataName, | |
const std::string &geometryShaderString = "", | |
int geometryShaderMaxVertices = 3); | |
void bind(); | |
void free(); | |
GLint attrib(const std::string &name) const; | |
GLint uniform(const std::string &name) const; | |
GLint bindVertexAttribArray(const std::string &name, GLuint bufferID, const Eigen::MatrixXf &M, bool refresh) const; | |
GLuint createShaderHelper(GLint type, const std::string &shaderString); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment