main.cc 8.9 KB

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