瀏覽代碼

normlization

CHEN Yihui 5 年之前
父節點
當前提交
7b907fb171
共有 1 個文件被更改,包括 51 次插入26 次删除
  1. 51 26
      main.cpp

+ 51 - 26
main.cpp

@@ -6,20 +6,21 @@
 //   as the default projetion.
 
 #include "Angel.h"
+#include <algorithm>
 #include <fstream>
 #include <iostream>
+#include <limits>
 #include <vector>
 
+#define NORM true
+
 typedef Angel::vec4 color4;
 typedef Angel::vec4 point4;
 
 std::vector<point4> points;
 std::vector<color4> colors;
 
-std::vector<point4> vertices;
-std::vector<color4> vertex_colors;
-
-vec4 multq(vec4 a, vec4 b) {
+inline vec4 multq(vec4 a, vec4 b) {
   // extract axes
   vec3 aa = vec3(a[1], a[2], a[3]);
   vec3 bb = vec3(b[1], b[2], b[3]);
@@ -42,6 +43,11 @@ float lastPos[3] = {0.0F, 0.0F, 0.0F};
 int curx, cury;
 int startX, startY;
 
+GLuint vao;
+GLuint buffer;
+GLuint program;
+GLuint vPosition;
+GLuint vColor;
 GLuint rquat_loc;
 GLuint move_loc;
 
@@ -53,30 +59,62 @@ void load_model(const std::string &file_name) {
    only contain triangles
    the triangles' vertices are in vertices
   */
+  std::vector<point4> vertices;
+  std::vector<color4> vertex_colors;
   std::fstream s(file_name, std::fstream::in);
   if (!s.is_open()) {
     std::cerr << "failed to open" << file_name << std::endl;
   } else {
     std::string t;
     float x, y, z;
+    float xmax = std::numeric_limits<float>::min(),
+          ymax = std::numeric_limits<float>::min(),
+          zmax = std::numeric_limits<float>::min();
+    float xmin = std::numeric_limits<float>::max(),
+          ymin = std::numeric_limits<float>::max(),
+          zmin = std::numeric_limits<float>::max();
     int a, b, c;
     int num = 0;
-    while (true) {
-      s >> t >> x >> y >> z;
+    while (s >> t >> x >> y >> z) {
       if (t == "v") {
         num++;
         vertices.emplace_back(x, y, z, 1.0);
+        xmax = std::max(x, xmax);
+        xmin = std::min(x, xmin);
+        ymax = std::max(y, ymax);
+        ymin = std::min(y, ymin);
+        zmax = std::max(z, zmax);
+        zmin = std::min(z, zmin);
       } else {
         vertex_colors.emplace_back(x, y, z, 1.0);
         break;
       }
     }
+    if (xmax > 1.0f || xmin < -1.0f || ymax > 1.0f || ymin < -1.0f ||
+        zmax > 1.0f || zmin < -1.0f || NORM) {
+      float scale = 1.0f / std::max({xmax - xmin, ymax - ymin, zmax - zmin});
+      std::cout << "scale: " << scale << std::endl;
+      float xmid = 0.5f * (xmax + xmin);
+      float ymid = 0.5f * (ymax + ymin);
+      float zmid = 0.5f * (zmax + zmin);
+
+      for (point4 &p : vertices) {
+        p[0] -= xmid;
+        p[0] *= scale;
+        p[1] -= ymid;
+        p[1] *= scale;
+        p[2] -= zmid;
+        p[2] *= scale;
+      }
+    }
     std::cout << "there are " << num << " vertex(ices)" << std::endl;
     for (int i = 1; i < num; ++i) {
       s >> t >> x >> y >> z;
       vertex_colors.emplace_back(x, y, z, 1.0);
     }
     num = 0;
+    points.clear();
+    colors.clear();
     while (s >> t >> a >> b >> c) {
       points.push_back(vertices[a - 1]);
       points.push_back(vertices[b - 1]);
@@ -86,19 +124,17 @@ void load_model(const std::string &file_name) {
       colors.push_back(vertex_colors[c - 1]);
       num++;
     }
+    std::cout << "there are " << num << " triangle(s)" << std::endl;
   }
 }
 
 // OpenGL initialization
-void init() {
-  load_model("v1_color.obj");
+void init(const std::string &file_name) {
+  load_model(file_name);
   // Create a vertex array object
-  GLuint vao;
   glGenVertexArrays(1, &vao);
   glBindVertexArray(vao);
-
   // Create and initialize a buffer object
-  GLuint buffer;
   glGenBuffers(1, &buffer);
   glBindBuffer(GL_ARRAY_BUFFER, buffer);
   glBufferData(GL_ARRAY_BUFFER, sizeof(vec4) * (points.size() + colors.size()),
@@ -107,24 +143,19 @@ void init() {
                   points.data());
   glBufferSubData(GL_ARRAY_BUFFER, sizeof(vec4) * points.size(),
                   sizeof(vec4) * colors.size(), colors.data());
-
   // Load shaders and use the resulting shader program
-  GLuint program = InitShader("vshader36.glsl", "fshader36.glsl");
+  program = InitShader("vshader36.glsl", "fshader36.glsl");
   glUseProgram(program);
-
   // set up vertex arrays
-  GLuint vPosition = glGetAttribLocation(program, "vPosition");
+  vPosition = glGetAttribLocation(program, "vPosition");
   glEnableVertexAttribArray(vPosition);
   glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
-
-  GLuint vColor = glGetAttribLocation(program, "vColor");
+  vColor = glGetAttribLocation(program, "vColor");
   glEnableVertexAttribArray(vColor);
   glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0,
                         BUFFER_OFFSET(sizeof(vec4) * points.size()));
-
   rquat_loc = glGetUniformLocation(program, "rquat");
   move_loc = glGetUniformLocation(program, "move");
-
   glEnable(GL_DEPTH_TEST);
   glClearColor(1.0, 1.0, 1.0, 1.0);
 }
@@ -188,7 +219,6 @@ void keyboard(unsigned char key, int x, int y) {
 
 void trackball_ptov(int x, int y, int width, int height, float v[3]) {
   float d, a;
-
   /* project x,y onto a hemi-sphere centered within width, height */
   v[0] = (2.0F * x - width) / width;
   v[1] = (height - 2.0F * y) / height;
@@ -202,7 +232,6 @@ void trackball_ptov(int x, int y, int width, int height, float v[3]) {
 
 void mouseMotion(int x, int y) {
   float curPos[3], dx, dy, dz;
-
   trackball_ptov(x, y, winWidth, winHeight, curPos);
   if (trackingMouse) {
     dx = curPos[0] - lastPos[0];
@@ -210,7 +239,6 @@ void mouseMotion(int x, int y) {
     dz = curPos[2] - lastPos[2];
     if (dx || dy || dz) {
       angle = 1.1 * M_PI * 0.5 * sqrt(dx * dx + dy * dy + dz * dz);
-
       axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1];
       axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2];
       axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0];
@@ -228,7 +256,6 @@ void mouseMotion(int x, int y) {
 }
 
 void startMotion(int x, int y) {
-
   trackingMouse = true;
   redrawContinue = false;
   startX = x;
@@ -240,9 +267,7 @@ void startMotion(int x, int y) {
 }
 
 void stopMotion(int x, int y) {
-
   trackingMouse = false;
-
   if (startX != x || startY != y) {
     redrawContinue = true;
   } else {
@@ -293,7 +318,7 @@ int main(int argc, char **argv) {
     exit(EXIT_FAILURE);
   }
 
-  init();
+  init("v1_color.obj");
   glutReshapeFunc(myReshape);
   glutIdleFunc(spinCube);
   glutDisplayFunc(display);