#include "Angel.h" #include #include #include const int NumTriangles = 64770; // (6 faces)(2 triangles/face) const int NumVertices = 3 * NumTriangles; const int TextureWidth = 256; const int TextureHeight = 128; typedef Angel::vec4 point4; typedef Angel::vec4 color4; // Texture objects and storage for texture image GLuint textures[1]; GLubyte image[TextureWidth][TextureHeight][3]; // Vertex data arrays point4 points[NumVertices]; vec2 tex_coords[NumVertices]; // Viewing transformation parameters GLfloat theta = 0.0; GLfloat phi = 0.0; GLfloat tau = 0.0; GLfloat eye_x = 0.0; GLfloat eye_y = 0.25; GLfloat eye_z = 0.1; GLfloat eye_w = 1.0; GLfloat at_x; GLfloat at_y; GLfloat at_z; GLfloat at_w; GLuint model_view; // model-view matrix uniform shader variable location // Projection transformation parameters GLfloat left = -0.01, right = 0.01; GLfloat bottom = -0.01, top = 0.01; GLfloat zNear = 0.1, zFar = 2.0; GLuint projection; // projection matrix uniform shader variable location //---------------------------------------------------------------------------- void load_model(const std::string &file_name) { std::vector vertices; std::vector tex_cods; std::fstream s(file_name, std::fstream::in); if (!s.is_open()) { std::cerr << "failed to open" << file_name << std::endl; } else { int index = 0; std::string t; float x, y, z; int a, b, c; int num = 0; while (s >> t) { if (t == "v") { // vertices s >> x >> y >> z; vertices.emplace_back(x / 50.0f, z / 50.0f, y / 50.0f, 1.0); } else if (t == "vt") { s >> x >> y; tex_cods.emplace_back(x, y); } else if (t == "f") { s >> a >> b >> c; a--; b--; c--; points[index] = vertices[a]; tex_coords[index] = tex_cods[a]; index++; points[index] = vertices[b]; tex_coords[index] = tex_cods[b]; index++; points[index] = vertices[c]; tex_coords[index] = tex_cods[c]; index++; num++; } } std::cout << "There are " << vertices.size() << "vertice(s)" << ", " << tex_cods.size() << "tex cor(s)" << std::endl << "There are " << num << "fragment(s)" << std::endl; s.close(); } } //---------------------------------------------------------------------------- void load_tex(const std::string &file_name) { char cline[1024]; char p6[10]; int width; int height; int depth; FILE *fp = fopen(file_name.data(), "rb"); fgets(cline, sizeof(cline), fp); sscanf(cline, "%s %d %d %d", p6, &width, &height, &depth); std::cout << p6 << "," << width << "," << height << "," << depth << std::endl; fread(image, sizeof(GLubyte), width * height * 3, fp); fclose(fp); } void init() { load_tex("gc_tex.ppm"); load_model("gc_tex.obj"); // Initialize texture objects glGenTextures(1, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TextureWidth, TextureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); // 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(points) + sizeof(tex_coords), NULL, GL_STATIC_DRAW); // Specify an offset to keep track of where we're placing data in our // vertex array buffer. We'll use the same technique when we // associate the offsets with vertex attribute pointers. GLintptr offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(points), points); offset += sizeof(points); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(tex_coords), tex_coords); // Load shaders and use the resulting shader program GLuint program = InitShader("vshader71.glsl", "fshader71.glsl"); glUseProgram(program); // set up vertex arrays offset = 0; GLuint vPosition = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(vPosition); glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset)); offset += sizeof(points); GLuint vTexCoord = glGetAttribLocation(program, "vTexCoord"); glEnableVertexAttribArray(vTexCoord); glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset)); // Set the value of the fragment shader texture sampler variable // ("texture") to the the appropriate texture unit. In this case, // zero, for GL_TEXTURE0 which was previously set by calling // glActiveTexture(). glUniform1i(glGetUniformLocation(program, "tex"), 0); model_view = glGetUniformLocation(program, "model_view"); projection = glGetUniformLocation(program, "projection"); glEnable(GL_DEPTH_TEST); glClearColor(1.0, 1.0, 1.0, 1.0); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); point4 eye(eye_x, eye_y, eye_z, 1.0); at_x = cos(theta) * cos(phi) * 100.0; at_y = sin(theta) * cos(phi) * 100.0; at_z = sin(phi) * 100.0; point4 at(at_x, at_y, at_z, 1.0); vec4 up(0.0, 100 * sin(tau), 100 * cos(tau), 0.0); mat4 mv = LookAt(eye, at, up); glUniformMatrix4fv(model_view, 1, GL_TRUE, mv); mat4 p = Frustum(left, right, bottom, top, zNear, zFar); glUniformMatrix4fv(projection, 1, GL_TRUE, p); glDrawArrays(GL_TRIANGLES, 0, NumVertices); glutSwapBuffers(); } //---------------------------------------------------------------------------- void mouse(int button, int state, int x, int y) {} //---------------------------------------------------------------------------- void idle(void) { glutPostRedisplay(); } //---------------------------------------------------------------------------- void keyboard(unsigned char key, int mousex, int mousey) { switch (key) { case 033: // Escape Key case '1': tau += 0.01; break; case '3': tau -= 0.01; break; case 'q': theta += 0.01; break; case 'e': theta -= 0.01; break; case 'A': at_x += 0.01; break; case 'D': at_x -= 0.001; break; case 'w': eye_x += 0.01; break; case 's': eye_x -= 0.01; break; case 'd': eye_y -= 0.01; break; case 'a': eye_y += 0.01; break; case '9': eye_z -= 0.01; break; case '6': eye_z += 0.01; break; case '8': phi -= 0.01; break; case '5': phi += 0.01; break; } printf("eye_x,y,z:%f, %f, %f, %f\n", eye_x, eye_y, eye_z, eye_w); printf("at_x,y,z:%f, %f, %f, %f\n", at_x, at_y, at_z, at_w); glutPostRedisplay(); } //---------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(512, 512); glutInitContextVersion(3, 1); glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow("flying"); if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW ... exiting" << std::endl; exit(EXIT_FAILURE); } init(); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); //glutIdleFunc(idle); glutMainLoop(); return 0; }