diff --git a/vis/CMakeLists.txt b/vis/CMakeLists.txt index 5de5d4f..9b9faae 100644 --- a/vis/CMakeLists.txt +++ b/vis/CMakeLists.txt @@ -1,3 +1,12 @@ add_executable(vis src/main.cpp) target_include_directories(vis PRIVATE include) target_link_libraries(vis PRIVATE tc glad glm glfw) + +add_custom_target(shaders ALL DEPENDS shader_output) +add_custom_command( + OUTPUT shader_output + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/shaders ${CMAKE_CURRENT_BINARY_DIR}/shaders + COMMENT "copied shaders" +) + +add_dependencies(vis shaders) diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 4cc51c7..c181f52 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -7,6 +7,7 @@ #include "geom.h" +#include #include #ifdef _WIN32 @@ -15,6 +16,30 @@ __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x000000 } #endif +void utilShaderSource(GLuint shader, const std::vector &sources) { + char const *ptrs[sources.size()]; + for (size_t i = 0; i < sources.size(); ++i) { + ptrs[i] = sources[i].c_str(); + } + glShaderSource(shader, sources.size(), ptrs, nullptr); +} + +std::string utilShaderInfoLog(GLuint shader) { + int len; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); + char buffer[len]; + glGetShaderInfoLog(shader, len, nullptr, buffer); + return std::string(buffer); +} + +std::string utilProgramInfoLog(GLuint program) { + int len; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); + char buffer[len]; + glGetProgramInfoLog(program, len, nullptr, buffer); + return std::string(buffer); +} + int main(int argc, char *argv[]) { if (!glfwInit()) { std::cerr << "Failed to initialize GLFW" << std::endl; @@ -71,8 +96,67 @@ int main(int argc, char *argv[]) { std::cout << " " << to_string(point) << std::endl; } + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + utilShaderSource(vs, { + "#version 430\n", + + "layout(location=0) uniform mat4 proj;" + "" + "void main() {" + " int i = gl_VertexID;" + " gl_Position = proj * vec4(i % 2, i / 2, 0, 1);" + "}" + }); + glCompileShader(vs); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + utilShaderSource(fs, { + "#version 430\n", + + "out vec4 color;" + "" + "void main() {" + " color = vec4(1);" + "}" + }); + + GLuint pgm = glCreateProgram(); + glAttachShader(pgm, vs); + glAttachShader(pgm, fs); + glLinkProgram(pgm); + + GLint status; + + glGetShaderiv(vs, GL_COMPILE_STATUS, &status); + if (!status) { + std::cerr << utilShaderInfoLog(vs) << "\n=========\n" << std::endl; + } + + glGetShaderiv(fs, GL_COMPILE_STATUS, &status); + if (!status) { + std::cerr << utilShaderInfoLog(fs) << "\n=========\n" << std::endl; + } + + glGetProgramiv(pgm, GL_LINK_STATUS, &status); + if (!status) { + std::cerr << utilProgramInfoLog(pgm) << "\n=========\n" << std::endl; + glfwTerminate(); + return EXIT_FAILURE; + } + + int width, height; + glfwGetFramebufferSize(window, &width, &height); + auto aspect = (float) width / (float) height; + + glm::mat4 proj = glm::ortho(-aspect, aspect, -1.f, 1.f); + while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(pgm); + glUniformMatrix4fv(0, 1, false, glm::value_ptr(proj)); + glDrawArrays(GL_TRIANGLES, 0, 3); + glfwSwapBuffers(window); glfwPollEvents();