123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #include "Angel.h"
- #include <fstream>
- #include <iostream>
- #include <vector>
- 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];
- // Array of rotation angles (in degrees) for each coordinate axis
- enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
- int Axis = Xaxis;
- GLfloat Theta[NumAxes] = {0.0, 0.0, 0.0};
- GLuint theta;
- //----------------------------------------------------------------------------
- void load_model(const std::string &file_name) {
- std::vector<point4> vertices;
- std::vector<vec2> 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_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- 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);
- theta = glGetUniformLocation(program, "theta");
- 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);
- glUniform3fv(theta, 1, Theta);
- glDrawArrays(GL_TRIANGLES, 0, NumVertices);
- glutSwapBuffers();
- }
- //----------------------------------------------------------------------------
- void mouse(int button, int state, int x, int y) {
- if (state == GLUT_DOWN) {
- switch (button) {
- case GLUT_LEFT_BUTTON:
- Axis = Xaxis;
- break;
- case GLUT_MIDDLE_BUTTON:
- Axis = Yaxis;
- break;
- case GLUT_RIGHT_BUTTON:
- Axis = Zaxis;
- break;
- }
- }
- }
- //----------------------------------------------------------------------------
- void idle(void) {
- Theta[Axis] += 0.5;
- if (Theta[Axis] > 360.0) {
- Theta[Axis] -= 360.0;
- }
- glutPostRedisplay();
- }
- //----------------------------------------------------------------------------
- void keyboard(unsigned char key, int mousex, int mousey) {
- switch (key) {
- case 033: // Escape Key
- case 'q':
- case 'Q':
- exit(EXIT_SUCCESS);
- break;
- case 'b':
- case 'B':
- glutIdleFunc(idle);
- break;
- case 'e':
- case 'E':
- glutIdleFunc(NULL);
- break;
- }
- 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;
- }
|