CS 455 Lecture 5 – Indexed Geometry and OBJ Models
Agenda
- what ?s
- filled geometry
- GL_TRIANGLES
- reading in an OBJ model
TODO
Before next class:
- Lab: tweak our model renderer to allow the user to toggle between a wireframe and filled display of our model. See glPolygonMode.
- Participation: Next lecture we’re going to build a Matrix class to help us represent our transformations. Before that, work through as much of http://chortle.ccsu.edu/vectorlessons/vectorIndex.html as you can. Write a 1/4 sheet with 3-4 questions or observations.
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
Her skin is perfect
Her smile never stops, but look!
Inside she’s empty