cmodsphere.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:8k
源码类别:

OpenGL

开发平台:

Visual C++

  1. #include <iostream>
  2. #include <fstream>
  3. #include <cmath>
  4. #include <cstdio>
  5. #include <io.h>
  6. #include <fcntl.h>
  7. #include "../../celmath/vecmath.h"
  8. using namespace std;
  9. typedef unsigned int uint32;
  10. // TODO: these shouldn't be hardcoded
  11. static int latSamples = 1440;
  12. static int longSamples = 2880;
  13. const float pi = 3.14159265;
  14. static float* samples = NULL;
  15. // Read a big-endian 32-bit unsigned integer
  16. static uint32 readUint(istream& in)
  17. {
  18.     uint32 ret;
  19.     in.read((char*) &ret, sizeof(uint32));
  20.     return (uint32) ret;
  21. }
  22. static float readFloat(istream& in)
  23. {
  24.     uint32 i = readUint(in);
  25.     uint32 n = ((i & 0xff) << 24) | ((i & 0xff00) << 8) | ((i & 0xff0000) >> 8) | ((i & 0xff000000) >> 24);
  26.     return *((float*) &n);
  27. }
  28. bool readLongLatAscii(istream& in)
  29. {
  30.     return false;
  31. }
  32. bool readBinary(istream& in,
  33.                 unsigned int latSampleCount,
  34.                 unsigned int longSampleCount)
  35. {
  36.     for (unsigned int i = 0; i < latSampleCount; i++)
  37.     {
  38.         for (unsigned int j = 0; j < longSampleCount; j++)
  39.         {
  40.             float r = readFloat(in) / 1000.0f;
  41.             samples[i * longSampleCount + j] = r;
  42.         }
  43.     }
  44.     return true;
  45. }
  46. inline float sample(float samples[],
  47.                     unsigned int width,
  48.                     unsigned int height,
  49.                     float s,
  50.                     float t)
  51. {
  52.     float ssamp = (float) (width - 1) + 0.99f;
  53.     float tsamp = (float) (height - 1) + 0.99f;
  54.     return samples[(unsigned int) (t * tsamp) * width +
  55.                    (unsigned int) (s * ssamp)];
  56. }
  57. inline float sampleBilinear(float samples[],
  58.                             unsigned int width,
  59.                             unsigned int height,
  60.                             float s,
  61.                             float t)
  62. {
  63.     unsigned int x0 = (unsigned int) (s * width) % width;
  64.     unsigned int y0 = (unsigned int) (t * height) % height;
  65.     unsigned int x1 = (unsigned int) (x0 + 1) % width;
  66.     unsigned int y1 = (unsigned int) (y0 + 1) % height;
  67.     float tx = s * width - (float) (unsigned int) (s * width);
  68.     float ty = t * height - (float) (unsigned int) (t * height);
  69.     float s00 = samples[y0 * width + x0];
  70.     float s01 = samples[y0 * width + x1];
  71.     float s10 = samples[y1 * width + x0];
  72.     float s11 = samples[y1 * width + x1];
  73.     float s0 = (1.0f - tx) * s00 + tx * s01;
  74.     float s1 = (1.0f - tx) * s10 + tx * s11;
  75.     return (1.0f - ty) * s0 + ty * s1;
  76. }
  77. // subdiv is the number of rows in the triangle
  78. void triangleSection(unsigned int subdiv,
  79.                      Vec3f v0, Vec3f v1, Vec3f v2,
  80.                      Vec2f tex0, Vec2f tex1, Vec2f tex2)
  81. {
  82.     float ssamp = (float) (longSamples - 1) + 0.99f;
  83.     float tsamp = (float) (latSamples - 1) + 0.99f;
  84.     for (unsigned int i = 0; i <= subdiv; i++)
  85.     {
  86.         for (unsigned int j = 0; j <= i; j++)
  87.         {
  88.             float u = (i == 0) ? 0.0f : (float) j / (float) i;
  89.             float v = (float) i / (float) subdiv;
  90.             Vec3f w0 = (1.0f - v) * v0 + v * v1;
  91.             Vec3f w1 = (1.0f - v) * v0 + v * v2;
  92.             Vec3f w = (1.0f - u) * w0 + u * w1;
  93.             Vec2f t((1.0f - u) * tex1.x + u * tex2.x,
  94.                     (1.0f - v) * tex0.y + v * tex1.y);
  95.             w.normalize();
  96.             if (samples != NULL)
  97.             {
  98.                 float theta = (float) acos(w.y);
  99.                 float phi = (float) atan2(-w.z, w.x);
  100.                 float s = phi / (2.0f * pi) + 0.5f;
  101.                 float t = theta / pi;
  102.                 float r = sampleBilinear(samples, longSamples, latSamples, s, t);
  103.                 w = w * r;
  104.             }
  105.             cout << w.x << " " << w.y << " " << w.z << " "
  106.                  << t.x << " " << t.y << "n";
  107.         }
  108.     }
  109. }
  110. // return the nth triangular number
  111. inline unsigned int trinum(unsigned int n)
  112. {
  113.     return (n * (n + 1)) / 2;
  114. }
  115. void triangleMesh(unsigned int subdiv,
  116.                   unsigned int baseIndex)
  117. {
  118.     for (unsigned int i = 0; i < subdiv; i++)
  119.     {
  120.         for (unsigned int j = 0; j <= i; j++)
  121.         {
  122.             unsigned int t0 = baseIndex + trinum(i) + j;
  123.             unsigned int t1 = baseIndex + trinum(i + 1) + j;
  124.             
  125.             cout << t0 << " " << t1 << " " << t1 + 1 << "n";
  126.             if (j != i)
  127.                 cout << t0 << " " << t1 + 1 << " " << t0 + 1 << "n";
  128.         }
  129.     }
  130. }
  131. int main(int argc, char* argv[])
  132. {
  133.     // Get the command line arguments
  134.     if (argc != 4)
  135.     {
  136.         cerr << "Usage: cmodsphere <width> <height> <tessellation>n";
  137.         return 1;
  138.     }
  139.     if (sscanf(argv[1], "%u", &longSamples) != 1)
  140.     {
  141.         cerr << "Invalid widthn";
  142.         return 1;
  143.     }
  144.     if (sscanf(argv[2], "%u", &latSamples) != 1)
  145.     {
  146.         cerr << "Invalid heightn";
  147.         return 1;
  148.     }
  149.     unsigned int subdiv = 0;
  150.     if (sscanf(argv[3], "%u", &subdiv) != 1)
  151.     {
  152.         cerr << "Invalid tessellation leveln";
  153.         return 1;
  154.     }
  155.     samples = new float[latSamples * longSamples];
  156. #ifdef _WIN32
  157.     // Enable binary reads for stdin on Windows
  158.     _setmode(_fileno(stdin), _O_BINARY);
  159. #endif
  160.     // Read the height map
  161.     readBinary(cin, latSamples, longSamples);
  162.     // Output the mesh header
  163.     cout << "#celmodel__asciin";
  164.     cout << "n";
  165.     cout << "materialn";
  166.     cout << "diffuse 0.8 0.8 0.8n";
  167.     cout << "end_materialn";
  168.     cout << "n";
  169.     cout << "meshn";
  170.     cout << "vertexdescn";
  171.     cout << "position f3n";
  172.     cout << "texcoord0 f2n";
  173.     cout << "end_vertexdescn";
  174.     cout << "n";
  175.     // Octahedral subdivision; the subdivison level for an a face
  176.     // is one fourth the overall tessellation level.
  177.     unsigned int primitiveFaces = 8;
  178.     subdiv = subdiv / 4;
  179.     unsigned int s1 = subdiv + 1;
  180.     unsigned int verticesPerPrimFace = (s1 * s1 + s1) / 2;
  181.     unsigned int vertexCount = primitiveFaces * verticesPerPrimFace;
  182.     unsigned int trianglesPerPrimFace = s1 * s1 - 2 * s1 + 1;
  183.     unsigned int triangleCount = primitiveFaces * trianglesPerPrimFace;
  184.     cout << "vertices " << vertexCount << "n";
  185.     triangleSection(subdiv,
  186.                     Vec3f(0.0f, 1.0f, 0.0f),
  187.                     Vec3f(1.0f, 0.0f, 0.0f),
  188.                     Vec3f(0.0f, 0.0f, -1.0f),
  189.                     Vec2f(0.0f, 0.0f),
  190.                     Vec2f(0.00f, 0.5f),
  191.                     Vec2f(0.25f, 0.5f));
  192.     triangleSection(subdiv,
  193.                     Vec3f(0.0f, 1.0f, 0.0f),
  194.                     Vec3f(0.0f, 0.0f, 1.0f),
  195.                     Vec3f(1.0f, 0.0f, 0.0f),
  196.                     Vec2f(0.0f, 0.0f),
  197.                     Vec2f(0.75f, 0.5f),
  198.                     Vec2f(1.00f, 0.5f));;
  199.     triangleSection(subdiv,
  200.                     Vec3f(0.0f, 1.0f, 0.0f),
  201.                     Vec3f(-1.0f, 0.0f, 0.0f),
  202.                     Vec3f(0.0f, 0.0f, 1.0f),
  203.                     Vec2f(0.0f, 0.0f),
  204.                     Vec2f(0.50f, 0.5f),
  205.                     Vec2f(0.75f, 0.5f));
  206.     triangleSection(subdiv,
  207.                     Vec3f(0.0f, 1.0f, 0.0f),
  208.                     Vec3f(0.0f, 0.0f, -1.0f),
  209.                     Vec3f(-1.0f, 0.0f, 0.0f),
  210.                     Vec2f(0.0f, 0.0f),
  211.                     Vec2f(0.25f, 0.5f),
  212.                     Vec2f(0.50f, 0.5f));
  213.     triangleSection(subdiv,
  214.                     Vec3f(0.0f, -1.0f, 0.0f),
  215.                     Vec3f(0.0f, 0.0f, -1.0f),
  216.                     Vec3f(1.0f, 0.0f, 0.0f),
  217.                     Vec2f(0.0f, 1.0f),
  218.                     Vec2f(0.25f, 0.5f),
  219.                     Vec2f(0.00f, 0.5f));
  220.     triangleSection(subdiv,
  221.                     Vec3f(0.0f, -1.0f, 0.0f),
  222.                     Vec3f(1.0f, 0.0f, 0.0f),
  223.                     Vec3f(0.0f, 0.0f, 1.0f),
  224.                     Vec2f(0.0f, 1.0f),
  225.                     Vec2f(1.00f, 0.5f),
  226.                     Vec2f(0.75f, 0.5f));
  227.     triangleSection(subdiv,
  228.                     Vec3f(0.0f, -1.0f, 0.0f),
  229.                     Vec3f(0.0f, 0.0f, 1.0f),
  230.                     Vec3f(-1.0f, 0.0f, 0.0f),
  231.                     Vec2f(0.0f, 1.0f),
  232.                     Vec2f(0.75f, 0.5f),
  233.                     Vec2f(0.50f, 0.5f));
  234.     triangleSection(subdiv,
  235.                     Vec3f(0.0f, -1.0f, 0.0f),
  236.                     Vec3f(-1.0f, 0.0f, 0.0f),
  237.                     Vec3f(0.0f, 0.0f, -1.0f),
  238.                     Vec2f(0.0f, 1.0f),
  239.                     Vec2f(0.50f, 0.5f),
  240.                     Vec2f(0.25f, 0.5f));
  241.     cout << "trilist 0 " << triangleCount * 3 << "n";
  242.     for (unsigned int f = 0; f < primitiveFaces; f++)
  243.     {
  244.         triangleMesh(subdiv, f * verticesPerPrimFace);
  245.     }
  246.     cout << "end_meshn";
  247. }