Goddess of Justice DB, the database used for storage on IzaroDFS
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

181 linhas
4.9 KiB

#include <iostream>
#include <fstream>
#include <sstream>
#include <variant>
#include <chrono>
#include "commander.hpp"
#include "nlohmann/json.hpp"
#include <GL/glew.h>
#define GLFW_DLL
#include <GLFW/glfw3.h>
std::variant<std::array<float,18>, std::vector<float>> points = std::array<float,18> {
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
std::string check_shader(GLuint shader)
{
std::array<char,4096> text_buffer;
GLsizei size;
glGetShaderInfoLog(shader, text_buffer.size(),&size,text_buffer.data());
return std::string{text_buffer.begin(), text_buffer.begin()+size};
}
std::string vertex_shader =
"#version 400\n"
"in vec3 vp;"
"void main() {"
" gl_Position = vec4(vp, 1.0);"
"}";
std::string fragment_shader =
"#version 400\n"
"out vec4 frag_colour;"
"void main() {"
" frag_colour = vec4(1.0, 0.0, 0.0, 1.0);"
"}";
std::pair<int,int> parse_resolution(const std::string& str)
{
auto x_it = std::find(str.begin(),str.end(),'x');
auto x_str = std::string{str.begin(),x_it};
auto y_str = std::string(x_it+1,str.end());
return std::make_pair(std::stoi(x_str),std::stoi(y_str));
}
std::string slurp_file(const std::string& path)
{
std::ifstream input(path);
std::stringstream sstr;
while(input >> sstr.rdbuf());
return sstr.str();
}
int main(int argc, char** argv)
{
// start GL context and O/S window using the GLFW helper library
if (!glfwInit()) {
std::cerr<<"ERROR: could not start GLFW3\n";
return 1;
}
CMD::commander cli_args{argc,argv};
auto res_str = cli_args.getFlagValue("-r");
auto res = parse_resolution(res_str.empty()?"800x800":res_str);
auto mesh_path = cli_args.getFlagValue("--mesh");
if(!mesh_path.empty()) {
auto mesh = nlohmann::json::parse(slurp_file(mesh_path));
assert(mesh.is_array());
points = std::vector<float>{mesh.begin(), mesh.end()};
}
auto vertshad_path = cli_args.getFlagValue("--vshader");
if(!vertshad_path.empty()) {
vertex_shader = slurp_file(vertshad_path);
}
auto fragshad_path = cli_args.getFlagValue("--fshader");
if(!fragshad_path.empty()) {
fragment_shader = slurp_file(fragshad_path);
}
// uncomment these lines if on Apple OS X
/*glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);*/
GLFWwindow* window = glfwCreateWindow(res.first, res.second, "sh_render", NULL, NULL);
if (!window) {
std::cerr<<"ERROR: could not open window with GLFW3\n";
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
const GLubyte* version = glGetString(GL_VERSION); // version as a string
std::cout <<"Renderer: "<<renderer<<"\n"
<<"OpenGL version supported "<<version<<"\n";
// tell GL to only draw onto a pixel if the shape is closer to the viewer
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
{
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(
GL_ARRAY_BUFFER,
std::visit([](auto& v)->size_t{return v.size();},points) * sizeof(float),
std::visit([](auto& v)->float* {return (float*)v.data();},points),
GL_STATIC_DRAW
);
auto num_triangles = std::visit([](auto& v)->size_t{return v.size();},points)/9;
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
auto vsh = vertex_shader.data();
glShaderSource(vs, 1, &vsh, NULL);
glCompileShader(vs);
std::cout<<"Vertex shader:"<<check_shader(vs)<<"\n";
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
auto fsh = fragment_shader.data();
glShaderSource(fs, 1, &fsh, NULL);
glCompileShader(fs);
std::cout<<"Fragment shader:"<<check_shader(fs)<<"\n";
GLuint shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
while(!glfwWindowShouldClose(window)) {
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_programme);
glBindVertexArray(vao);
// draw points 0-4 from the currently bound VAO with current in-use shader
for(size_t tri_it = 0; tri_it<num_triangles; tri_it++) {
glDrawArrays(GL_TRIANGLES, tri_it*3, 3);
}
// update other events like input handling
glfwPollEvents();
// put the stuff we've been drawing onto the display
glfwSwapBuffers(window);
}
}
// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}