diff --git a/modules/v4d/CMakeLists.txt b/modules/v4d/CMakeLists.txt index 9a8807163..0d6dc8e5c 100644 --- a/modules/v4d/CMakeLists.txt +++ b/modules/v4d/CMakeLists.txt @@ -13,7 +13,14 @@ macro(add_emscripten_sample sample source) opencv_v4d opencv_face opencv_tracking opencv_objdetect opencv_stitching opencv_optflow opencv_imgcodecs opencv_features2d opencv_dnn opencv_flann nanogui ${GLEW_LIBRARIES}) target_link_directories(${sample} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../lib") target_compile_features(${sample} PRIVATE cxx_std_20) - set_target_properties(${sample} PROPERTIES SUFFIX ".html") + set_target_properties(${sample} PROPERTIES SUFFIX ".js") + # configure_file("${CMAKE_CURRENT_LIST_DIR}/samples/${sample}.html" "${CMAKE_CURRENT_BINARY_DIR}/../../bin/${sample}.html" COPYONLY) + +add_custom_command( + TARGET ${sample} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_CURRENT_LIST_DIR}/samples/${sample}.html" + "${CMAKE_CURRENT_BINARY_DIR}/../../bin/${sample}.html") endmacro() macro(add_binary_sample sample) @@ -40,11 +47,8 @@ if (${idx} LESS 0) endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L../../lib/") -OCV_OPTION(OPENCV_V4D_ENABLE_ES "Enable OpenGL ES backend for V4D" OFF +OCV_OPTION(OPENCV_V4D_ENABLE_ES3 "Enable OpenGL ES 3.0 backend for V4D" OFF VERIFY HAVE_OPENGL) -OCV_OPTION(OPENCV_V4D_ES3 "Use OpenGL ES3 instead of ES2" OFF - VERIFY OPENCV_V4D_ENABLE_ES) - find_package(Git QUIET) if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../.git") @@ -118,8 +122,7 @@ endif() if(EMSCRIPTEN) set(NANOGUI_BUILD_SHARED OFF) - set(OPENCV_V4D_ENABLE_ES ON) - set(OPENCV_V4D_ES3 ON) + set(OPENCV_V4D_ENABLE_ES3 ON) else() set(NANOGUI_BUILD_SHARED ON) endif() @@ -127,14 +130,9 @@ set(NANOGUI_BUILD_PYTHON OFF) set(NANOGUI_BUILD_EXAMPLES OFF) set(NANOGUI_BACKEND "OpenGL" CACHE STRING "Choose the backend used for rendering (OpenGL/GLES 2/GLES 3/Metal)" FORCE) -if(OPENCV_V4D_ENABLE_ES) - if(OPENCV_V4D_ES3) +if(OPENCV_V4D_ENABLE_ES3) set(NANOGUI_BACKEND "GLES 3") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV_V4D_ES_VERSION=3") - else() - set(NANOGUI_BACKEND "GLES 2") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV_V4D_ES_VERSION=2") - endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV_V4D_USE_ES3=1") else() set(NANOGUI_BACKEND "OpenGL") endif() diff --git a/modules/v4d/include/opencv2/v4d/nvg.hpp b/modules/v4d/include/opencv2/v4d/nvg.hpp index bc4f84d62..bc4644c31 100644 --- a/modules/v4d/include/opencv2/v4d/nvg.hpp +++ b/modules/v4d/include/opencv2/v4d/nvg.hpp @@ -8,14 +8,14 @@ #include "v4d.hpp" -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 # ifndef NANOGUI_USE_OPENGL # define NANOGUI_USE_OPENGL # endif #else # ifndef NANOGUI_USE_GLES # define NANOGUI_USE_GLES -# define NANOGUI_GLES_VERSION OPENCV_V4D_ES_VERSION +# define NANOGUI_GLES_VERSION 3 # endif #endif #include diff --git a/modules/v4d/include/opencv2/v4d/util.hpp b/modules/v4d/include/opencv2/v4d/util.hpp index a3aa64190..30f8b1259 100644 --- a/modules/v4d/include/opencv2/v4d/util.hpp +++ b/modules/v4d/include/opencv2/v4d/util.hpp @@ -23,6 +23,8 @@ namespace cv { namespace viz { using std::string; class V4D; + +CV_EXPORTS unsigned int init_shader(const char* vShader, const char* fShader, const char* outputAttributeName); /*! * Returns the OpenGL Version information. * @return a string object with the OpenGL version information diff --git a/modules/v4d/include/opencv2/v4d/v4d.hpp b/modules/v4d/include/opencv2/v4d/v4d.hpp index 86c253270..87d04eea4 100644 --- a/modules/v4d/include/opencv2/v4d/v4d.hpp +++ b/modules/v4d/include/opencv2/v4d/v4d.hpp @@ -21,15 +21,11 @@ #include "cxxpool.hpp" -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 # include # define GLFW_INCLUDE_GLCOREARB #else -# if(OPENCV_V4D_ES_VERSION == 3) -# define GLFW_INCLUDE_ES3 -# else -# define GLFW_INCLUDE_ES2 -# endif +# define GLFW_INCLUDE_ES3 # define GLFW_INCLUDE_GLEXT #endif #include @@ -59,21 +55,6 @@ class FrameBufferContext; class CLVAContext; class NanoVGContext; -/*! - * Convenience function to check for OpenGL errors. Should only be used via the macro #GL_CHECK. - * @param file The file path of the error. - * @param line The file line of the error. - * @param expression The expression that failed. - */ -void gl_check_error(const std::filesystem::path& file, unsigned int line, const char* expression); - -/*! - * Convenience macro to check for OpenGL errors. - */ -#define GL_CHECK(expr) \ - expr; \ - cv::viz::gl_check_error(__FILE__, __LINE__, #expr); - /*! * The GFLW error callback. * @param error Error number @@ -104,6 +85,29 @@ template void find_widgets(nanogui::Widget* parent, std::vector& } } +/*! + * Convenience function to check for OpenGL errors. Should only be used via the macro #GL_CHECK. + * @param file The file path of the error. + * @param line The file line of the error. + * @param expression The expression that failed. + */ +static void gl_check_error(const std::filesystem::path& file, unsigned int line, const char* expression) { + int errorCode = glGetError(); + + if (errorCode != 0) { + std::cerr << "GL failed in " << file.filename() << " (" << line << ") : " + << "\nExpression:\n " << expression << "\nError code:\n " << errorCode + << "\n " << std::endl; + assert(false); + } +} +/*! + * Convenience macro to check for OpenGL errors. + */ +#define GL_CHECK(expr) \ + expr; \ + cv::viz::gl_check_error(__FILE__, __LINE__, #expr); + /*! * Convenience function to color convert from Scalar to Scalar * @param src The scalar to color convert @@ -183,7 +187,7 @@ public: */ CV_EXPORTS static cv::Ptr make(const cv::Size& initialSize, const cv::Size& frameBufferSize, bool offscreen, const string& title, int major = 3, - int minor = 2, bool compat = true, int samples = 0, bool debug = false); + int minor = 2, bool compat = false, int samples = 0, bool debug = false); /*! * Default destructor */ @@ -443,7 +447,7 @@ private: * @param debug Create a debug OpenGL context. */ CV_EXPORTS V4D(const cv::Size& initialSize, const cv::Size& frameBufferSize, bool offscreen, - const string& title, int major = 3, int minor = 2, bool compat = true, int samples = 0, bool debug = false); + const string& title, int major = 3, int minor = 2, bool compat = false, int samples = 0, bool debug = false); void setDefaultKeyboardEventCallback(); void setKeyboardEventCallback( std::function fn); diff --git a/modules/v4d/samples/cube-demo.cpp b/modules/v4d/samples/cube-demo.cpp index 54662cc28..932d17832 100644 --- a/modules/v4d/samples/cube-demo.cpp +++ b/modules/v4d/samples/cube-demo.cpp @@ -16,81 +16,23 @@ constexpr bool OFFSCREEN = false; constexpr const char* OUTPUT_FILENAME = "cube-demo.mkv"; const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT)); -const int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138), - 1); +const int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138), 1); using std::cerr; using std::endl; -cv::Ptr v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), - cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Cube Demo"); - -GLuint vbo_cube_vertices, vbo_cube_colors; -GLuint ibo_cube_elements; -GLuint program; -GLint attribute_coord3d, attribute_v_color; -GLint uniform_mvp; - -GLuint init_shader(const char* vShader, const char* fShader, const char* outputAttributeName) { - struct Shader { - GLenum type; - const char* source; - } shaders[2] = { { GL_VERTEX_SHADER, vShader }, { GL_FRAGMENT_SHADER, fShader } }; - - GLuint program = glCreateProgram(); - - for (int i = 0; i < 2; ++i) { - Shader& s = shaders[i]; - GLuint shader = glCreateShader(s.type); - glShaderSource(shader, 1, (const GLchar**) &s.source, NULL); - glCompileShader(shader); - - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - std::cerr << " failed to compile:" << std::endl; - GLint logSize; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); - char* logMsg = new char[logSize]; - glGetShaderInfoLog(shader, logSize, NULL, logMsg); - std::cerr << logMsg << std::endl; - delete[] logMsg; - - exit (EXIT_FAILURE); - } - - glAttachShader(program, shader); - } -#ifndef OPENCV_V4D_ES_VERSION - /* Link output */ - glBindFragDataLocation(program, 0, outputAttributeName); -#endif - /* link and error check */ - glLinkProgram(program); - - GLint linked; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) { - std::cerr << "Shader program failed to link" << std::endl; - GLint logSize; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); - char* logMsg = new char[logSize]; - glGetProgramInfoLog(program, logSize, NULL, logMsg); - std::cerr << logMsg << std::endl; - delete[] logMsg; - - exit (EXIT_FAILURE); - } +const unsigned int triangles = 12; +const unsigned int vertices_index = 0; +const unsigned int colors_index = 1; +unsigned int shader_program; +unsigned int vao; +unsigned int uniform_transform; - /* use program object */ - glUseProgram(program); +cv::Ptr v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), + OFFSCREEN, "Cube Demo"); - return program; -} - -//mandelbrot shader code adapted from my own project: https://github.com/kallaballa/FractalDive#after -void load_shader() { -#ifndef OPENCV_V4D_ES_VERSION +GLuint load_shader() { +#ifndef OPENCV_V4D_USE_ES3 const string shaderVersion = "330"; #else const string shaderVersion = "300 es"; @@ -100,15 +42,15 @@ void load_shader() { " #version " + shaderVersion + R"( precision lowp float; - layout(location = 0) in vec3 coord3d; - layout(location = 1) in vec3 v_color; + layout(location = 0) in vec3 pos; + layout(location = 1) in vec3 vertex_color; - uniform mat4 mvp; - out vec3 f_color; + uniform mat4 transform; - void main(void) { - gl_Position = mvp * vec4(coord3d, 1.0); - f_color = v_color; + out vec3 color; + void main() { + gl_Position = transform * vec4(pos, 1.0); + color = vertex_color; } )"; @@ -116,164 +58,111 @@ void load_shader() { " #version " + shaderVersion + R"( precision lowp float; - in vec3 f_color; - out vec4 fragColor; - - void main(void) { - fragColor = vec4(f_color.r, f_color.g, f_color.b, 1.0); + in vec3 color; + + out vec4 frag_color; + + void main() { + frag_color = vec4(color, 1.0); } )"; - cerr << "##### Cube Vertex Shader #####" << endl; - cerr << vert << endl; - cerr << "##### Cube Fragment Shader #####" << endl; - cerr << frag << endl; - - program = init_shader(vert.c_str(), frag.c_str(), "fragColor"); + return cv::viz::init_shader(vert.c_str(), frag.c_str(), "fragColor"); } -int init_resources() { - GLfloat cube_vertices[] = { - // front - -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, - // back - -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, }; - glGenBuffers(1, &vbo_cube_vertices); - glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); - - GLfloat cube_colors[] = { - // front colors - 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, - // back colors - 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, }; - glGenBuffers(1, &vbo_cube_colors); - glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_colors); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW); - - GLushort cube_elements[] = { - // front +void init_scene(const cv::Size& sz) { + glEnable (GL_DEPTH_TEST); + + float vertices[] = { + // Front face + 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, + + // Back face + 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, }; + + float vertex_colors[] = { 1.0, 0.4, 0.6, 1.0, 0.9, 0.2, 0.7, 0.3, 0.8, 0.5, 0.3, 1.0, + + 0.2, 0.6, 1.0, 0.6, 1.0, 0.4, 0.6, 0.8, 0.8, 0.4, 0.8, 0.8, }; + + unsigned short triangle_indices[] = { + // Front 0, 1, 2, 2, 3, 0, - // top + + // Right + 0, 3, 7, 7, 4, 0, + + // Bottom + 2, 6, 7, 7, 3, 2, + + // Left 1, 5, 6, 6, 2, 1, - // back - 7, 6, 5, 5, 4, 7, - // bottom - 4, 0, 3, 3, 7, 4, - // left - 4, 5, 1, 1, 0, 4, - // right - 3, 2, 6, 6, 7, 3, }; - glGenBuffers(1, &ibo_cube_elements); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW); - - GLint link_ok = GL_FALSE; - - GLuint vs, fs; - - load_shader(); - - const char* attribute_name; - attribute_name = "coord3d"; - attribute_coord3d = glGetAttribLocation(program, attribute_name); - if (attribute_coord3d == -1) { - fprintf(stderr, "Could not bind attribute %s\n", attribute_name); - return 0; - } - attribute_name = "v_color"; - attribute_v_color = glGetAttribLocation(program, attribute_name); - if (attribute_v_color == -1) { - fprintf(stderr, "Could not bind attribute %s\n", attribute_name); - return 0; - } - const char* uniform_name; - uniform_name = "mvp"; - uniform_mvp = glGetUniformLocation(program, uniform_name); - if (uniform_mvp == -1) { - fprintf(stderr, "Could not bind uniform %s\n", uniform_name); - return 0; - } - return 1; -} + // Back + 4, 7, 6, 6, 5, 4, -void init_scene(const cv::Size& sz) { - init_resources(); - glEnable (GL_BLEND); - glEnable (GL_DEPTH_TEST); -// glDepthFunc(GL_LESS); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Top + 5, 1, 0, 0, 4, 5, }; + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + unsigned int triangles_ebo; + glGenBuffers(1, &triangles_ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangles_ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof triangle_indices, triangle_indices, + GL_STATIC_DRAW); + + unsigned int verticies_vbo; + glGenBuffers(1, &verticies_vbo); + glBindBuffer(GL_ARRAY_BUFFER, verticies_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(vertices_index, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(vertices_index); + + unsigned int colors_vbo; + glGenBuffers(1, &colors_vbo); + glBindBuffer(GL_ARRAY_BUFFER, colors_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof vertex_colors, vertex_colors, GL_STATIC_DRAW); + + glVertexAttribPointer(colors_index, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(colors_index); + + // Unbind to prevent accidental modification + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + shader_program = load_shader(); + uniform_transform = glGetUniformLocation(shader_program, "transform"); } void render_scene(const cv::Size& sz) { - glClearColor(1.0, 1.0, 1.0, 1.0); + glClearColor(0.1, 0.12, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(program); + glUseProgram(shader_program); + float angle = fmod(double(cv::getTickCount()) / double(cv::getTickFrequency()), 2 * M_PI); float scale = 0.25; - cv::Matx44f rotXMat( - 1.0, 0.0, 0.0, 0.0, - 0.0, cos(angle), -sin(angle), 0.0, - 0.0, sin(angle), cos(angle), 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - - cv::Matx44f rotYMat( - cos(angle), 0.0, sin(angle), 0.0, - 0.0, 1.0, 0.0, 0.0, - -sin(angle), 0.0, cos(angle), 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - - cv::Matx44f rotZMat( - cos(angle), -sin(angle), 0.0, 0.0, - sin(angle), cos(angle), 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - - cv::Matx44f scaleMat( - scale, 0.0, 0.0, 0.0, - 0.0, scale, 0.0, 0.0, - 0.0, 0.0, scale, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - - cv::Matx44f trans = scaleMat * rotXMat * rotYMat * rotZMat; - glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, trans.val); - - glEnableVertexAttribArray(attribute_coord3d); - // Describe our vertices array to OpenGL (it can't guess its format automatically) - glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices); - glVertexAttribPointer(attribute_coord3d, // attribute - 3, // number of elements per vertex, here (x,y,z) - GL_FLOAT, // the type of each element - GL_FALSE, // take our values as-is - 0, // no extra data between each position - 0 // offset of first element - ); - - glEnableVertexAttribArray(attribute_v_color); - glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_colors); - glVertexAttribPointer(attribute_v_color, // attribute - 3, // number of elements per vertex, here (R,G,B) - GL_FLOAT, // the type of each element - GL_FALSE, // take our values as-is - 0, // no extra data between each position - 0 // offset of first element - ); - - /* Push each element in buffer_vertices to the vertex shader */ - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements); - int size; - glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0); - - glDisableVertexAttribArray(attribute_coord3d); - glDisableVertexAttribArray(attribute_v_color); + cv::Matx44f scaleMat(scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, + 0.0, 1.0); + + cv::Matx44f rotXMat(1.0, 0.0, 0.0, 0.0, 0.0, cos(angle), -sin(angle), 0.0, 0.0, sin(angle), + cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0); + + cv::Matx44f rotYMat(cos(angle), 0.0, sin(angle), 0.0, 0.0, 1.0, 0.0, 0.0, -sin(angle), 0.0, + cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0); + + cv::Matx44f rotZMat(cos(angle), -sin(angle), 0.0, 0.0, sin(angle), cos(angle), 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); + + cv::Matx44f transform = scaleMat * rotXMat * rotYMat * rotZMat; + glUniformMatrix4fv(uniform_transform, 1, GL_FALSE, transform.val); + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_SHORT, NULL); + } void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) { @@ -301,10 +190,10 @@ void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) { bool iteration() { using namespace cv::viz; + //Render using OpenGL v4d->gl(render_scene); - //If we have OpenCL and maybe even CL-GL sharing then this is faster than the glow shader. Without OpenCL this is very slow. #ifndef __EMSCRIPTEN__ //Aquire the frame buffer for use by OpenCL @@ -314,10 +203,10 @@ bool iteration() { }); #endif - v4d->write(); - updateFps(v4d, true); + v4d->write(); + //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. if (!v4d->display()) return false; diff --git a/modules/v4d/samples/shader-demo.cpp b/modules/v4d/samples/shader-demo.cpp index 76418e5aa..c303f5f6c 100644 --- a/modules/v4d/samples/shader-demo.cpp +++ b/modules/v4d/samples/shader-demo.cpp @@ -44,7 +44,7 @@ GLint zoom_hdl; /** shader and program handle **/ GLuint shader_program_hdl; -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 //vertex array GLuint VAO; #endif @@ -71,7 +71,7 @@ unsigned int indices[] = void load_buffer_data(){ -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); #endif @@ -89,7 +89,7 @@ void load_buffer_data(){ glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 glBindVertexArray(0); #endif } @@ -141,7 +141,7 @@ GLuint init_shader(const char* vShader, const char* fShader, const char* outputA glAttachShader( program, shader ); } -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 /* Link output */ glBindFragDataLocation(program, 0, outputAttributeName); #endif @@ -170,7 +170,7 @@ GLuint init_shader(const char* vShader, const char* fShader, const char* outputA //mandelbrot shader code adapted from my own project: https://github.com/kallaballa/FractalDive#after void load_shader(){ -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 const string shaderVersion = "330"; #else const string shaderVersion = "300 es"; @@ -293,7 +293,7 @@ void render_scene(const cv::Size& sz) { glUniform1f(zoom_hdl, zoom); } -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 glBindVertexArray(VAO); #endif glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); diff --git a/modules/v4d/samples/video-demo.cpp b/modules/v4d/samples/video-demo.cpp index a70230b6b..2ae642312 100644 --- a/modules/v4d/samples/video-demo.cpp +++ b/modules/v4d/samples/video-demo.cpp @@ -61,7 +61,7 @@ GLuint init_shader(const char* vShader, const char* fShader, const char* outputA glAttachShader(program, shader); } -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 /* Link output */ glBindFragDataLocation(program, 0, outputAttributeName); #endif @@ -90,7 +90,7 @@ GLuint init_shader(const char* vShader, const char* fShader, const char* outputA //mandelbrot shader code adapted from my own project: https://github.com/kallaballa/FractalDive#after void load_shader() { -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 const string shaderVersion = "330"; #else const string shaderVersion = "300 es"; diff --git a/modules/v4d/src/detail/framebuffercontext.cpp b/modules/v4d/src/detail/framebuffercontext.cpp index 0ecbbd454..6cb67c218 100644 --- a/modules/v4d/src/detail/framebuffercontext.cpp +++ b/modules/v4d/src/detail/framebuffercontext.cpp @@ -15,7 +15,7 @@ namespace detail { //FIXME use cv::ogl FrameBufferContext::FrameBufferContext(const cv::Size& frameBufferSize) : frameBufferSize_(frameBufferSize) { -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 glewExperimental = true; glewInit(); try { diff --git a/modules/v4d/src/detail/framebuffercontext.hpp b/modules/v4d/src/detail/framebuffercontext.hpp index b8997fe6b..e282b2e2d 100644 --- a/modules/v4d/src/detail/framebuffercontext.hpp +++ b/modules/v4d/src/detail/framebuffercontext.hpp @@ -17,15 +17,11 @@ # endif #endif -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 # include # define GLFW_INCLUDE_GLCOREARB #else -# if(OPENCV_V4D_ES_VERSION == 3) -# define GLFW_INCLUDE_ES3 -# else -# define GLFW_INCLUDE_ES2 -# endif +# define GLFW_INCLUDE_ES3 # define GLFW_INCLUDE_GLEXT #endif diff --git a/modules/v4d/src/detail/nanovgcontext.cpp b/modules/v4d/src/detail/nanovgcontext.cpp index 62e8d0390..e5270d013 100644 --- a/modules/v4d/src/detail/nanovgcontext.cpp +++ b/modules/v4d/src/detail/nanovgcontext.cpp @@ -26,34 +26,8 @@ void NanoVGContext::render(std::function fn) { cv::viz::nvg::detail::NVG::initializeContext(context_), fn(clglContext_.getSize()); } -void push() { -#ifndef OPENCV_V4D_ES_VERSION - GL_CHECK(glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS)); - GL_CHECK(glPushAttrib(GL_ALL_ATTRIB_BITS)); - GL_CHECK(glMatrixMode(GL_MODELVIEW)); - GL_CHECK(glPushMatrix()); - GL_CHECK(glMatrixMode(GL_PROJECTION)); - GL_CHECK(glPushMatrix()); - GL_CHECK(glMatrixMode(GL_TEXTURE)); - GL_CHECK(glPushMatrix()); -#endif -} - -void pop() { -#ifndef OPENCV_V4D_ES_VERSION - GL_CHECK(glMatrixMode(GL_TEXTURE)); - GL_CHECK(glPopMatrix()); - GL_CHECK(glMatrixMode(GL_PROJECTION)); - GL_CHECK(glPopMatrix()); - GL_CHECK(glMatrixMode(GL_MODELVIEW)); - GL_CHECK(glPopMatrix()); - GL_CHECK(glPopClientAttrib()); - GL_CHECK(glPopAttrib()); -#endif -} - void NanoVGContext::begin() { - push(); +// push(); float w = v4d_.getFrameBufferSize().width; float h = v4d_.getFrameBufferSize().height; float r = v4d_.getXPixelRatio(); @@ -70,7 +44,7 @@ void NanoVGContext::end() { //FIXME make nvgCancelFrame possible nvgEndFrame(context_); nvgRestore(context_); - pop(); +// pop(); } } } diff --git a/modules/v4d/src/detail/nanovgcontext.hpp b/modules/v4d/src/detail/nanovgcontext.hpp index 1620ffd87..32e900a56 100644 --- a/modules/v4d/src/detail/nanovgcontext.hpp +++ b/modules/v4d/src/detail/nanovgcontext.hpp @@ -13,11 +13,11 @@ #include #endif -#ifndef OPENCV_V4D_ES_VERSION +#ifndef OPENCV_V4D_USE_ES3 #define NANOGUI_USE_OPENGL #else #define NANOGUI_USE_GLES -#define NANOGUI_GLES_VERSION OPENCV_V4D_ES_VERSION +#define NANOGUI_GLES_VERSION 3 #endif #include diff --git a/modules/v4d/src/util.cpp b/modules/v4d/src/util.cpp index 655115296..92fe180de 100644 --- a/modules/v4d/src/util.cpp +++ b/modules/v4d/src/util.cpp @@ -19,6 +19,63 @@ namespace cv { namespace viz { +unsigned int init_shader(const char* vShader, const char* fShader, const char* outputAttributeName) { + struct Shader { + GLenum type; + const char* source; + } shaders[2] = { { GL_VERTEX_SHADER, vShader }, { GL_FRAGMENT_SHADER, fShader } }; + + GLuint program = glCreateProgram(); + + for (int i = 0; i < 2; ++i) { + Shader& s = shaders[i]; + GLuint shader = glCreateShader(s.type); + glShaderSource(shader, 1, (const GLchar**) &s.source, NULL); + glCompileShader(shader); + + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + std::cerr << " failed to compile:" << std::endl; + GLint logSize; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); + char* logMsg = new char[logSize]; + glGetShaderInfoLog(shader, logSize, NULL, logMsg); + std::cerr << logMsg << std::endl; + delete[] logMsg; + + exit (EXIT_FAILURE); + } + + glAttachShader(program, shader); + } +#ifndef OPENCV_V4D_USE_ES3 + /* Link output */ + glBindFragDataLocation(program, 0, outputAttributeName); +#endif + /* link and error check */ + glLinkProgram(program); + + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) { + std::cerr << "Shader program failed to link" << std::endl; + GLint logSize; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); + char* logMsg = new char[logSize]; + glGetProgramInfoLog(program, logSize, NULL, logMsg); + std::cerr << logMsg << std::endl; + delete[] logMsg; + + exit (EXIT_FAILURE); + } + + /* use program object */ + glUseProgram(program); + + return program; +} + std::string getGlInfo() { return reinterpret_cast(glGetString(GL_VERSION)); } diff --git a/modules/v4d/src/v4d.cpp b/modules/v4d/src/v4d.cpp index a40eeaf9f..5a6388130 100644 --- a/modules/v4d/src/v4d.cpp +++ b/modules/v4d/src/v4d.cpp @@ -11,16 +11,6 @@ namespace cv { namespace viz { namespace detail { -void gl_check_error(const std::filesystem::path& file, unsigned int line, const char* expression) { - int errorCode = glGetError(); - - if (errorCode != 0) { - std::cerr << "GL failed in " << file.filename() << " (" << line << ") : " - << "\nExpression:\n " << expression << "\nError code:\n " << errorCode - << "\n " << std::endl; - assert(false); - } -} void glfw_error_callback(int error, const char* description) { fprintf(stderr, "GLFW Error: %s\n", description); @@ -122,8 +112,8 @@ bool V4D::initializeWindowing() { glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - #elif defined(OPENCV_V4D_ES_VERSION) - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OPENCV_V4D_ES_VERSION); + #elif defined(OPENCV_V4D_USE_ES3) + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);