Advertisement
Guest User

Untitled

a guest
Feb 12th, 2014
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.93 KB | None | 0 0
  1. #include <GL/glew.h>
  2. #include <GLFW/glfw3.h>
  3. #include <glm/glm.hpp>
  4. #include <glm/gtc/matrix_transform.hpp>
  5. #include <glm/gtx/multiple.hpp>
  6. #include <glm/gtc/type_ptr.hpp>
  7. #include <vector>
  8. #include <cstdio>
  9.  
  10. #define GLSL(src) "#version 440 core\n" #src
  11.  
  12. void APIENTRY debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void* data)
  13. {
  14.     printf("OpenGL debug: %s\n\n", msg);
  15. }
  16.  
  17. void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  18. {
  19.     if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
  20.         glfwSetWindowShouldClose(window, GL_TRUE);
  21. }
  22.  
  23. void init_debug()
  24. {
  25.     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  26.     glDebugMessageCallback(debug_callback, nullptr);
  27.     glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
  28.     glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
  29.     const char debug_message[] = "Debug output enabled.";
  30.     glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, sizeof(debug_message), debug_message);
  31. }
  32.  
  33. GLuint create_program(const char *vertex_source, const char *fragment_source)
  34. {
  35.     GLuint vs = glCreateShader(GL_VERTEX_SHADER);
  36.     glShaderSource(vs, 1, &vertex_source, nullptr);
  37.     glCompileShader(vs);
  38.  
  39.     GLint status;
  40.     glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
  41.  
  42.     if (status == GL_FALSE)
  43.     {
  44.         GLint maxLength = 0;
  45.         glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);
  46.  
  47.         std::vector<char> errorLog(maxLength);
  48.         glGetShaderInfoLog(vs, maxLength, &maxLength, &errorLog[0]);
  49.  
  50.         printf(&errorLog[0]);
  51.  
  52.         glfwTerminate();
  53.         exit(EXIT_FAILURE);
  54.     }
  55.  
  56.     unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
  57.     glShaderSource(fs, 1, &fragment_source, nullptr);
  58.     glCompileShader(fs);
  59.  
  60.     glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
  61.  
  62.     if (status == GL_FALSE)
  63.     {
  64.         GLint maxLength = 0;
  65.         glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength);
  66.  
  67.         std::vector<char> errorLog(maxLength);
  68.         glGetShaderInfoLog(fs, maxLength, &maxLength, &errorLog[0]);
  69.  
  70.         printf(&errorLog[0]);
  71.  
  72.         glfwTerminate();
  73.         exit(EXIT_FAILURE);
  74.     }
  75.  
  76.     GLuint shader_program = glCreateProgram();
  77.     glAttachShader(shader_program, fs);
  78.     glAttachShader(shader_program, vs);
  79.     glLinkProgram(shader_program);
  80.  
  81.     glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
  82.  
  83.     if (status == GL_FALSE)
  84.     {
  85.         GLint maxLength = 0;
  86.         glGetProgramiv(shader_program, GL_INFO_LOG_LENGTH, &maxLength);
  87.  
  88.         std::vector<char> errorLog(maxLength);
  89.         glGetProgramInfoLog(shader_program, maxLength, &maxLength, &errorLog[0]);
  90.  
  91.         printf(&errorLog[0]);
  92.  
  93.         glfwTerminate();
  94.         exit(EXIT_FAILURE);
  95.     }
  96.  
  97.     return shader_program;
  98. }
  99.  
  100. enum buffer_type
  101. {
  102.     BUFFER_INDEX,
  103.     BUFFER_POSITION,
  104.     BUFFER_TEXCOORD,
  105.     BUFFER_MAX
  106. };
  107.  
  108. enum texture_type
  109. {
  110.     TEXTURE_INDEX,
  111.     TEXTURE_POSITION,
  112.     TEXTURE_TEXCOORD,
  113.     TEXTURE_DIFUSE,
  114.     TEXTURE_MAX
  115. };
  116.  
  117. const int indexBufferData[] = {
  118.     4, 0, 5, 1, 1, 2,
  119.     5, 0, 6, 1, 2, 2,
  120.     6, 0, 7, 1, 3, 2,
  121.     7, 0, 4, 1, 0, 2,
  122.     0, 0, 1, 1, 3, 3,
  123.     7, 0, 6, 1, 5, 2,
  124.     0, 3, 4, 0, 1, 2,
  125.     1, 3, 5, 0, 2, 2,
  126.     2, 3, 6, 0, 3, 2,
  127.     3, 3, 7, 0, 0, 2,
  128.     3, 3, 0, 0, 2, 2,
  129.     4, 3, 7, 0, 5, 2
  130. };
  131.  
  132. const float positionBufferData[] = {
  133.     -1.0f, -1.0f, 1.0f,
  134.     -1.0f, -1.0f, -1.0f,
  135.     1.0f, -1.0f, -1.0f,
  136.     1.0f, -1.0f, 1.0f,
  137.     -1.0f, 1.0f, 1.0f,
  138.     -1.0f, 1.0f, -1.0f,
  139.     1.0f, 1.0f, -1.0f,
  140.     1.0f, 1.0f, 1.0f
  141. };
  142.  
  143. const float texcoordBufferData[] = {
  144.     0.0f, 0.0f,
  145.     1.0f, 0.0f,
  146.     1.0f, 1.0f,
  147.     0.0f, 1.0f
  148. };
  149.  
  150. const char* vertex_shader = GLSL(
  151.     layout(location = 0) uniform isamplerBuffer indexBuffer;
  152.     layout(location = 1) uniform samplerBuffer positionBuffer;
  153.     layout(location = 2) uniform samplerBuffer texcoordBuffer;
  154.     layout(location = 4) uniform mat4 MVP;
  155.     out vec2 texcoord;
  156.  
  157.     void main()
  158.     {
  159.         ivec2 index = texelFetch(indexBuffer, gl_VertexID).xy;
  160.         vec3 position = texelFetch(positionBuffer, index.x).xyz;
  161.         texcoord = texelFetch(texcoordBuffer, index.y).xy;
  162.         gl_Position = MVP * vec4(position, 1.0);
  163.     }
  164. );
  165.  
  166. const char* fragment_shader = GLSL(
  167.     in vec2 texcoord;
  168.     out vec4 frag_color;
  169.     layout(location = 3) uniform sampler2D texture0;
  170.  
  171.     void main()
  172.     {
  173.         vec3 diffuse = texture(texture0, texcoord).xyz;
  174.         frag_color = vec4(diffuse, 1.0);
  175.     }
  176. );
  177.  
  178. int main()
  179. {
  180.     if(!glfwInit())
  181.         exit(EXIT_FAILURE);
  182.  
  183.     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
  184.     glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
  185.     glfwWindowHint(GLFW_SAMPLES, 16);
  186.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  187.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
  188.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  189.     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  190.     glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
  191.  
  192.     GLFWwindow* window = glfwCreateWindow(768, 768, "OpenGL", NULL, NULL);
  193.  
  194.     if(!window)
  195.     {
  196.         glfwTerminate();
  197.         exit(EXIT_FAILURE);
  198.     }
  199.  
  200.     glfwSetKeyCallback(window, key_callback);
  201.     glfwMakeContextCurrent(window);
  202.     glfwSwapInterval(-1);
  203.  
  204.     glewExperimental = GL_TRUE;
  205.     GLenum glewError = glewInit();
  206.  
  207.     if(glewError != GLEW_OK)
  208.     {
  209.         glfwTerminate();
  210.         exit(EXIT_FAILURE);
  211.     }
  212.  
  213.     printf("OpenGL Version: %s\n\n", glGetString(GL_VERSION));
  214.  
  215.     init_debug();
  216.  
  217.     GLuint vao = 0;
  218.     glGenVertexArrays(1, &vao);
  219.     glBindVertexArray(vao);
  220.  
  221.     GLint TextureBufferOffsetAlignment = 0;
  222.     glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &TextureBufferOffsetAlignment);
  223.  
  224.     int IndexMultiple = glm::higherMultiple(int(sizeof(indexBufferData)), int(TextureBufferOffsetAlignment));
  225.     int PositionMultiple = glm::higherMultiple(int(sizeof(positionBufferData)), int(TextureBufferOffsetAlignment));
  226.     int TexcoordMultiple = glm::higherMultiple(int(sizeof(texcoordBufferData)), int(TextureBufferOffsetAlignment));
  227.  
  228.     GLuint BufferName[BUFFER_MAX] = {0};
  229.  
  230.     glGenBuffers(BUFFER_MAX, BufferName);
  231.  
  232.     glBindBuffer(GL_TEXTURE_BUFFER, BufferName[BUFFER_INDEX]);
  233.     glBufferData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment + IndexMultiple, 0, GL_STATIC_DRAW);
  234.     glBufferSubData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment, sizeof(indexBufferData), indexBufferData);
  235.  
  236.     glBindBuffer(GL_TEXTURE_BUFFER, BufferName[BUFFER_POSITION]);
  237.     glBufferData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment + PositionMultiple, 0, GL_STATIC_DRAW);
  238.     glBufferSubData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment, sizeof(positionBufferData), positionBufferData);
  239.  
  240.     glBindBuffer(GL_TEXTURE_BUFFER, BufferName[BUFFER_TEXCOORD]);
  241.     glBufferData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment + TexcoordMultiple, 0, GL_STATIC_DRAW);
  242.     glBufferSubData(GL_TEXTURE_BUFFER, TextureBufferOffsetAlignment, sizeof(texcoordBufferData), texcoordBufferData);
  243.  
  244.     GLuint TextureName[TEXTURE_MAX] = {0};
  245.  
  246.     glGenTextures(TEXTURE_MAX, TextureName);
  247.  
  248.     glBindTexture(GL_TEXTURE_BUFFER, TextureName[TEXTURE_INDEX]);
  249.     glTexBufferRange(GL_TEXTURE_BUFFER, GL_RG32I, BufferName[BUFFER_INDEX], TextureBufferOffsetAlignment, sizeof(indexBufferData));
  250.     glBindMultiTextureEXT(GL_TEXTURE0, GL_TEXTURE_BUFFER, TextureName[TEXTURE_INDEX]);
  251.  
  252.     glBindTexture(GL_TEXTURE_BUFFER, TextureName[TEXTURE_POSITION]);
  253.     glTexBufferRange(GL_TEXTURE_BUFFER, GL_RGB32F, BufferName[BUFFER_POSITION], TextureBufferOffsetAlignment, sizeof(positionBufferData));
  254.     glBindMultiTextureEXT(GL_TEXTURE1, GL_TEXTURE_BUFFER, TextureName[TEXTURE_POSITION]);
  255.  
  256.     glBindTexture(GL_TEXTURE_BUFFER, TextureName[TEXTURE_TEXCOORD]);
  257.     glTexBufferRange(GL_TEXTURE_BUFFER, GL_RG32F, BufferName[BUFFER_TEXCOORD], TextureBufferOffsetAlignment, sizeof(texcoordBufferData));
  258.     glBindMultiTextureEXT(GL_TEXTURE2, GL_TEXTURE_BUFFER, TextureName[TEXTURE_TEXCOORD]);
  259.  
  260.  
  261.     unsigned char* image_buffer = new unsigned char[512*512*3];
  262.     FILE* image_file = fopen("box_texture.raw", "rb");
  263.     fread(image_buffer, 3, 512*512, image_file);
  264.     fclose(image_file);
  265.  
  266.     glTextureStorage2DEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, 10, GL_SRGB8, 512, 512);
  267.     glTextureSubImage2DEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, 0, 0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, image_buffer);
  268.     delete[] image_buffer;
  269.     glGenerateTextureMipmapEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D);
  270.     glBindMultiTextureEXT(GL_TEXTURE3, GL_TEXTURE_2D, TextureName[TEXTURE_DIFUSE]);
  271.  
  272.     glTextureParameteriEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  273.     glTextureParameteriEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  274.     glTextureParameteriEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  275.     glTextureParameteriEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  276.     GLfloat maxAniso = 1.0f;
  277.     glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
  278.     glTextureParameterfEXT(TextureName[TEXTURE_DIFUSE], GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso);
  279.  
  280.     GLuint shader_program = create_program(vertex_shader, fragment_shader);
  281.     glUseProgram(shader_program);
  282.  
  283.     glProgramUniform1i(shader_program, 0, 0);
  284.     glProgramUniform1i(shader_program, 1, 1);
  285.     glProgramUniform1i(shader_program, 2, 2);
  286.     glProgramUniform1i(shader_program, 3, 3);
  287.  
  288.     glEnable(GL_DEPTH_TEST);
  289.     glEnable(GL_FRAMEBUFFER_SRGB);
  290.     glEnable(GL_CULL_FACE);
  291.     glCullFace(GL_BACK);
  292.  
  293.     glm::mat4 view = glm::lookAt(
  294.         glm::vec3(0.0f, 2.0f, 6.0f),
  295.         glm::vec3(0.0f, 0.0f, 0.0f),
  296.         glm::vec3(0.0f, 1.0f, 0.0f)
  297.     );
  298.  
  299.     glm::mat4 proj = glm::perspective(45.0f, 1.0f, 0.2f, 10.0f);
  300.  
  301.     double lastTime = glfwGetTime();
  302.     int nbFrames = 0;
  303.  
  304.     while(!glfwWindowShouldClose(window))
  305.     {
  306.         double currentTime = glfwGetTime();
  307.         nbFrames++;
  308.         if (currentTime - lastTime >= 1.0)
  309.         {
  310.             char buff[128];
  311.             sprintf(buff, "OpenGL [%.1f fps, %.3f ms]", double(nbFrames), 1000.0 / double(nbFrames));
  312.             glfwSetWindowTitle(window, buff);
  313.             nbFrames = 0;
  314.             lastTime += 1.0;
  315.         }
  316.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  317.         glm::mat4 model = glm::rotate(glm::mat4(1.0f), (float)currentTime * 45.0f, glm::vec3(0, 1, 0));
  318.         glm::mat4 MVP = proj * view * model;
  319.         glProgramUniformMatrix4fv(shader_program, 4, 1, GL_FALSE, glm::value_ptr(MVP));
  320.         glDrawArrays(GL_TRIANGLES, 0, 36);
  321.         glfwSwapBuffers(window);
  322.         glfwPollEvents();
  323.     }
  324.  
  325.     glfwDestroyWindow(window);
  326.     glfwTerminate();
  327.     exit(EXIT_SUCCESS);
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement