Created
March 15, 2013 12:09
-
-
Save timshen91/5169444 to your computer and use it in GitHub Desktop.
OFF(噗...) model viewer based on OpenGL
This file contains 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 <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