test/test.cpp
c80e256d
 #ifdef GLSHADER_TEST
 
 
 #include <iostream>
 #include <iomanip>
 #include <stdexcept>
 
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
 
 #include "str.hpp"
e0fdd020
 #include "shader.hpp"
c80e256d
 
 
 static auto debugMessageDisable = false;
 
 
 // Only check the first line, the others are from the driver dependent OpenGL
 // info log.
 #define EXPECT_EXCEPTION(CODE, WHAT) \
     { \
         std::string what; \
         debugMessageDisable = true; \
         try { \
             CODE; \
         } catch (std::exception const & e) { \
             what = e.what(); \
             what = what.substr(0, what.find("\n")); \
         } \
         debugMessageDisable = false; \
         if (what.empty()) \
             throw std::runtime_error{STR( \
                 "Expected exception \"" << WHAT << "\", got none." \
             )}; \
         if (what != WHAT) \
             throw std::runtime_error{STR( \
                 "Expected exception \"" << WHAT << "\", got \"" << what \
                 << "\"." \
             )}; \
     }
 
 
 void test() {
e0fdd020
     EXPECT_EXCEPTION(
         Shader({ "bad_noextension" }),
         "Failed to infer shader type of 'bad_noextension' of shader program 'bad_noextension'; no file extension."
     )
     EXPECT_EXCEPTION(
         Shader({ "bad.unknownextension" }),
         "Failed to infer shader type of 'bad.unknownextension' of shader program 'bad.unknownextension'; unknown file extension 'unknownextension'."
     )
     EXPECT_EXCEPTION(
         Shader({ "bad_nonexistent.vert" }),
         "Failed to open vert shader 'bad_nonexistent.vert' of shader program 'bad_nonexistent.vert'."
     )
     EXPECT_EXCEPTION(
         Shader({ "bad_compile.vert" }),
         "Failed to compile vert shader 'bad_compile.vert' of shader program 'bad_compile.vert'."
         // "0:4(5): error: main() must return void"
         // "0:4(1): error: function `main' has non-void return type int, but no return statement"
     )
     EXPECT_EXCEPTION(
         Shader({ "bad_link.vert", "good.frag" }),
         "Failed to link shader program 'bad_link.vert', 'good.frag'."
         // "error: vertex shader does not write to `gl_Position'. "
     )
     {
         Shader shader{std::move(Shader({
             "good.vert",
             "good.frag",
         }))};
         shader.use();
         shader = Shader({
             "good.vert",
             "good.frag",
         });
         shader.use();
     }
     Shader shader({
         "good.vert",
         "good.frag",
     });
     shader.use();
     shader.validate();
c80e256d
 }
 
 
 void errorCallback(int /* error */, char const * description) {
     std::cerr << "GLFW ERROR: " << description << std::endl;
     exit(1);
 }
 
 
 void APIENTRY debugMessageCallback(
     GLenum /* source */,
     GLenum /* type */,
     GLuint /* id */,
     GLenum severity,
     GLsizei /* length */,
     const GLchar *message,
     const void * /* userParam */
 ) {
     if (debugMessageDisable)
         return;
     std::cerr << "GL DEBUG MESSAGE: " << message << std::endl;
     if (
         severity == GL_DEBUG_SEVERITY_HIGH ||
         severity == GL_DEBUG_SEVERITY_MEDIUM
     )
         exit(1);
 }
 
 
 int main() {
     try {
         glfwInit();
         glfwSetErrorCallback(errorCallback);
         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
         glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
         auto window = glfwCreateWindow(
             640, 480, "glshader test", nullptr, nullptr
         );
         glfwMakeContextCurrent(window);
         glfwSwapInterval(0);
 
         glewInit();
         #define GLSHADER_TEST_PRINT(NAME) \
             std::cout << std::setw(24+2) << std::left << #NAME ": " << \
                 glGetString(GL_##NAME) << std::endl;
         GLSHADER_TEST_PRINT(VENDOR);
         GLSHADER_TEST_PRINT(RENDERER);
         GLSHADER_TEST_PRINT(VERSION);
         GLSHADER_TEST_PRINT(SHADING_LANGUAGE_VERSION);
         glEnable(GL_DEBUG_OUTPUT);
         glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
         glDebugMessageControl(
             GL_DONT_CARE,
             GL_DONT_CARE,
             GL_DEBUG_SEVERITY_NOTIFICATION,
             0,
             nullptr,
             GL_FALSE
         );
         glDebugMessageCallback(debugMessageCallback, 0);
 
         std::cout << "---\n";
 
         int frame = 0;
         glfwSetTime(0);
         while (glfwGetTime() < 1) {
             ++frame;
             test();
 
             glBegin(GL_TRIANGLE_STRIP);
             glVertex3f(-0.5, -0.5, 0);
             glVertex3f(-0.5, +0.5, 0);
             glVertex3f(+0.5, +0.5, 0);
             glVertex3f(+0.5, -0.5, 0);
             glVertex3f(-0.5, -0.5, 0);
             glEnd();
 
             glfwSwapBuffers(window);
             glfwPollEvents();
         }
 
         std::cout << "---\n";
 
         std::cout << "Frames run: " << frame << "\n";
 
         glfwDestroyWindow(window);
         glfwTerminate();
     } catch (std::exception const & e) {
         std::cerr << e.what() << std::endl;
         return 1;
     }
 }
 
 
 #endif // GLSHADER_TEST