main.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #include "Angel.h"
  2. #include <fstream>
  3. #include <iostream>
  4. #include <vector>
  5. #define PARAMS_DEBUG_PRINT true
  6. const int texNumTriangles = 64770;
  7. const int cowNumTriangles = 5804;
  8. const int NumTriangles = texNumTriangles + cowNumTriangles;
  9. const int NumVertices = 3 * NumTriangles;
  10. const int TextureWidth = 256;
  11. const int TextureHeight = 128;
  12. typedef Angel::vec4 point4;
  13. typedef Angel::vec4 color4;
  14. // terrain altitude array
  15. float ter_alt[128][256];
  16. // Texture objects and storage for texture image
  17. GLuint textures[1];
  18. GLubyte image[TextureWidth][TextureHeight][3];
  19. // Vertex data arrays
  20. point4 points[NumVertices];
  21. vec2 tex_coords[NumVertices];
  22. vec3 normals[NumVertices];
  23. // plane light params
  24. GLuint plane_light;
  25. GLfloat light_on = 1.0f;
  26. // fog params
  27. GLuint fog; // is_foggy uniform
  28. GLuint eye_pos;
  29. int foggy = 1;
  30. GLuint fog_fac;
  31. float fogFac = 1.0f;
  32. // object (cow) params
  33. GLuint obj_shi;
  34. float objShi = 50.0f;
  35. // Viewing transformation parameters
  36. GLfloat theta = 0.0;
  37. GLfloat phi = 0.0;
  38. GLfloat tau = 0.0;
  39. GLfloat eye_x = 0.0;
  40. GLfloat eye_y = 0.25;
  41. GLfloat eye_z = 0.1;
  42. GLfloat eye_w = 1.0;
  43. GLfloat at_x;
  44. GLfloat at_y;
  45. GLfloat at_z;
  46. GLfloat at_w;
  47. GLuint model_view; // model-view matrix uniform shader variable location
  48. // Projection transformation parameters
  49. GLfloat left = -0.01, right = 0.01;
  50. GLfloat bottom = -0.01, top = 0.01;
  51. GLfloat zNear = 0.1, zFar = 2.0;
  52. GLuint projection; // projection matrix uniform shader variable location
  53. //----------------------------------------------------------------------------
  54. bool hit_check(GLfloat &x, GLfloat &y, GLfloat &z) {
  55. int x_idx = x * 256;
  56. int y_idx = y * 256;
  57. if (x_idx > 255 || x_idx < 0 || y_idx < 0 || y_idx > 127) {
  58. x = 0.0;
  59. y = 0.25;
  60. z = 0.1;
  61. return false;
  62. }
  63. if (PARAMS_DEBUG_PRINT) {
  64. printf("%f, %f\n", ter_alt[y_idx][x_idx], z);
  65. }
  66. if (ter_alt[y_idx][x_idx] >= z) {
  67. x = 0.0;
  68. y = 0.25;
  69. z = 0.1;
  70. return false;
  71. }
  72. return true;
  73. }
  74. void load_model(const std::string &file_name, bool not_tex = false,
  75. float x_offset = 0.0f, float y_offset = 0.0f,
  76. float z_offset = 0.0f) {
  77. std::vector<point4> vertices;
  78. std::vector<vec2> tex_cods;
  79. std::fstream s(file_name, std::fstream::in);
  80. static int index = 0;
  81. if (!s.is_open()) {
  82. std::cerr << "failed to open" << file_name << std::endl;
  83. } else {
  84. std::string t;
  85. float x, y, z;
  86. int a, b, c;
  87. int num = 0;
  88. int idx = 0;
  89. while (s >> t) {
  90. if (t == "v") { // vertices
  91. s >> x >> y >> z;
  92. vertices.emplace_back(x / 50.0f + x_offset, z / 50.0f + z_offset,
  93. y / 50.0f + y_offset, 1.0);
  94. if (!not_tex) {
  95. *(reinterpret_cast<float *>(ter_alt) + idx) = y / 50.0f;
  96. idx++;
  97. }
  98. } else if (t == "vt") {
  99. s >> x >> y;
  100. tex_cods.emplace_back(x, y);
  101. } else if (t == "f") {
  102. s >> a >> b >> c;
  103. a--;
  104. b--;
  105. c--;
  106. vec3 normal = normalize(
  107. cross(vertices[b] - vertices[a], vertices[c] - vertices[b]));
  108. points[index] = vertices[a];
  109. normals[index] = normal;
  110. if (not_tex) {
  111. tex_coords[index] = {20.0, 0.0};
  112. } else {
  113. tex_coords[index] = tex_cods[a];
  114. }
  115. index++;
  116. points[index] = vertices[b];
  117. normals[index] = normal;
  118. if (not_tex) {
  119. tex_coords[index] = {20.0, 0.0};
  120. } else {
  121. tex_coords[index] = tex_cods[b];
  122. }
  123. index++;
  124. points[index] = vertices[c];
  125. normals[index] = normal;
  126. if (not_tex) {
  127. tex_coords[index] = {20.0, 0.0};
  128. } else {
  129. tex_coords[index] = tex_cods[c];
  130. }
  131. index++;
  132. num++;
  133. }
  134. }
  135. std::cout << "Load model:" << file_name << std::endl;
  136. std::cout << "There are " << vertices.size() << "vertice(s)"
  137. << ", " << tex_cods.size() << "tex cor(s)" << std::endl
  138. << "There are " << num << "fragment(s)" << std::endl;
  139. s.close();
  140. }
  141. }
  142. //----------------------------------------------------------------------------
  143. void load_tex(const std::string &file_name) {
  144. char cline[1024];
  145. char p6[10];
  146. int width;
  147. int height;
  148. int depth;
  149. FILE *fp = fopen(file_name.data(), "rb");
  150. fgets(cline, sizeof(cline), fp);
  151. sscanf(cline, "%s %d %d %d", p6, &width, &height, &depth);
  152. std::cout << p6 << "," << width << "," << height << "," << depth << std::endl;
  153. fread(image, sizeof(GLubyte), width * height * 3, fp);
  154. fclose(fp);
  155. }
  156. void init() {
  157. load_tex("gc_tex.ppm");
  158. load_model("gc_tex.obj");
  159. load_model("cow.obj", true, 0.90, 0.05, 0.25); // no tex data in cow obj
  160. // Initialize texture objects
  161. glGenTextures(1, textures);
  162. glBindTexture(GL_TEXTURE_2D, textures[0]);
  163. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TextureWidth, TextureHeight, 0, GL_RGB,
  164. GL_UNSIGNED_BYTE, image);
  165. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  166. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  167. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  168. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  169. glActiveTexture(GL_TEXTURE0);
  170. glBindTexture(GL_TEXTURE_2D, textures[0]);
  171. // Create a vertex array object
  172. GLuint vao;
  173. glGenVertexArrays(1, &vao);
  174. glBindVertexArray(vao);
  175. // Create and initialize a buffer object
  176. GLuint buffer;
  177. glGenBuffers(1, &buffer);
  178. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  179. glBufferData(GL_ARRAY_BUFFER,
  180. sizeof(points) + sizeof(tex_coords) + sizeof(normals), NULL,
  181. GL_STATIC_DRAW);
  182. // Specify an offset to keep track of where we're placing data in our
  183. // vertex array buffer. We'll use the same technique when we
  184. // associate the offsets with vertex attribute pointers.
  185. GLintptr offset = 0;
  186. glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(points), points);
  187. offset += sizeof(points);
  188. glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(tex_coords), tex_coords);
  189. offset += sizeof(tex_coords);
  190. glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(normals), normals);
  191. // Load shaders and use the resulting shader program
  192. GLuint program = InitShader("vshader71.glsl", "fshader71.glsl");
  193. glUseProgram(program);
  194. // set up vertex arrays
  195. offset = 0;
  196. GLuint vPosition = glGetAttribLocation(program, "vPosition");
  197. glEnableVertexAttribArray(vPosition);
  198. glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,
  199. BUFFER_OFFSET(offset));
  200. offset += sizeof(points);
  201. GLuint vTexCoord = glGetAttribLocation(program, "vTexCoord");
  202. glEnableVertexAttribArray(vTexCoord);
  203. glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
  204. BUFFER_OFFSET(offset));
  205. offset += sizeof(tex_coords);
  206. GLuint vNormal = glGetAttribLocation(program, "vNormal");
  207. glEnableVertexAttribArray(vNormal);
  208. glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0,
  209. BUFFER_OFFSET(offset));
  210. // Set the value of the fragment shader texture sampler variable
  211. // ("texture") to the the appropriate texture unit. In this case,
  212. // zero, for GL_TEXTURE0 which was previously set by calling
  213. // glActiveTexture().
  214. glUniform1i(glGetUniformLocation(program, "tex"), 0);
  215. model_view = glGetUniformLocation(program, "model_view");
  216. projection = glGetUniformLocation(program, "projection");
  217. fog = glGetUniformLocation(program, "foggy");
  218. eye_pos = glGetUniformLocation(program, "eye_pos");
  219. plane_light = glGetUniformLocation(program, "plane_light_on");
  220. fog_fac = glGetUniformLocation(program, "fog_fac");
  221. obj_shi = glGetUniformLocation(program, "obj_shi");
  222. glEnable(GL_DEPTH_TEST);
  223. glClearColor(1, 1, 1, 1);
  224. }
  225. void display(void) {
  226. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  227. point4 eye(eye_x, eye_y, eye_z, 1.0);
  228. at_x = cos(theta) * cos(phi) * 100.0;
  229. at_y = sin(theta) * cos(phi) * 100.0;
  230. at_z = sin(phi) * 100.0;
  231. point4 at(at_x, at_y, at_z, 1.0);
  232. vec4 up(0.0, 100 * sin(tau), 100 * cos(tau), 0.0);
  233. mat4 mv = LookAt(eye, at, up);
  234. glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
  235. mat4 p = Frustum(left, right, bottom, top, zNear, zFar);
  236. glUniformMatrix4fv(projection, 1, GL_TRUE, p);
  237. glUniform3f(eye_pos, eye_x, eye_y, eye_z);
  238. glUniform1i(fog, foggy);
  239. glUniform1f(plane_light, light_on);
  240. glUniform1f(fog_fac, fogFac);
  241. glUniform1f(obj_shi, objShi);
  242. glDrawArrays(GL_TRIANGLES, 0, NumVertices);
  243. glutSwapBuffers();
  244. }
  245. //----------------------------------------------------------------------------
  246. void mouse(int button, int state, int x, int y) {}
  247. //----------------------------------------------------------------------------
  248. void idle(void) { glutPostRedisplay(); }
  249. //----------------------------------------------------------------------------
  250. void keyboard(unsigned char key, int mousex, int mousey) {
  251. switch (key) {
  252. case 033: // Escape Key
  253. exit(0);
  254. break;
  255. case 'l':
  256. if (light_on > 0.0) {
  257. light_on = 0.0;
  258. } else {
  259. light_on = 1.0;
  260. }
  261. break;
  262. case 'f':
  263. if (foggy > 0) {
  264. foggy = 0;
  265. } else {
  266. foggy = 1;
  267. }
  268. break;
  269. case 'k':
  270. objShi -= 1.0f;
  271. if (objShi < 0.0f) {
  272. objShi = 0.0f;
  273. }
  274. break;
  275. case 'K':
  276. objShi += 1.0f;
  277. break;
  278. case 'g':
  279. fogFac -= 0.1;
  280. if (fogFac < 0) {
  281. fogFac = 0;
  282. }
  283. break;
  284. case 'G':
  285. fogFac += 0.1;
  286. break;
  287. case '1':
  288. tau += 0.01;
  289. break;
  290. case '3':
  291. tau -= 0.01;
  292. break;
  293. case 'q':
  294. theta += 0.01;
  295. break;
  296. case 'e':
  297. theta -= 0.01;
  298. break;
  299. case 'w':
  300. eye_x += 0.01;
  301. break;
  302. case 's':
  303. eye_x -= 0.01;
  304. break;
  305. case 'd':
  306. eye_y -= 0.01;
  307. break;
  308. case 'a':
  309. eye_y += 0.01;
  310. break;
  311. case '9':
  312. eye_z -= 0.01;
  313. break;
  314. case '6':
  315. eye_z += 0.01;
  316. break;
  317. case '8':
  318. phi -= 0.01;
  319. break;
  320. case '5':
  321. phi += 0.01;
  322. break;
  323. }
  324. if (PARAMS_DEBUG_PRINT) {
  325. printf("obj_shi:%f\n", objShi);
  326. printf("eye_x,y,z:%f, %f, %f, %f\n", eye_x, eye_y, eye_z, eye_w);
  327. printf("at_x,y,z:%f, %f, %f, %f\n", at_x, at_y, at_z, at_w);
  328. }
  329. hit_check(eye_x, eye_y, eye_z);
  330. glutPostRedisplay();
  331. }
  332. //----------------------------------------------------------------------------
  333. int main(int argc, char **argv) {
  334. glutInit(&argc, argv);
  335. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  336. glutInitWindowSize(512, 512);
  337. glutInitContextVersion(3, 1);
  338. glutInitContextProfile(GLUT_CORE_PROFILE);
  339. glutCreateWindow("flying");
  340. if (glewInit() != GLEW_OK) {
  341. std::cerr << "Failed to initialize GLEW ... exiting" << std::endl;
  342. exit(EXIT_FAILURE);
  343. }
  344. init();
  345. glutDisplayFunc(display);
  346. glutKeyboardFunc(keyboard);
  347. glutMouseFunc(mouse);
  348. // glutIdleFunc(idle);
  349. glutMainLoop();
  350. return 0;
  351. }