teaching machines

CS 455 Lecture 5 – Indexed Geometry and OBJ Models

February 10, 2015 by . Filed under cs455, lectures, spring 2015.

Agenda

TODO

Before next class:

Code

CMakeLists.txt

add_definitions(-DSHADERS_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_executable(third third.cpp ${COMMON})
target_link_libraries(third ${GLUT_LIBRARIES} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})

if(WIN32)
  add_custom_command(
      TARGET third POST_BUILD
      COMMAND ${CMAKE_COMMAND} -E copy_if_different
      "${GLUT_DLL}"
      $<TARGET_FILE_DIR:third>)
    
  add_custom_command(
      TARGET third POST_BUILD
      COMMAND ${CMAKE_COMMAND} -E copy_if_different
      "${GLEW_DLL}"
      $<TARGET_FILE_DIR:third>)
endif(WIN32)

v.glsl

#version 120

attribute vec3 position;

uniform float theta;

void main() {
  gl_Position = vec4(position.x * cos(theta) - position.z * sin(theta),
                     position.y,
                     position.x * sin(theta) + position.z * cos(theta), 1.0);
}

// third

f.glsl

#version 120

void main() {
  gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0);
}

third.cpp

#include <iostream>
#include <fstream>

#include "BaseRenderer.h"
#include "glut_utilities.h"
#include "VertexArray.h"

using namespace td;

/* ------------------------------------------------------------------------- */

void read(const std::string& path,
          int &npositions,
          float *&positions,
          int &nfaces,
          int *&faces) {
  std::ifstream in(path.c_str()); 
 
  std::string line;
  std::string token; 

  npositions = 0;
  nfaces = 0;

  while (in >> token) {
    if (token == "v") {
      ++npositions;
    } else if (token == "f") {
      ++nfaces;
    }
    getline(in, line);
  }

  std::cout << "npositions: " << npositions << std::endl;
  std::cout << "nfaces: " << nfaces << std::endl;

  positions = new float[npositions * 3];
  faces = new int[nfaces * 3];

  in.clear();
  in.seekg(0, std::ios_base::beg);

  float *position = positions;
  int *face = faces;
  while (in >> token) {
    if (token == "v") {
      in >> position[0] >> position[1] >> position[2]; 
      position += 3;
    } else if (token == "f") {
      in >> face[0] >> face[1] >> face[2]; 
      face[0] -= 1;
      face[1] -= 1;
      face[2] -= 1;
      face += 3;
    }
    getline(in, line);
  }

  in.close();
}

/* ------------------------------------------------------------------------- */

class ThirdRenderer : public BaseRenderer {
  public:
    void OnDraw(float delta);
    void OnInitialize();
    void OnKey(Keys::key_t key);
    void OnLeftMouseDown(int x, int y);
    void OnLeftMouseDragged(int x, int y);

  private:
    VertexAttributes *plane_attributes;
    ShaderProgram *shader_program;
    VertexArray *plane;
    float point_size;
    int mouse_x;
    int mouse_y;
    float theta;
};

/* ------------------------------------------------------------------------- */

void ThirdRenderer::OnLeftMouseDown(int x, int y) {
  mouse_x = x;
  mouse_y = y; 
}

/* ------------------------------------------------------------------------- */

void ThirdRenderer::OnLeftMouseDragged(int x, int y) {
  theta += (x - mouse_x) * 0.2f;
  mouse_x = x;
  mouse_y = y;
}

/* ------------------------------------------------------------------------- */

void ThirdRenderer::OnDraw(float delta) {
  BaseRenderer::OnDraw(delta);

  shader_program->Bind();  
  shader_program->SetUniform("theta", theta * 3.14159f / 180.0f);
  plane->Bind();
  plane->DrawIndexed(GL_TRIANGLES);
  plane->Unbind();
  shader_program->Unbind();
}

/* ------------------------------------------------------------------------- */

void ThirdRenderer::OnInitialize() {
  SetBackgroundColor(175.0f / 255, 238.0f / 255, 238.0f / 255, 1.0f);   

  point_size = 1.0f;

  int npositions;
  int nfaces;
  int *faces;
  float *positions;
  read(MODELS_DIR "/suzanne.obj", npositions, positions, nfaces, faces);

  /* int npositions = 6; */
  /* float positions[] = { */
    /* 0.0f, 0.0f, 0.0f, */
    /* 1.0f, 0.0f, 0.0f, */
    /* 0.0f, 1.0f, 0.0f, */
    /* 1.0f, 1.0f, 0.0f, */
  /* }; */

  /* int nfaces = 2; */
  /* int faces[] = { */
    /* 0, 1, 3, */
    /* 0, 3, 2 */
  /* }; */

  // Ship positions off to GPU.
  plane_attributes = new VertexAttributes();
  plane_attributes->AddAttribute("position", npositions, 3, positions);
  plane_attributes->AddIndices(nfaces * 3, faces);

  // CPU positions are free to go now.
  delete[] positions;
  delete[] faces;

  shader_program = ShaderProgram::FromFiles(SHADERS_DIR "/v.glsl", SHADERS_DIR "/f.glsl");

  plane = new VertexArray(*shader_program, *plane_attributes);
}

/* ------------------------------------------------------------------------- */

void ThirdRenderer::OnKey(Keys::key_t key) {
  switch (key) {
    case '+':
      point_size += 1.0f;
      glPointSize(point_size);
      break;
    case '-':
      point_size -= 1.0f;
      glPointSize(point_size);
      break;
    case '[':
      theta += 1;
      break;
    case ']':
      theta -= 1;
      break;
    default:
      BaseRenderer::OnKey(key);
      break;  
  }
}

/* ------------------------------------------------------------------------- */

int main(int argc, char **argv) {
  ThirdRenderer *renderer = new ThirdRenderer();
  glut_render(renderer); 
  return 0;
}

/* ------------------------------------------------------------------------- */


// third

Haiku

on surfaces
Her skin is perfect
Her smile never stops, but look!
Inside she’s empty