00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "tango-gl/mesh.h"
00018 #include "tango-gl/shaders.h"
00019
00020 namespace tango_gl {
00021 Mesh::Mesh() {
00022 render_mode_ = GL_TRIANGLES;
00023 }
00024 Mesh::Mesh(GLenum render_mode) {
00025 render_mode_ = render_mode;
00026 }
00027
00028 void Mesh::SetShader() {
00029 DrawableObject::SetShader();
00030
00031 is_lighting_on_ = false;
00032
00033 is_bounding_box_on_ = false;
00034 }
00035
00036 void Mesh::SetShader(bool is_lighting_on) {
00037 if (is_lighting_on) {
00038 shader_program_ =
00039 util::CreateProgram(shaders::GetShadedVertexShader().c_str(),
00040 shaders::GetBasicFragmentShader().c_str());
00041 if (!shader_program_) {
00042 LOGE("Could not create program.");
00043 }
00044 uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
00045 uniform_mv_mat_ = glGetUniformLocation(shader_program_, "mv");
00046 uniform_light_vec_ = glGetUniformLocation(shader_program_, "lightVec");
00047 uniform_color_ = glGetUniformLocation(shader_program_, "color");
00048
00049 attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
00050 attrib_normals_ = glGetAttribLocation(shader_program_, "normal");
00051 is_lighting_on_ = true;
00052
00053 light_direction_ = glm::vec3(-1.0f, -3.0f, -1.0f);
00054 light_direction_ = glm::normalize(light_direction_);
00055 } else {
00056 SetShader();
00057 }
00058 }
00059
00060 void Mesh::SetBoundingBox(){
00061
00062
00063 if(vertices_.size()==0){
00064 LOGE("Please set up vertices first!");
00065 return;
00066 }
00067 is_bounding_box_on_ = true;
00068 bounding_box_ = new BoundingBox(vertices_);
00069 }
00070
00071 void Mesh::SetLightDirection(const glm::vec3& light_direction) {
00072 light_direction_ = light_direction;
00073 }
00074
00075 bool Mesh::IsIntersecting(const Segment& segment) {
00076
00077
00078 if (!is_bounding_box_on_) {
00079 LOGE("Mesh::IsIntersecting, bounding box is not available.");
00080 return false;
00081 }
00082 return bounding_box_->IsIntersecting(segment, GetRotation(),
00083 GetTransformationMatrix());
00084 }
00085
00086 void Mesh::Render(const glm::mat4& projection_mat,
00087 const glm::mat4& view_mat) const {
00088 glUseProgram(shader_program_);
00089 glm::mat4 model_mat = GetTransformationMatrix();
00090 glm::mat4 mv_mat = view_mat * model_mat;
00091 glm::mat4 mvp_mat = projection_mat * mv_mat;
00092 glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
00093 glUniform4f(uniform_color_, red_, green_, blue_, alpha_);
00094
00095 if (is_lighting_on_) {
00096 glUniformMatrix4fv(uniform_mv_mat_, 1, GL_FALSE, glm::value_ptr(mv_mat));
00097
00098 glEnableVertexAttribArray(attrib_normals_);
00099 glVertexAttribPointer(attrib_normals_, 3, GL_FLOAT, GL_FALSE,
00100 3 * sizeof(GLfloat), &normals_[0]);
00101 glm::vec3 light_direction = glm::mat3(view_mat) * light_direction_;
00102 glUniform3fv(uniform_light_vec_, 1, glm::value_ptr(light_direction));
00103 }
00104
00105 glEnableVertexAttribArray(attrib_vertices_);
00106
00107 if (!indices_.empty()) {
00108 glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
00109 3 * sizeof(GLfloat), vertices_.data());
00110 glDrawElements(render_mode_, indices_.size(), GL_UNSIGNED_SHORT,
00111 indices_.data());
00112 } else {
00113 glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
00114 3 * sizeof(GLfloat), &vertices_[0]);
00115 glDrawArrays(render_mode_, 0, vertices_.size() / 3);
00116 }
00117
00118 glDisableVertexAttribArray(attrib_vertices_);
00119 if (is_lighting_on_) {
00120 glDisableVertexAttribArray(attrib_normals_);
00121 }
00122 glUseProgram(0);
00123 }
00124 }