Goddess of Justice DB, the database used for storage on IzaroDFS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
4.9 KiB

4 years ago
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <variant>
  5. #include <chrono>
  6. #include "commander.hpp"
  7. #include "nlohmann/json.hpp"
  8. #include <GL/glew.h>
  9. #define GLFW_DLL
  10. #include <GLFW/glfw3.h>
  11. std::variant<std::array<float,18>, std::vector<float>> points = std::array<float,18> {
  12. -1.0f, 1.0f, 0.0f,
  13. 1.0f, -1.0f, 0.0f,
  14. -1.0f, -1.0f, 0.0f,
  15. 1.0f, -1.0f, 0.0f,
  16. 1.0f, 1.0f, 0.0f,
  17. -1.0f, 1.0f, 0.0f
  18. };
  19. std::string check_shader(GLuint shader)
  20. {
  21. std::array<char,4096> text_buffer;
  22. GLsizei size;
  23. glGetShaderInfoLog(shader, text_buffer.size(),&size,text_buffer.data());
  24. return std::string{text_buffer.begin(), text_buffer.begin()+size};
  25. }
  26. std::string vertex_shader =
  27. "#version 400\n"
  28. "in vec3 vp;"
  29. "void main() {"
  30. " gl_Position = vec4(vp, 1.0);"
  31. "}";
  32. std::string fragment_shader =
  33. "#version 400\n"
  34. "out vec4 frag_colour;"
  35. "void main() {"
  36. " frag_colour = vec4(1.0, 0.0, 0.0, 1.0);"
  37. "}";
  38. std::pair<int,int> parse_resolution(const std::string& str)
  39. {
  40. auto x_it = std::find(str.begin(),str.end(),'x');
  41. auto x_str = std::string{str.begin(),x_it};
  42. auto y_str = std::string(x_it+1,str.end());
  43. return std::make_pair(std::stoi(x_str),std::stoi(y_str));
  44. }
  45. std::string slurp_file(const std::string& path)
  46. {
  47. std::ifstream input(path);
  48. std::stringstream sstr;
  49. while(input >> sstr.rdbuf());
  50. return sstr.str();
  51. }
  52. int main(int argc, char** argv)
  53. {
  54. // start GL context and O/S window using the GLFW helper library
  55. if (!glfwInit()) {
  56. std::cerr<<"ERROR: could not start GLFW3\n";
  57. return 1;
  58. }
  59. CMD::commander cli_args{argc,argv};
  60. auto res_str = cli_args.getFlagValue("-r");
  61. auto res = parse_resolution(res_str.empty()?"800x800":res_str);
  62. auto mesh_path = cli_args.getFlagValue("--mesh");
  63. if(!mesh_path.empty()) {
  64. auto mesh = nlohmann::json::parse(slurp_file(mesh_path));
  65. assert(mesh.is_array());
  66. points = std::vector<float>{mesh.begin(), mesh.end()};
  67. }
  68. auto vertshad_path = cli_args.getFlagValue("--vshader");
  69. if(!vertshad_path.empty()) {
  70. vertex_shader = slurp_file(vertshad_path);
  71. }
  72. auto fragshad_path = cli_args.getFlagValue("--fshader");
  73. if(!fragshad_path.empty()) {
  74. fragment_shader = slurp_file(fragshad_path);
  75. }
  76. // uncomment these lines if on Apple OS X
  77. /*glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  78. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  79. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  80. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);*/
  81. GLFWwindow* window = glfwCreateWindow(res.first, res.second, "sh_render", NULL, NULL);
  82. if (!window) {
  83. std::cerr<<"ERROR: could not open window with GLFW3\n";
  84. glfwTerminate();
  85. return 1;
  86. }
  87. glfwMakeContextCurrent(window);
  88. // start GLEW extension handler
  89. glewExperimental = GL_TRUE;
  90. glewInit();
  91. // get version info
  92. const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
  93. const GLubyte* version = glGetString(GL_VERSION); // version as a string
  94. std::cout <<"Renderer: "<<renderer<<"\n"
  95. <<"OpenGL version supported "<<version<<"\n";
  96. // tell GL to only draw onto a pixel if the shape is closer to the viewer
  97. glEnable(GL_DEPTH_TEST); // enable depth-testing
  98. glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
  99. {
  100. GLuint vbo = 0;
  101. glGenBuffers(1, &vbo);
  102. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  103. glBufferData(
  104. GL_ARRAY_BUFFER,
  105. std::visit([](auto& v)->size_t{return v.size();},points) * sizeof(float),
  106. std::visit([](auto& v)->float* {return (float*)v.data();},points),
  107. GL_STATIC_DRAW
  108. );
  109. auto num_triangles = std::visit([](auto& v)->size_t{return v.size();},points)/9;
  110. GLuint vao = 0;
  111. glGenVertexArrays(1, &vao);
  112. glBindVertexArray(vao);
  113. glEnableVertexAttribArray(0);
  114. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  115. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
  116. GLuint vs = glCreateShader(GL_VERTEX_SHADER);
  117. auto vsh = vertex_shader.data();
  118. glShaderSource(vs, 1, &vsh, NULL);
  119. glCompileShader(vs);
  120. std::cout<<"Vertex shader:"<<check_shader(vs)<<"\n";
  121. GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
  122. auto fsh = fragment_shader.data();
  123. glShaderSource(fs, 1, &fsh, NULL);
  124. glCompileShader(fs);
  125. std::cout<<"Fragment shader:"<<check_shader(fs)<<"\n";
  126. GLuint shader_programme = glCreateProgram();
  127. glAttachShader(shader_programme, fs);
  128. glAttachShader(shader_programme, vs);
  129. glLinkProgram(shader_programme);
  130. while(!glfwWindowShouldClose(window)) {
  131. // wipe the drawing surface clear
  132. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  133. glUseProgram(shader_programme);
  134. glBindVertexArray(vao);
  135. // draw points 0-4 from the currently bound VAO with current in-use shader
  136. for(size_t tri_it = 0; tri_it<num_triangles; tri_it++) {
  137. glDrawArrays(GL_TRIANGLES, tri_it*3, 3);
  138. }
  139. // update other events like input handling
  140. glfwPollEvents();
  141. // put the stuff we've been drawing onto the display
  142. glfwSwapBuffers(window);
  143. }
  144. }
  145. // close GL context and any other GLFW resources
  146. glfwTerminate();
  147. return 0;
  148. }