CHEN Yihui 5 years ago
parent
commit
80db8450da
3 changed files with 302 additions and 0 deletions
  1. 15 0
      Angel.h
  2. 243 0
      main.cc
  3. 44 0
      mat.h

+ 15 - 0
Angel.h

@@ -0,0 +1,15 @@
+
+#version 150
+
+in  vec4 color;
+in  vec2 texCoord;
+
+out vec4 fColor;
+
+uniform sampler2D tex;
+
+void main() 
+{ 
+    fColor = color * texture( tex, texCoord );
+} 
+

+ 243 - 0
main.cc

@@ -0,0 +1,243 @@
+#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;
+}

+ 44 - 0
mat.h

@@ -0,0 +1,44 @@
+#version 150
+
+in  vec4 vPosition;
+in  vec4 vColor;
+in  vec2 vTexCoord;
+
+out vec4 color;
+out vec2 texCoord;
+
+uniform vec3 theta;
+
+void main() 
+{
+    const float  DegreesToRadians = 3.14159265 / 180.0;
+    
+    vec3 c = cos( DegreesToRadians * theta );
+    vec3 s = sin( DegreesToRadians * theta );
+
+    mat4 rx = mat4( 1.0, 0.0,  0.0, 0.0,
+		    0.0, c.x, -s.x, 0.0,
+		    0.0, s.x,  c.x, 0.0,
+		    0.0, 0.0,  0.0, 1.0);
+
+    mat4 ry = mat4(   c.y, 0.0, s.y, 0.0,
+		      0.0, 1.0, 0.0, 0.0,
+		     -s.y, 0.0, c.y, 0.0,
+		      0.0, 0.0, 0.0, 1.0 );
+
+    // Workaround for bug in ATI driver
+    ry[1][0] = 0.0;
+    ry[1][1] = 1.0;
+    
+    mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
+		    s.z,  c.z, 0.0, 0.0,
+		    0.0,  0.0, 1.0, 0.0,
+		    0.0,  0.0, 0.0, 1.0 );
+
+    // Workaround for bug in ATI driver
+    rz[2][2] = 1.0;
+    
+    color       = vec4(0.5, 0.5, 0.5, 1);
+    texCoord    = vTexCoord;
+    gl_Position = rz * ry * rx * vPosition;
+}