Skip to content

Instantly share code, notes, and snippets.

@timshen91
Created March 15, 2013 12:09
Show Gist options
  • Save timshen91/5169444 to your computer and use it in GitHub Desktop.
Save timshen91/5169444 to your computer and use it in GitHub Desktop.
OFF(噗...) model viewer based on OpenGL
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cassert>
#include <cmath>
#include <GL/gl.h>
#include <GL/glut.h>
#define sqr(a) ((a) * (a))
using namespace std;
vector<vector<double>> vertices;
vector<vector<int>> mesh;
GLfloat position[] = {10., 0., 0., 1.};
int width = 640;
int height = 480;
float Rotation = 0;
vector<double> sub(vector<double> a, vector<double> b) {
assert(a.size() == b.size());
vector<double> ret(a.size());
for (unsigned int i = 0; i < a.size(); i++) {
ret[i] = a[i] - b[i];
}
return ret;
}
vector<double> calcNormal3(vector<double> p1, vector<double> p2, vector<double> p3) {
assert(p1.size() == 3 && p2.size() == 3 && p3.size() == 3);
vector<double> u(3);
vector<double> v(3);
u = sub(p2, p1);
v = sub(p3, p2);
vector<double> ret(3);
ret[0] = u[1] * v[2] - u[2] * v[1];
ret[1] = u[2] * v[0] - u[0] * v[2];
ret[2] = u[0] * v[1] - u[1] * v[0];
double m = sqrt(sqr(ret[0]) + sqr(ret[1]) + sqr(ret[2]));
ret[0] /= m;
ret[1] /= m;
ret[2] /= m;
return ret;
}
void model() {
float white[] = {1., 1., 1., 1.};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, white);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, white);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, white);
for (auto poly : mesh){
glBegin(GL_POLYGON); {
auto normal = calcNormal3(vertices[poly[0]], vertices[poly[1]], vertices[poly[2]]);
glNormal3f(normal[0], normal[1], normal[2]);
for (auto vi : poly){
auto v = vertices[vi];
glVertex3f(v[0], v[1], v[2]);
}
} glEnd();
}
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
glPushMatrix(); {
glRotatef(Rotation,0,1,0);
glRotatef(-90,1,0,0);
model();
} glPopMatrix();
Rotation += .1;
glutSwapBuffers();
}
void init(){
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspect = (GLfloat)width / height;
gluPerspective(45., aspect, 1., 500.);
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
GLfloat amb_light[] = { 0.1, 0.1, 0.1, 1.0 };
GLfloat diffuse[] = { 0.6, 0.6, 0.6, 1 };
GLfloat specular[] = { 0.7, 0.7, 0.7, 1 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb_light);
//glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glClearColor(0.0, 0.0, 0.0, 1.0);
}
void readin(const char * filepath){
ifstream fin;
fin.open(filepath);
string s;
getline(fin, s);
int n, m, k;
fin >> n >> m >> k;
vertices.resize(n);
mesh.resize(m);
for (int i = 0; i < n; i++){
double x, y, z;
fin >> x >> y >> z;
vector<double> v = {x, y, z};
vertices[i] = v;
}
for (int i = 0; i < m; i++){
int nn;
fin >> nn;
vector<int> m(nn);
for (int j = 0; j < nn; j++){
fin >> m[j];
}
mesh[i] = m;
}
// skip edge
fin.close();
}
int main(int argc, char * argv[]){
if (argc < 2) {
return 1;
}
readin(argv[1]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("test");
glutDisplayFunc(display);
glutIdleFunc(display);
init();
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment