Basic Web support

This commit is contained in:
Pasalc 2023-12-06 19:47:42 +03:00
parent abfb667d0f
commit 203487938c
20 changed files with 2456 additions and 38 deletions

View File

@ -0,0 +1,39 @@
# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
#
# This file is the CEF CMake configuration entry point and should be loaded
# using `find_package(CEF REQUIRED)`. See the top-level CMakeLists.txt file
# included with the CEF binary distribution for usage information.
#
# Find the CEF binary distribution root directory.
set(_CEF_ROOT "")
if(CEF_ROOT AND IS_DIRECTORY "${CEF_ROOT}")
set(_CEF_ROOT "${CEF_ROOT}")
set(_CEF_ROOT_EXPLICIT 1)
else()
set(_ENV_CEF_ROOT "")
if(DEFINED ENV{CEF_ROOT})
file(TO_CMAKE_PATH "$ENV{CEF_ROOT}" _ENV_CEF_ROOT)
endif()
if(_ENV_CEF_ROOT AND IS_DIRECTORY "${_ENV_CEF_ROOT}")
set(_CEF_ROOT "${_ENV_CEF_ROOT}")
set(_CEF_ROOT_EXPLICIT 1)
endif()
unset(_ENV_CEF_ROOT)
endif()
if(NOT DEFINED _CEF_ROOT_EXPLICIT)
message(FATAL_ERROR "Must specify a CEF_ROOT value via CMake or environment variable.")
endif()
if(NOT IS_DIRECTORY "${_CEF_ROOT}/cmake")
message(FATAL_ERROR "No CMake bootstrap found for CEF binary distribution at: ${CEF_ROOT}.")
endif()
# Execute additional cmake files from the CEF binary distribution.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${_CEF_ROOT}/cmake")
include("cef_variables")
include("cef_macros")

View File

@ -0,0 +1,387 @@
# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
# Must be loaded via FindCEF.cmake.
if(NOT DEFINED _CEF_ROOT_EXPLICIT)
message(FATAL_ERROR "Use find_package(CEF) to load this file.")
endif()
#
# Shared macros.
#
# Print the current CEF configuration.
macro(PRINT_CEF_CONFIG)
message(STATUS "*** CEF CONFIGURATION SETTINGS ***")
message(STATUS "Generator: ${CMAKE_GENERATOR}")
message(STATUS "Platform: ${CMAKE_SYSTEM_NAME}")
message(STATUS "Project architecture: ${PROJECT_ARCH}")
if(GEN_NINJA OR GEN_MAKEFILES)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
endif()
message(STATUS "Binary distribution root: ${_CEF_ROOT}")
if(OS_MAC)
message(STATUS "Base SDK: ${CMAKE_OSX_SYSROOT}")
message(STATUS "Target SDK: ${CEF_TARGET_SDK}")
endif()
if(OS_WINDOWS)
message(STATUS "Visual Studio ATL support: ${USE_ATL}")
endif()
message(STATUS "CEF sandbox: ${USE_SANDBOX}")
set(_libraries ${CEF_STANDARD_LIBS})
if(OS_WINDOWS AND USE_SANDBOX)
list(APPEND _libraries ${CEF_SANDBOX_STANDARD_LIBS})
endif()
message(STATUS "Standard libraries: ${_libraries}")
message(STATUS "Compile defines: ${CEF_COMPILER_DEFINES}")
message(STATUS "Compile defines (Debug): ${CEF_COMPILER_DEFINES_DEBUG}")
message(STATUS "Compile defines (Release): ${CEF_COMPILER_DEFINES_RELEASE}")
message(STATUS "C compile flags: ${CEF_COMPILER_FLAGS} ${CEF_C_COMPILER_FLAGS}")
message(STATUS "C compile flags (Debug): ${CEF_COMPILER_FLAGS_DEBUG} ${CEF_C_COMPILER_FLAGS_DEBUG}")
message(STATUS "C compile flags (Release): ${CEF_COMPILER_FLAGS_RELEASE} ${CEF_C_COMPILER_FLAGS_RELEASE}")
message(STATUS "C++ compile flags: ${CEF_COMPILER_FLAGS} ${CEF_CXX_COMPILER_FLAGS}")
message(STATUS "C++ compile flags (Debug): ${CEF_COMPILER_FLAGS_DEBUG} ${CEF_CXX_COMPILER_FLAGS_DEBUG}")
message(STATUS "C++ compile flags (Release): ${CEF_COMPILER_FLAGS_RELEASE} ${CEF_CXX_COMPILER_FLAGS_RELEASE}")
message(STATUS "Exe link flags: ${CEF_LINKER_FLAGS} ${CEF_EXE_LINKER_FLAGS}")
message(STATUS "Exe link flags (Debug): ${CEF_LINKER_FLAGS_DEBUG} ${CEF_EXE_LINKER_FLAGS_DEBUG}")
message(STATUS "Exe link flags (Release): ${CEF_LINKER_FLAGS_RELEASE} ${CEF_EXE_LINKER_FLAGS_RELEASE}")
message(STATUS "Shared link flags: ${CEF_LINKER_FLAGS} ${CEF_SHARED_LINKER_FLAGS}")
message(STATUS "Shared link flags (Debug): ${CEF_LINKER_FLAGS_DEBUG} ${CEF_SHARED_LINKER_FLAGS_DEBUG}")
message(STATUS "Shared link flags (Release): ${CEF_LINKER_FLAGS_RELEASE} ${CEF_SHARED_LINKER_FLAGS_RELEASE}")
if(OS_LINUX OR OS_WINDOWS)
message(STATUS "CEF Binary files: ${CEF_BINARY_FILES}")
message(STATUS "CEF Resource files: ${CEF_RESOURCE_FILES}")
endif()
endmacro()
# Append platform specific sources to a list of sources.
macro(APPEND_PLATFORM_SOURCES name_of_list)
if(OS_LINUX AND ${name_of_list}_LINUX)
list(APPEND ${name_of_list} ${${name_of_list}_LINUX})
endif()
if(OS_POSIX AND ${name_of_list}_POSIX)
list(APPEND ${name_of_list} ${${name_of_list}_POSIX})
endif()
if(OS_WINDOWS AND ${name_of_list}_WINDOWS)
list(APPEND ${name_of_list} ${${name_of_list}_WINDOWS})
endif()
if(OS_MAC AND ${name_of_list}_MAC)
list(APPEND ${name_of_list} ${${name_of_list}_MAC})
endif()
endmacro()
# Determine the target output directory based on platform and generator.
macro(SET_CEF_TARGET_OUT_DIR)
if(GEN_NINJA OR GEN_MAKEFILES)
# By default Ninja and Make builds don't create a subdirectory named after
# the configuration.
set(CEF_TARGET_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
# Output binaries (executables, libraries) to the correct directory.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
else()
set(CEF_TARGET_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
endif()
endmacro()
# Copy a list of files from one directory to another. Relative file paths are maintained.
macro(COPY_FILES target file_list source_dir target_dir)
foreach(FILENAME ${file_list})
set(source_file ${source_dir}/${FILENAME})
# Remove the target file path component.
get_filename_component(target_name ${FILENAME} NAME)
set(target_file ${target_dir}/${target_name})
COPY_SINGLE_FILE(${target} ${source_file} ${target_file})
endforeach()
endmacro()
# Copy a list of files from one directory to another. Relative file paths are maintained.
macro(COPY_RESOURCES target file_list prefix_list source_dir target_dir)
foreach(FILENAME ${file_list})
set(source_file ${source_dir}/${FILENAME})
# Remove one or more prefixes from the source paths.
set(TARGET_FILENAME "${FILENAME}")
foreach(PREFIX ${prefix_list})
string(REGEX REPLACE "^.*${PREFIX}" "" TARGET_FILENAME ${TARGET_FILENAME})
endforeach()
set(target_file ${target_dir}/${TARGET_FILENAME})
COPY_SINGLE_FILE(${target} ${source_file} ${target_file})
endforeach()
endmacro()
macro(COPY_SINGLE_FILE target source_file target_file)
string(FIND ${source_file} "$<CONFIGURATION>" _pos)
if(NOT ${_pos} EQUAL -1)
# Must test with an actual configuration directory.
string(REPLACE "$<CONFIGURATION>" "Release" existing_source_file ${source_file})
if(NOT EXISTS ${existing_source_file})
string(REPLACE "$<CONFIGURATION>" "Debug" existing_source_file ${source_file})
endif()
else()
set(existing_source_file ${source_file})
endif()
if(IS_DIRECTORY ${existing_source_file})
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory "${source_file}" "${target_file}"
VERBATIM
)
else()
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source_file}" "${target_file}"
VERBATIM
)
endif()
endmacro()
#
# Linux macros.
#
if(OS_LINUX)
# Use pkg-config to find Linux libraries and update compiler/linker variables.
macro(FIND_LINUX_LIBRARIES libraries)
# Read pkg-config info into variables.
execute_process(COMMAND pkg-config --cflags ${libraries} OUTPUT_VARIABLE FLL_CFLAGS)
execute_process(COMMAND pkg-config --libs-only-L --libs-only-other ${libraries} OUTPUT_VARIABLE FLL_LDFLAGS)
execute_process(COMMAND pkg-config --libs-only-l ${libraries} OUTPUT_VARIABLE FLL_LIBS)
# Strip leading and trailing whitepspace.
STRING(STRIP "${FLL_CFLAGS}" FLL_CFLAGS)
STRING(STRIP "${FLL_LDFLAGS}" FLL_LDFLAGS)
STRING(STRIP "${FLL_LIBS}" FLL_LIBS)
# Convert to a list.
separate_arguments(FLL_CFLAGS)
separate_arguments(FLL_LDFLAGS)
separate_arguments(FLL_LIBS)
# Update build variables.
list(APPEND CEF_C_COMPILER_FLAGS ${FLL_CFLAGS})
list(APPEND CEF_CXX_COMPILER_FLAGS ${FLL_CFLAGS})
list(APPEND CEF_EXE_LINKER_FLAGS ${FLL_LDFLAGS})
list(APPEND CEF_SHARED_LINKER_FLAGS ${FLL_LDFLAGS})
list(APPEND CEF_STANDARD_LIBS ${FLL_LIBS})
endmacro()
# Set SUID permissions on the specified executable.
macro(SET_LINUX_SUID_PERMISSIONS target executable)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo ""
COMMAND ${CMAKE_COMMAND} -E echo "*** Run the following command manually to set SUID permissions ***"
COMMAND ${CMAKE_COMMAND} -E echo "EXE=\"${executable}\" && sudo -- chown root:root $EXE && sudo -- chmod 4755 $EXE"
COMMAND ${CMAKE_COMMAND} -E echo ""
VERBATIM
)
endmacro()
endif(OS_LINUX)
#
# Mac OS X macros.
#
if(OS_MAC)
# Manually process and copy over resource files.
macro(COPY_MAC_RESOURCES resource_list prefix_list target source_dir app_path)
foreach(FILENAME ${resource_list})
# Remove one or more prefixes from the source paths.
set(TARGET_FILENAME "${FILENAME}")
foreach(PREFIX ${prefix_list})
string(REGEX REPLACE "^.*${PREFIX}" "" TARGET_FILENAME ${TARGET_FILENAME})
endforeach()
# Determine the absolute source and target paths.
set(TARGET_PATH "${app_path}/Contents/Resources/${TARGET_FILENAME}")
if(IS_ABSOLUTE ${FILENAME})
set(SOURCE_PATH ${FILENAME})
else()
set(SOURCE_PATH "${source_dir}/${FILENAME}")
endif()
if(${FILENAME} MATCHES ".xib$")
# Change the target file extension.
string(REGEX REPLACE ".xib$" ".nib" TARGET_PATH ${TARGET_PATH})
get_filename_component(TARGET_DIRECTORY ${TARGET_PATH} PATH)
add_custom_command(
TARGET ${target}
POST_BUILD
# Create the target directory.
COMMAND ${CMAKE_COMMAND} -E make_directory "${TARGET_DIRECTORY}"
# Compile the XIB file to a NIB.
COMMAND /usr/bin/ibtool --output-format binary1 --compile "${TARGET_PATH}" "${SOURCE_PATH}"
VERBATIM
)
elseif(NOT ${TARGET_FILENAME} STREQUAL "Info.plist")
# Copy the file as-is.
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${TARGET_PATH}"
VERBATIM
)
endif()
endforeach()
endmacro()
endif(OS_MAC)
#
# Windows macros.
#
if(OS_WINDOWS)
# Add custom manifest files to an executable target.
macro(ADD_WINDOWS_MANIFEST manifest_path target extension)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND "mt.exe" -nologo
-manifest \"${manifest_path}/${target}.${extension}.manifest\" \"${manifest_path}/compatibility.manifest\"
-outputresource:"${CEF_TARGET_OUT_DIR}/${target}.${extension}"\;\#1
COMMENT "Adding manifest..."
)
endmacro()
endif(OS_WINDOWS)
#
# Target configuration macros.
#
# Add a logical target that can be used to link the specified libraries into an
# executable target.
macro(ADD_LOGICAL_TARGET target debug_lib release_lib)
add_library(${target} ${CEF_LIBTYPE} IMPORTED)
set_target_properties(${target} PROPERTIES
IMPORTED_LOCATION "${release_lib}"
IMPORTED_LOCATION_DEBUG "${debug_lib}"
IMPORTED_LOCATION_RELEASE "${release_lib}"
)
endmacro()
# Set common target properties. Use SET_LIBRARY_TARGET_PROPERTIES() or
# SET_EXECUTABLE_TARGET_PROPERTIES() instead of calling this macro directly.
macro(SET_COMMON_TARGET_PROPERTIES target)
# Compile flags.
target_compile_options(${target} PRIVATE ${CEF_COMPILER_FLAGS} ${CEF_CXX_COMPILER_FLAGS})
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:${CEF_COMPILER_FLAGS_DEBUG} ${CEF_CXX_COMPILER_FLAGS_DEBUG}>)
target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:${CEF_COMPILER_FLAGS_RELEASE} ${CEF_CXX_COMPILER_FLAGS_RELEASE}>)
# Compile definitions.
target_compile_definitions(${target} PRIVATE ${CEF_COMPILER_DEFINES})
target_compile_definitions(${target} PRIVATE $<$<CONFIG:Debug>:${CEF_COMPILER_DEFINES_DEBUG}>)
target_compile_definitions(${target} PRIVATE $<$<CONFIG:Release>:${CEF_COMPILER_DEFINES_RELEASE}>)
# Include directories.
target_include_directories(${target} PRIVATE ${CEF_INCLUDE_PATH})
# Linker flags.
if(CEF_LINKER_FLAGS)
string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
endif()
if(CEF_LINKER_FLAGS_DEBUG)
string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS_DEBUG}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
endif()
if(CEF_LINKER_FLAGS_RELEASE)
string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS_RELEASE}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
endif()
if(OS_MAC)
# Set Xcode target properties.
set_target_properties(${target} PROPERTIES
XCODE_ATTRIBUTE_ALWAYS_SEARCH_USER_PATHS NO
XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "gnu++11" # -std=gnu++11
XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME NO # -fno-objc-link-runtime
XCODE_ATTRIBUTE_CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS YES # -Wobjc-missing-property-synthesis
XCODE_ATTRIBUTE_COPY_PHASE_STRIP NO
XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release] YES # -Wl,-dead_strip
XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD "c99" # -std=c99
XCODE_ATTRIBUTE_GCC_CW_ASM_SYNTAX NO # No -fasm-blocks
XCODE_ATTRIBUTE_GCC_DYNAMIC_NO_PIC NO
XCODE_ATTRIBUTE_GCC_ENABLE_CPP_EXCEPTIONS NO # -fno-exceptions
XCODE_ATTRIBUTE_GCC_ENABLE_CPP_RTTI NO # -fno-rtti
XCODE_ATTRIBUTE_GCC_ENABLE_PASCAL_STRINGS NO # No -mpascal-strings
XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN YES # -fvisibility-inlines-hidden
XCODE_ATTRIBUTE_GCC_OBJC_CALL_CXX_CDTORS YES # -fobjc-call-cxx-cdtors
XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN YES # -fvisibility=hidden
XCODE_ATTRIBUTE_GCC_THREADSAFE_STATICS NO # -fno-threadsafe-statics
XCODE_ATTRIBUTE_GCC_TREAT_WARNINGS_AS_ERRORS YES # -Werror
XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0"
XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE YES # -Wnewline-eof
XCODE_ATTRIBUTE_USE_HEADERMAP NO
OSX_ARCHITECTURES_DEBUG "${CMAKE_OSX_ARCHITECTURES}"
OSX_ARCHITECTURES_RELEASE "${CMAKE_OSX_ARCHITECTURES}"
)
endif()
endmacro()
# Set library-specific properties.
macro(SET_LIBRARY_TARGET_PROPERTIES target)
SET_COMMON_TARGET_PROPERTIES(${target})
# Shared library linker flags.
if(CEF_SHARED_LINKER_FLAGS)
string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
endif()
if(CEF_SHARED_LINKER_FLAGS_DEBUG)
string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS_DEBUG}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
endif()
if(CEF_SHARED_LINKER_FLAGS_RELEASE)
string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS_RELEASE}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
endif()
endmacro()
# Set executable-specific properties.
macro(SET_EXECUTABLE_TARGET_PROPERTIES target)
SET_COMMON_TARGET_PROPERTIES(${target})
# Executable linker flags.
if(CEF_EXE_LINKER_FLAGS)
string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
endif()
if(CEF_EXE_LINKER_FLAGS_DEBUG)
string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS_DEBUG}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
endif()
if(CEF_EXE_LINKER_FLAGS_RELEASE)
string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS_RELEASE}")
set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
endif()
endmacro()

View File

@ -0,0 +1,582 @@
# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
# Must be loaded via FindCEF.cmake.
if(NOT DEFINED _CEF_ROOT_EXPLICIT)
message(FATAL_ERROR "Use find_package(CEF) to load this file.")
endif()
#
# Shared configuration.
#
# Determine the platform.
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(OS_MAC 1)
set(OS_MACOSX 1) # For backwards compatibility.
set(OS_POSIX 1)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(OS_LINUX 1)
set(OS_POSIX 1)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
set(OS_WINDOWS 1)
endif()
# Determine the project architecture.
if(NOT DEFINED PROJECT_ARCH)
if(("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") OR
("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM64"))
set(PROJECT_ARCH "arm64")
elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
set(PROJECT_ARCH "x86_64")
else()
set(PROJECT_ARCH "x86")
endif()
endif()
if(${CMAKE_GENERATOR} STREQUAL "Ninja")
set(GEN_NINJA 1)
elseif(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
set(GEN_MAKEFILES 1)
endif()
# Determine the build type.
if(NOT CMAKE_BUILD_TYPE AND (GEN_NINJA OR GEN_MAKEFILES))
# CMAKE_BUILD_TYPE should be specified when using Ninja or Unix Makefiles.
set(CMAKE_BUILD_TYPE Release)
message(WARNING "No CMAKE_BUILD_TYPE value selected, using ${CMAKE_BUILD_TYPE}")
endif()
# Path to the include directory.
set(CEF_INCLUDE_PATH "${_CEF_ROOT}")
# Path to the libcef_dll_wrapper target.
set(CEF_LIBCEF_DLL_WRAPPER_PATH "${_CEF_ROOT}/libcef_dll")
# Shared compiler/linker flags.
list(APPEND CEF_COMPILER_DEFINES
# Allow C++ programs to use stdint.h macros specified in the C99 standard that aren't
# in the C++ standard (e.g. UINT8_MAX, INT64_MIN, etc)
__STDC_CONSTANT_MACROS __STDC_FORMAT_MACROS
)
# Configure use of the sandbox.
option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
#
# Linux configuration.
#
if(OS_LINUX)
# Platform-specific compiler/linker flags.
set(CEF_LIBTYPE SHARED)
list(APPEND CEF_COMPILER_FLAGS
-fno-strict-aliasing # Avoid assumptions regarding non-aliasing of objects of different types
-fPIC # Generate position-independent code for shared libraries
-fstack-protector # Protect some vulnerable functions from stack-smashing (security feature)
-funwind-tables # Support stack unwinding for backtrace()
-fvisibility=hidden # Give hidden visibility to declarations that are not explicitly marked as visible
--param=ssp-buffer-size=4 # Set the minimum buffer size protected by SSP (security feature, related to stack-protector)
-pipe # Use pipes rather than temporary files for communication between build stages
-pthread # Use the pthread library
# -Wall # Enable all warnings
# -Werror # Treat warnings as errors
# -Wno-missing-field-initializers # Don't warn about missing field initializers
# -Wno-unused-parameter # Don't warn about unused parameters
# -Wno-error=comment # Don't warn about code in comments
# -Wno-comment # Don't warn about code in comments
# -Wno-deprecated-declarations # Don't warn about using deprecated methods
)
list(APPEND CEF_C_COMPILER_FLAGS
-std=c99 # Use the C99 language standard
)
list(APPEND CEF_CXX_COMPILER_FLAGS
# -fno-exceptions # Disable exceptions
-fno-rtti # Disable real-time type information
-fno-threadsafe-statics # Don't generate thread-safe statics
-fvisibility-inlines-hidden # Give hidden visibility to inlined class member functions
-std=c++17 # Use the C++17 language standard
-Wsign-compare # Warn about mixed signed/unsigned type comparisons
)
list(APPEND CEF_COMPILER_FLAGS_DEBUG
-O0 # Disable optimizations
-g # Generate debug information
)
list(APPEND CEF_COMPILER_FLAGS_RELEASE
-O2 # Optimize for maximum speed
-fdata-sections # Enable linker optimizations to improve locality of reference for data sections
-ffunction-sections # Enable linker optimizations to improve locality of reference for function sections
-fno-ident # Ignore the #ident directive
-U_FORTIFY_SOURCE # Undefine _FORTIFY_SOURCE in case it was previously defined
-D_FORTIFY_SOURCE=2 # Add memory and string function protection (security feature, related to stack-protector)
)
list(APPEND CEF_LINKER_FLAGS
-fPIC # Generate position-independent code for shared libraries
-pthread # Use the pthread library
-Wl,--disable-new-dtags # Don't generate new-style dynamic tags in ELF
-Wl,--fatal-warnings # Treat warnings as errors
-Wl,-rpath,. # Set rpath so that libraries can be placed next to the executable
-Wl,-z,noexecstack # Mark the stack as non-executable (security feature)
-Wl,-z,now # Resolve symbols on program start instead of on first use (security feature)
-Wl,-z,relro # Mark relocation sections as read-only (security feature)
)
list(APPEND CEF_LINKER_FLAGS_RELEASE
-Wl,-O1 # Enable linker optimizations
-Wl,--as-needed # Only link libraries that export symbols used by the binary
-Wl,--gc-sections # Remove unused code resulting from -fdata-sections and -function-sections
)
list(APPEND CEF_COMPILER_DEFINES
_FILE_OFFSET_BITS=64 # Allow the Large File Support (LFS) interface to replace the old interface
)
list(APPEND CEF_COMPILER_DEFINES_RELEASE
NDEBUG # Not a debug build
)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-Wno-undefined-var-template COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
if(COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
list(APPEND CEF_CXX_COMPILER_FLAGS
-Wno-undefined-var-template # Don't warn about potentially uninstantiated static members
)
endif()
CHECK_C_COMPILER_FLAG(-Wno-unused-local-typedefs COMPILER_SUPPORTS_NO_UNUSED_LOCAL_TYPEDEFS)
if(COMPILER_SUPPORTS_NO_UNUSED_LOCAL_TYPEDEFS)
list(APPEND CEF_C_COMPILER_FLAGS
-Wno-unused-local-typedefs # Don't warn about unused local typedefs
)
endif()
CHECK_CXX_COMPILER_FLAG(-Wno-literal-suffix COMPILER_SUPPORTS_NO_LITERAL_SUFFIX)
if(COMPILER_SUPPORTS_NO_LITERAL_SUFFIX)
list(APPEND CEF_CXX_COMPILER_FLAGS
-Wno-literal-suffix # Don't warn about invalid suffixes on literals
)
endif()
CHECK_CXX_COMPILER_FLAG(-Wno-narrowing COMPILER_SUPPORTS_NO_NARROWING)
if(COMPILER_SUPPORTS_NO_NARROWING)
list(APPEND CEF_CXX_COMPILER_FLAGS
-Wno-narrowing # Don't warn about type narrowing
)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
list(APPEND CEF_CXX_COMPILER_FLAGS
-Wno-attributes # The cfi-icall attribute is not supported by the GNU C++ compiler
)
endif()
if(PROJECT_ARCH STREQUAL "x86_64")
# 64-bit architecture.
list(APPEND CEF_COMPILER_FLAGS
-m64
-march=x86-64
)
list(APPEND CEF_LINKER_FLAGS
-m64
)
elseif(PROJECT_ARCH STREQUAL "x86")
# 32-bit architecture.
list(APPEND CEF_COMPILER_FLAGS
-msse2
-mfpmath=sse
-mmmx
-m32
)
list(APPEND CEF_LINKER_FLAGS
-m32
)
endif()
# Standard libraries.
set(CEF_STANDARD_LIBS
X11
)
# CEF directory paths.
set(CEF_RESOURCE_DIR "${_CEF_ROOT}/Resources")
set(CEF_BINARY_DIR "${_CEF_ROOT}/${CMAKE_BUILD_TYPE}")
set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug")
set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release")
# CEF library paths.
set(CEF_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/libcef.so")
set(CEF_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/libcef.so")
# List of CEF binary files.
set(CEF_BINARY_FILES
chrome-sandbox
libcef.so
libEGL.so
libGLESv2.so
libvk_swiftshader.so
libvulkan.so.1
snapshot_blob.bin
v8_context_snapshot.bin
vk_swiftshader_icd.json
)
# List of CEF resource files.
set(CEF_RESOURCE_FILES
chrome_100_percent.pak
chrome_200_percent.pak
resources.pak
icudtl.dat
locales
)
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
endif()
endif()
#
# Mac OS X configuration.
#
if(OS_MAC)
# Platform-specific compiler/linker flags.
# See also Xcode target properties in cef_macros.cmake.
set(CEF_LIBTYPE SHARED)
list(APPEND CEF_COMPILER_FLAGS
-fno-strict-aliasing # Avoid assumptions regarding non-aliasing of objects of different types
-fstack-protector # Protect some vulnerable functions from stack-smashing (security feature)
-funwind-tables # Support stack unwinding for backtrace()
-fvisibility=hidden # Give hidden visibility to declarations that are not explicitly marked as visible
-Wall # Enable all warnings
-Werror # Treat warnings as errors
-Wextra # Enable additional warnings
-Wendif-labels # Warn whenever an #else or an #endif is followed by text
-Wnewline-eof # Warn about no newline at end of file
-Wno-missing-field-initializers # Don't warn about missing field initializers
-Wno-unused-parameter # Don't warn about unused parameters
)
list(APPEND CEF_C_COMPILER_FLAGS
-std=c99 # Use the C99 language standard
)
list(APPEND CEF_CXX_COMPILER_FLAGS
-fno-exceptions # Disable exceptions
-fno-rtti # Disable real-time type information
-fno-threadsafe-statics # Don't generate thread-safe statics
-fobjc-call-cxx-cdtors # Call the constructor/destructor of C++ instance variables in ObjC objects
-fvisibility-inlines-hidden # Give hidden visibility to inlined class member functions
-std=c++17 # Use the C++17 language standard
-Wno-narrowing # Don't warn about type narrowing
-Wsign-compare # Warn about mixed signed/unsigned type comparisons
)
list(APPEND CEF_COMPILER_FLAGS_DEBUG
-O0 # Disable optimizations
-g # Generate debug information
)
list(APPEND CEF_COMPILER_FLAGS_RELEASE
-O3 # Optimize for maximum speed plus a few extras
)
list(APPEND CEF_LINKER_FLAGS
-Wl,-search_paths_first # Search for static or shared library versions in the same pass
-Wl,-ObjC # Support creation of ObjC static libraries
-Wl,-pie # Generate position-independent code suitable for executables only
)
list(APPEND CEF_LINKER_FLAGS_RELEASE
-Wl,-dead_strip # Strip dead code
)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-Wno-undefined-var-template COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
if(COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
list(APPEND CEF_CXX_COMPILER_FLAGS
-Wno-undefined-var-template # Don't warn about potentially uninstantiated static members
)
endif()
# Standard libraries.
set(CEF_STANDARD_LIBS
-lpthread
"-framework Cocoa"
"-framework AppKit"
)
# Find the newest available base SDK.
execute_process(COMMAND xcode-select --print-path OUTPUT_VARIABLE XCODE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
foreach(OS_VERSION 10.15 10.14 10.13)
set(SDK "${XCODE_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OS_VERSION}.sdk")
if(NOT "${CMAKE_OSX_SYSROOT}" AND EXISTS "${SDK}" AND IS_DIRECTORY "${SDK}")
set(CMAKE_OSX_SYSROOT ${SDK})
endif()
endforeach()
# Target SDK.
set(CEF_TARGET_SDK "10.13")
list(APPEND CEF_COMPILER_FLAGS
-mmacosx-version-min=${CEF_TARGET_SDK}
)
set(CMAKE_OSX_DEPLOYMENT_TARGET ${CEF_TARGET_SDK})
# Target architecture.
if(PROJECT_ARCH STREQUAL "x86_64")
set(CMAKE_OSX_ARCHITECTURES "x86_64")
elseif(PROJECT_ARCH STREQUAL "arm64")
set(CMAKE_OSX_ARCHITECTURES "arm64")
else()
set(CMAKE_OSX_ARCHITECTURES "i386")
endif()
# Prevent Xcode 11 from doing automatic codesigning.
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
# CEF directory paths.
set(CEF_BINARY_DIR "${_CEF_ROOT}/$<CONFIGURATION>")
set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug")
set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release")
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
list(APPEND CEF_STANDARD_LIBS
-lsandbox
)
# CEF sandbox library paths.
set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.a")
set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.a")
endif()
# CEF Helper app suffixes.
# Format is "<name suffix>:<target suffix>:<plist suffix>".
set(CEF_HELPER_APP_SUFFIXES
"::"
" (Alerts):_alerts:.alerts"
" (GPU):_gpu:.gpu"
" (Plugin):_plugin:.plugin"
" (Renderer):_renderer:.renderer"
)
endif()
#
# Windows configuration.
#
if(OS_WINDOWS)
if (GEN_NINJA)
# When using the Ninja generator clear the CMake defaults to avoid excessive
# console warnings (see issue #2120).
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
endif()
if(USE_SANDBOX)
# Check if the current MSVC version is compatible with the cef_sandbox.lib
# static library. We require VS2015 or newer.
if(MSVC_VERSION LESS 1900)
message(WARNING "CEF sandbox is not compatible with the current MSVC version (${MSVC_VERSION})")
set(USE_SANDBOX OFF)
endif()
endif()
# Consumers who run into LNK4099 warnings can pass /Z7 instead (see issue #385).
set(CEF_DEBUG_INFO_FLAG "/Zi" CACHE STRING "Optional flag specifying specific /Z flag to use")
# Consumers using different runtime types may want to pass different flags
set(CEF_RUNTIME_LIBRARY_FLAG "/MT" CACHE STRING "Optional flag specifying which runtime to use")
if (CEF_RUNTIME_LIBRARY_FLAG)
list(APPEND CEF_COMPILER_FLAGS_DEBUG ${CEF_RUNTIME_LIBRARY_FLAG}d)
list(APPEND CEF_COMPILER_FLAGS_RELEASE ${CEF_RUNTIME_LIBRARY_FLAG})
endif()
# Platform-specific compiler/linker flags.
set(CEF_LIBTYPE STATIC)
list(APPEND CEF_COMPILER_FLAGS
/MP # Multiprocess compilation
/Gy # Enable function-level linking
/GR- # Disable run-time type information
/W4 # Warning level 4
/WX # Treat warnings as errors
/wd4100 # Ignore "unreferenced formal parameter" warning
/wd4127 # Ignore "conditional expression is constant" warning
/wd4244 # Ignore "conversion possible loss of data" warning
/wd4324 # Ignore "structure was padded due to alignment specifier" warning
/wd4481 # Ignore "nonstandard extension used: override" warning
/wd4512 # Ignore "assignment operator could not be generated" warning
/wd4701 # Ignore "potentially uninitialized local variable" warning
/wd4702 # Ignore "unreachable code" warning
/wd4996 # Ignore "function or variable may be unsafe" warning
${CEF_DEBUG_INFO_FLAG}
)
list(APPEND CEF_COMPILER_FLAGS_DEBUG
/RTC1 # Disable optimizations
/Od # Enable basic run-time checks
)
list(APPEND CEF_COMPILER_FLAGS_RELEASE
/O2 # Optimize for maximum speed
/Ob2 # Inline any suitable function
/GF # Enable string pooling
)
list(APPEND CEF_CXX_COMPILER_FLAGS
/std:c++17 # Use the C++17 language standard
)
list(APPEND CEF_LINKER_FLAGS_DEBUG
/DEBUG # Generate debug information
)
list(APPEND CEF_EXE_LINKER_FLAGS
/MANIFEST:NO # No default manifest (see ADD_WINDOWS_MANIFEST macro usage)
/LARGEADDRESSAWARE # Allow 32-bit processes to access 3GB of RAM
)
list(APPEND CEF_COMPILER_DEFINES
WIN32 _WIN32 _WINDOWS # Windows platform
UNICODE _UNICODE # Unicode build
# Targeting Windows 10. We can't say `=_WIN32_WINNT_WIN10` here because
# some files do `#if WINVER < 0x0600` without including windows.h before,
# and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00.
WINVER=0x0A00
_WIN32_WINNT=0x0A00
NTDDI_VERSION=NTDDI_WIN10_FE
NOMINMAX # Use the standard's templated min/max
WIN32_LEAN_AND_MEAN # Exclude less common API declarations
_HAS_EXCEPTIONS=0 # Disable exceptions
)
list(APPEND CEF_COMPILER_DEFINES_RELEASE
NDEBUG _NDEBUG # Not a debug build
)
if(PROJECT_ARCH STREQUAL "x86")
# Set the initial stack size to 0.5MiB, instead of the 1.5MiB minimum
# needed by CEF's main thread. This saves significant memory on threads
# (like those in the Windows thread pool, and others) whose stack size we
# can only control through this setting. The main thread (in 32-bit builds
# only) uses fibers to switch to a 4MiB stack at runtime via
# CefRunWinMainWithPreferredStackSize().
list(APPEND CEF_EXE_LINKER_FLAGS
/STACK:0x80000
)
else()
# Increase the initial stack size to 8MiB from the default 1MiB.
list(APPEND CEF_EXE_LINKER_FLAGS
/STACK:0x800000
)
endif()
# Standard libraries.
set(CEF_STANDARD_LIBS
comctl32.lib
gdi32.lib
rpcrt4.lib
shlwapi.lib
ws2_32.lib
)
# CEF directory paths.
set(CEF_RESOURCE_DIR "${_CEF_ROOT}/Resources")
set(CEF_BINARY_DIR "${_CEF_ROOT}/$<CONFIGURATION>")
set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug")
set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release")
# CEF library paths.
set(CEF_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/libcef.lib")
set(CEF_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/libcef.lib")
# List of CEF binary files.
set(CEF_BINARY_FILES
chrome_elf.dll
d3dcompiler_47.dll
libcef.dll
libEGL.dll
libGLESv2.dll
snapshot_blob.bin
v8_context_snapshot.bin
vk_swiftshader.dll
vk_swiftshader_icd.json
vulkan-1.dll
)
# List of CEF resource files.
set(CEF_RESOURCE_FILES
chrome_100_percent.pak
chrome_200_percent.pak
resources.pak
icudtl.dat
locales
)
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
PSAPI_VERSION=1 # Required by cef_sandbox.lib
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
list(APPEND CEF_COMPILER_DEFINES_DEBUG
_HAS_ITERATOR_DEBUGGING=0 # Disable iterator debugging
)
# Libraries required by cef_sandbox.lib.
set(CEF_SANDBOX_STANDARD_LIBS
Advapi32.lib
dbghelp.lib
Delayimp.lib
ntdll.lib
OleAut32.lib
PowrProf.lib
Propsys.lib
psapi.lib
SetupAPI.lib
Shell32.lib
Shcore.lib
Userenv.lib
version.lib
wbemuuid.lib
WindowsApp.lib
winmm.lib
)
# CEF sandbox library paths.
set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.lib")
set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.lib")
endif()
# Configure use of ATL.
option(USE_ATL "Enable or disable use of ATL." ON)
if(USE_ATL)
# Locate the atlmfc directory if it exists. It may be at any depth inside
# the VC directory. The cl.exe path returned by CMAKE_CXX_COMPILER may also
# be at different depths depending on the toolchain version
# (e.g. "VC/bin/cl.exe", "VC/bin/amd64_x86/cl.exe",
# "VC/Tools/MSVC/14.10.25017/bin/HostX86/x86/cl.exe", etc).
set(HAS_ATLMFC 0)
get_filename_component(VC_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
get_filename_component(VC_DIR_NAME ${VC_DIR} NAME)
while(NOT ${VC_DIR_NAME} STREQUAL "VC")
get_filename_component(VC_DIR ${VC_DIR} DIRECTORY)
if(IS_DIRECTORY "${VC_DIR}/atlmfc")
set(HAS_ATLMFC 1)
break()
endif()
get_filename_component(VC_DIR_NAME ${VC_DIR} NAME)
endwhile()
# Determine if the Visual Studio install supports ATL.
if(NOT HAS_ATLMFC)
message(WARNING "ATL is not supported by your VC installation.")
set(USE_ATL OFF)
endif()
endif()
if(USE_ATL)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_ATL # Used by apps to test if ATL support is enabled
)
endif()
endif()

View File

@ -6,7 +6,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <utility>
#include "Drivers/CX11OpenGLDriver.h"
using namespace WallpaperEngine::Render;
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context,
@ -24,7 +24,10 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend
a_TexCoord (GL_NONE),
m_vaoBuffer (GL_NONE),
m_audioContext (audioContext),
m_state (scalingMode) {
m_state (scalingMode),
cef_window(1920,1080, "test title", reinterpret_cast<Drivers::CX11OpenGLDriver*>(const_cast<Drivers::CVideoDriver*>(&context.getDriver()))->getWindow())
{
cef_window.setup();
// generate the VAO to stop opengl from complaining
glGenVertexArrays (1, &this->m_vaoBuffer);
glBindVertexArray (this->m_vaoBuffer);
@ -194,41 +197,7 @@ void CWallpaper::updateUVs (const glm::ivec4& viewport, const bool vflip) {
void CWallpaper::render (glm::ivec4 viewport, bool vflip) {
this->renderFrame (viewport);
// Update UVs coordinates according to scaling mode of this wallpaper
updateUVs (viewport, vflip);
auto [ustart, uend, vstart, vend] = this->m_state.getTextureUVs ();
const GLfloat texCoords [] = {
ustart, vstart, uend, vstart, ustart, vend, ustart, vend, uend, vstart, uend, vend,
};
glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer);
glBindVertexArray (this->m_vaoBuffer);
glDisable (GL_BLEND);
glDisable (GL_DEPTH_TEST);
// do not use any shader
glUseProgram (this->m_shader);
// activate scene texture
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture ());
// set uniforms and attribs
glEnableVertexAttribArray (this->a_TexCoord);
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
glBufferData (GL_ARRAY_BUFFER, sizeof (texCoords), texCoords, GL_STATIC_DRAW);
glVertexAttribPointer (this->a_TexCoord, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray (this->a_Position);
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
glVertexAttribPointer (this->a_Position, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glUniform1i (this->g_Texture0, 0);
// write the framebuffer as is to the screen
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
glDrawArrays (GL_TRIANGLES, 0, 6);
cef_window.update();
}
void CWallpaper::setupFramebuffers () {

View File

@ -16,6 +16,8 @@
#include "CWallpaperState.h"
#include "cefsimple_opengl/CEFGLWindow.hpp"
using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Audio;
@ -183,5 +185,6 @@ class CWallpaper : public Helpers::CContextAware {
CAudioContext& m_audioContext;
/** Current Wallpaper state */
CWallpaperState m_state;
CEFGLWindow cef_window;
};
} // namespace WallpaperEngine::Render

View File

@ -0,0 +1,249 @@
// This code is a modification of the original projects that can be found at
// https://github.com/if1live/cef-gl-example
// https://github.com/andmcgregor/cefgui
#include "BrowserView.hpp"
#include "GLCore.hpp"
//------------------------------------------------------------------------------
BrowserView::RenderHandler::RenderHandler(glm::vec4 const& viewport)
: m_viewport(viewport)
{}
//------------------------------------------------------------------------------
BrowserView::RenderHandler::~RenderHandler()
{
// Free GPU memory
GLCore::deleteProgram(m_prog);
glDeleteBuffers(1, &m_vbo);
glDeleteVertexArrays(1, &m_vao);
}
//------------------------------------------------------------------------------
bool BrowserView::RenderHandler::init()
{
// Dummy texture data
const unsigned char data[] = {
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
255, 255, 255, 255,
};
// Compile vertex and fragment shaders
m_prog = GLCore::createShaderProgram("shaders/tex.vert", "shaders/tex.frag");
if (m_prog == 0)
{
std::cerr << "shader compile failed" << std::endl;
return false;
}
// Get locations of shader variables (attributes and uniforms)
m_pos_loc = GLCHECK(glGetAttribLocation(m_prog, "position"));
m_tex_loc = GLCHECK(glGetUniformLocation(m_prog, "tex"));
m_mvp_loc = GLCHECK(glGetUniformLocation(m_prog, "mvp"))
// Square vertices (texture positions are computed directly inside the shader)
float coords[] = {-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,1.0};
// See https://learnopengl.com/Getting-started/Textures
GLCHECK(glGenVertexArrays(1, &m_vao));
GLCHECK(glBindVertexArray(m_vao));
GLCHECK(glGenBuffers(1, &m_vbo));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
GLCHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW));
GLCHECK(glEnableVertexAttribArray(m_pos_loc));
GLCHECK(glVertexAttribPointer(m_pos_loc, 2, GL_FLOAT, GL_FALSE, 0, 0));
// GLCHECK(glGenTextures(1, &m_tex));
// GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
// GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
// GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
GLCHECK(glBindVertexArray(0));
return true;
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::draw(glm::vec4 const& viewport, bool fixed)
{
// Where to paint on the OpenGL window
GLCHECK(glViewport(viewport[0],
viewport[1],
GLsizei(viewport[2] * m_width),
GLsizei(viewport[3] * m_height)));
// // Apply a rotation
glm::mat4 trans = glm::mat4(1.0f); // Identity matrix
// if (!fixed)
// {
// trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
// trans = glm::rotate(trans, (float)glfwGetTime() / 5.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// }
// See https://learnopengl.com/Getting-started/Textures
GLCHECK(glUseProgram(m_prog));
GLCHECK(glBindVertexArray(m_vao));
GLCHECK(glUniformMatrix4fv(m_mvp_loc, 1, GL_FALSE, glm::value_ptr(trans)));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
GLCHECK(glActiveTexture(GL_TEXTURE0));
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
GLCHECK(glDrawArrays(GL_TRIANGLES, 0, 6));
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
GLCHECK(glBindVertexArray(0));
GLCHECK(glUseProgram(0));
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::reshape(int w, int h)
{
m_width = w;
m_height = h;
}
bool BrowserView::viewport(float x, float y, float w, float h)
{
if (!(x >= 0.0f) && (x < 1.0f))
return false;
if (!(x >= 0.0f) && (y < 1.0f))
return false;
if (!(w > 0.0f) && (w <= 1.0f))
return false;
if (!(h > 0.0f) && (h <= 1.0f))
return false;
if (x + w > 1.0f)
return false;
if (y + h > 1.0f)
return false;
m_viewport[0] = x;
m_viewport[1] = y;
m_viewport[2] = w;
m_viewport[3] = h;
return true;
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
{
rect = CefRect(m_viewport[0], m_viewport[1], m_viewport[2] * m_width, m_viewport[3] * m_height);
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList &dirtyRects, const void *buffer,
int width, int height)
{
//std::cout << "BrowserView::RenderHandler::OnPaint" << std::endl;
GLCHECK(glActiveTexture(GL_TEXTURE0));
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
GL_UNSIGNED_BYTE, (unsigned char*)buffer));
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
}
//------------------------------------------------------------------------------
BrowserView::BrowserView(const std::string &url)
: m_mouse_x(0), m_mouse_y(0), m_viewport(0.0f, 0.0f, 1.0f, 1.0f)
{
CefWindowInfo window_info;
window_info.SetAsWindowless(0);
m_render_handler = new RenderHandler(m_viewport);
m_initialized = m_render_handler->init();
m_render_handler->reshape(128, 128); // initial size
CefBrowserSettings browserSettings;
browserSettings.windowless_frame_rate = 60; // 30 is default
m_client = new BrowserClient(m_render_handler);
m_browser = CefBrowserHost::CreateBrowserSync(window_info, m_client.get(),
url, browserSettings,
nullptr, nullptr);
}
//------------------------------------------------------------------------------
BrowserView::~BrowserView()
{
CefDoMessageLoopWork();
m_browser->GetHost()->CloseBrowser(true);
m_browser = nullptr;
m_client = nullptr;
}
//------------------------------------------------------------------------------
void BrowserView::load(const std::string &url)
{
assert(m_initialized);
m_browser->GetMainFrame()->LoadURL(url);
}
//------------------------------------------------------------------------------
void BrowserView::draw()
{
CefDoMessageLoopWork();
m_render_handler->draw(m_viewport, m_fixed);
}
//------------------------------------------------------------------------------
void BrowserView::reshape(int w, int h)
{
m_render_handler->reshape(w, h);
GLCHECK(glViewport(m_viewport[0],
m_viewport[1],
GLsizei(m_viewport[2] * w),
GLsizei(m_viewport[3] * h)));
m_browser->GetHost()->WasResized();
}
//------------------------------------------------------------------------------
void BrowserView::mouseMove(int x, int y)
{
m_mouse_x = x;
m_mouse_y = y;
CefMouseEvent evt;
evt.x = x;
evt.y = y;
bool mouse_leave = false; // TODO
m_browser->GetHost()->SendMouseMoveEvent(evt, mouse_leave);
}
//------------------------------------------------------------------------------
void BrowserView::mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up)
{
CefMouseEvent evt;
evt.x = m_mouse_x;
evt.y = m_mouse_y;
int click_count = 1; // TODO
m_browser->GetHost()->SendMouseClickEvent(evt, btn, mouse_up, click_count);
}
//------------------------------------------------------------------------------
void BrowserView::keyPress(int key, bool pressed)
{
CefKeyEvent evt;
evt.character = key;
evt.native_key_code = key;
evt.type = pressed ? KEYEVENT_CHAR : KEYEVENT_KEYUP;
m_browser->GetHost()->SendKeyEvent(evt);
}

View File

@ -0,0 +1,187 @@
// This code is a modification of the original "cefsimple" example that can be found at
// https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage
#ifndef BROWSERVIEW_HPP
# define BROWSERVIEW_HPP
# include <iostream>
// OpenGL
# include <GL/glew.h>
# include <GLFW/glfw3.h>
// Matrices manipulation for OpenGL
# include <glm/glm.hpp>
# include <glm/ext.hpp>
// Chromium Embedded Framework
# include <cef_render_handler.h>
# include <cef_client.h>
# include <cef_app.h>
# include <string>
# include <vector>
# include <memory>
# include <algorithm>
// ****************************************************************************
//! \brief Interface class rendering a single web page.
// ****************************************************************************
class BrowserView
{
public:
//! \brief Default Constructor using a given URL.
BrowserView(const std::string &url);
//! \brief
~BrowserView();
//! \brief Load the given web page.
void load(const std::string &url);
//! \brief Render the web page.
void draw();
//! \brief Set the windows size.
void reshape(int w, int h);
//! \brief Set the viewport: the rectangle on the window where to display
//! the web document.
//! \return false if arguments are incorrect.
bool viewport(float x, float y, float w, float h);
//! \brief Get the viewport.
inline glm::vec4 const& viewport() const
{
return m_viewport;
}
//! \brief TODO
// void executeJS(const std::string &cmd);
//! \brief Set the new mouse position
void mouseMove(int x, int y);
//! \brief Set the new mouse state (clicked ...)
void mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up);
//! \brief Set the new keyboard state (char typed ...)
void keyPress(int key, bool pressed);
private:
// *************************************************************************
//! \brief Private implementation to handle CEF events to draw the web page.
// *************************************************************************
class RenderHandler: public CefRenderHandler
{
public:
RenderHandler(glm::vec4 const& viewport);
//! \brief
~RenderHandler();
//! \brief Compile OpenGL shaders and create OpenGL objects (VAO,
//! VBO, texture, locations ...)
bool init();
//! \brief Render OpenGL VAO (rotating a textured square)
void draw(glm::vec4 const& viewport, bool fixed);
//! \brief Resize the view
void reshape(int w, int h);
//! \brief Return the OpenGL texture handle
GLuint texture() const
{
return m_tex;
}
//! \brief CefRenderHandler interface
virtual void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) override;
//! \brief CefRenderHandler interface
//! Update the OpenGL texture.
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList &dirtyRects, const void *buffer,
int width, int height) override;
//! \brief CefBase interface
IMPLEMENT_REFCOUNTING(RenderHandler);
private:
//! \brief Dimension
int m_width;
int m_height;
//! \brief Where to draw on the OpenGL window
glm::vec4 const& m_viewport;
//! \brief OpenGL shader program handle
GLuint m_prog = 0;
//! \brief OpenGL texture handle
GLuint m_tex = 0;
//! \brief OpenGL vertex array object handle
GLuint m_vao = 0;
//! \brief OpenGL vertex buffer obejct handle
GLuint m_vbo = 0;
//! \brief OpenGL shader variable locations for vertices of the
//! rectangle
GLint m_pos_loc = -1;
//! \brief OpenGL shader variable locations for the texture
GLint m_tex_loc = -1;
//! \brief OpenGL shader variable locations for the Model View
//! Projection matrix.
GLint m_mvp_loc = -1;
};
// *************************************************************************
//! \brief Provide access to browser-instance-specific callbacks. A single
//! CefClient instance can be shared among any number of browsers.
// *************************************************************************
class BrowserClient: public CefClient
{
public:
BrowserClient(CefRefPtr<CefRenderHandler> ptr)
: m_renderHandler(ptr)
{}
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override
{
return m_renderHandler;
}
CefRefPtr<CefRenderHandler> m_renderHandler;
IMPLEMENT_REFCOUNTING(BrowserClient);
};
private:
//! \brief Mouse cursor position on the OpenGL window
int m_mouse_x;
int m_mouse_y;
//! \brief Where to draw on the OpenGL window
glm::vec4 m_viewport;
//! \brief Chromium Embedded framework elements
CefRefPtr<CefBrowser> m_browser;
CefRefPtr<BrowserClient> m_client;
RenderHandler* m_render_handler = nullptr;
//! \brief OpenGL has created GPU elements with success
bool m_initialized = false;
public:
//! \brief If set to false then the web page is turning.
bool m_fixed = true;
};
#endif // BROWSERVIEW_HPP

View File

@ -0,0 +1,249 @@
// This code is a modification of the original projects that can be found at
// https://github.com/if1live/cef-gl-example
// https://github.com/andmcgregor/cefgui
#include "BrowserView.hpp"
#include "GLCore.hpp"
//------------------------------------------------------------------------------
BrowserView::RenderHandler::RenderHandler(glm::vec4 const& viewport)
: m_viewport(viewport)
{}
//------------------------------------------------------------------------------
BrowserView::RenderHandler::~RenderHandler()
{
// Free GPU memory
GLCore::deleteProgram(m_prog);
glDeleteBuffers(1, &m_vbo);
glDeleteVertexArrays(1, &m_vao);
}
//------------------------------------------------------------------------------
bool BrowserView::RenderHandler::init()
{
// Dummy texture data
const unsigned char data[] = {
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
255, 255, 255, 255,
};
// Compile vertex and fragment shaders
m_prog = GLCore::createShaderProgram("shaders/tex.vert", "shaders/tex.frag");
if (m_prog == 0)
{
std::cerr << "shader compile failed" << std::endl;
return false;
}
// Get locations of shader variables (attributes and uniforms)
m_pos_loc = GLCHECK(glGetAttribLocation(m_prog, "position"));
m_tex_loc = GLCHECK(glGetUniformLocation(m_prog, "tex"));
m_mvp_loc = GLCHECK(glGetUniformLocation(m_prog, "mvp"))
// Square vertices (texture positions are computed directly inside the shader)
float coords[] = {-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,1.0};
// See https://learnopengl.com/Getting-started/Textures
GLCHECK(glGenVertexArrays(1, &m_vao));
GLCHECK(glBindVertexArray(m_vao));
GLCHECK(glGenBuffers(1, &m_vbo));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
GLCHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW));
GLCHECK(glEnableVertexAttribArray(m_pos_loc));
GLCHECK(glVertexAttribPointer(m_pos_loc, 2, GL_FLOAT, GL_FALSE, 0, 0));
GLCHECK(glGenTextures(1, &m_tex));
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
GLCHECK(glBindVertexArray(0));
return true;
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::draw(glm::vec4 const& viewport, bool fixed)
{
// Where to paint on the OpenGL window
GLCHECK(glViewport(viewport[0],
viewport[1],
GLsizei(viewport[2] * m_width),
GLsizei(viewport[3] * m_height)));
// Apply a rotation
glm::mat4 trans = glm::mat4(1.0f); // Identity matrix
if (!fixed)
{
trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
trans = glm::rotate(trans, (float)glfwGetTime() / 5.0f, glm::vec3(0.0f, 0.0f, 1.0f));
}
// See https://learnopengl.com/Getting-started/Textures
GLCHECK(glUseProgram(m_prog));
GLCHECK(glBindVertexArray(m_vao));
GLCHECK(glUniformMatrix4fv(m_mvp_loc, 1, GL_FALSE, glm::value_ptr(trans)));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
GLCHECK(glActiveTexture(GL_TEXTURE0));
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
GLCHECK(glDrawArrays(GL_TRIANGLES, 0, 6));
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
GLCHECK(glBindVertexArray(0));
GLCHECK(glUseProgram(0));
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::reshape(int w, int h)
{
m_width = w;
m_height = h;
}
bool BrowserView::viewport(float x, float y, float w, float h)
{
if (!(x >= 0.0f) && (x < 1.0f))
return false;
if (!(x >= 0.0f) && (y < 1.0f))
return false;
if (!(w > 0.0f) && (w <= 1.0f))
return false;
if (!(h > 0.0f) && (h <= 1.0f))
return false;
if (x + w > 1.0f)
return false;
if (y + h > 1.0f)
return false;
m_viewport[0] = x;
m_viewport[1] = y;
m_viewport[2] = w;
m_viewport[3] = h;
return true;
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
{
rect = CefRect(m_viewport[0], m_viewport[1], m_viewport[2] * m_width, m_viewport[3] * m_height);
}
//------------------------------------------------------------------------------
void BrowserView::RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList &dirtyRects, const void *buffer,
int width, int height)
{
//std::cout << "BrowserView::RenderHandler::OnPaint" << std::endl;
GLCHECK(glActiveTexture(GL_TEXTURE0));
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
GL_UNSIGNED_BYTE, (unsigned char*)buffer));
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
}
//------------------------------------------------------------------------------
BrowserView::BrowserView(const std::string &url)
: m_mouse_x(0), m_mouse_y(0), m_viewport(0.0f, 0.0f, 1.0f, 1.0f)
{
CefWindowInfo window_info;
window_info.SetAsWindowless(0);
m_render_handler = new RenderHandler(m_viewport);
m_initialized = m_render_handler->init();
m_render_handler->reshape(128, 128); // initial size
CefBrowserSettings browserSettings;
browserSettings.windowless_frame_rate = 60; // 30 is default
m_client = new BrowserClient(m_render_handler);
m_browser = CefBrowserHost::CreateBrowserSync(window_info, m_client.get(),
url, browserSettings,
nullptr, nullptr);
}
//------------------------------------------------------------------------------
BrowserView::~BrowserView()
{
CefDoMessageLoopWork();
m_browser->GetHost()->CloseBrowser(true);
m_browser = nullptr;
m_client = nullptr;
}
//------------------------------------------------------------------------------
void BrowserView::load(const std::string &url)
{
assert(m_initialized);
m_browser->GetMainFrame()->LoadURL(url);
}
//------------------------------------------------------------------------------
void BrowserView::draw()
{
CefDoMessageLoopWork();
m_render_handler->draw(m_viewport, m_fixed);
}
//------------------------------------------------------------------------------
void BrowserView::reshape(int w, int h)
{
m_render_handler->reshape(w, h);
GLCHECK(glViewport(m_viewport[0],
m_viewport[1],
GLsizei(m_viewport[2] * w),
GLsizei(m_viewport[3] * h)));
m_browser->GetHost()->WasResized();
}
//------------------------------------------------------------------------------
void BrowserView::mouseMove(int x, int y)
{
m_mouse_x = x;
m_mouse_y = y;
CefMouseEvent evt;
evt.x = x;
evt.y = y;
bool mouse_leave = false; // TODO
m_browser->GetHost()->SendMouseMoveEvent(evt, mouse_leave);
}
//------------------------------------------------------------------------------
void BrowserView::mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up)
{
CefMouseEvent evt;
evt.x = m_mouse_x;
evt.y = m_mouse_y;
int click_count = 1; // TODO
m_browser->GetHost()->SendMouseClickEvent(evt, btn, mouse_up, click_count);
}
//------------------------------------------------------------------------------
void BrowserView::keyPress(int key, bool pressed)
{
CefKeyEvent evt;
evt.character = key;
evt.native_key_code = key;
evt.type = pressed ? KEYEVENT_CHAR : KEYEVENT_KEYUP;
m_browser->GetHost()->SendKeyEvent(evt);
}

View File

@ -0,0 +1,187 @@
// This code is a modification of the original "cefsimple" example that can be found at
// https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage
#ifndef BROWSERVIEW_HPP
# define BROWSERVIEW_HPP
# include <iostream>
// OpenGL
# include <GL/glew.h>
# include <GLFW/glfw3.h>
// Matrices manipulation for OpenGL
# include <glm/glm.hpp>
# include <glm/ext.hpp>
// Chromium Embedded Framework
# include "include/cef_render_handler.h"
# include "include/cef_client.h"
# include "include/cef_app.h"
# include <string>
# include <vector>
# include <memory>
# include <algorithm>
// ****************************************************************************
//! \brief Interface class rendering a single web page.
// ****************************************************************************
class BrowserView
{
public:
//! \brief Default Constructor using a given URL.
BrowserView(const std::string &url);
//! \brief
~BrowserView();
//! \brief Load the given web page.
void load(const std::string &url);
//! \brief Render the web page.
void draw();
//! \brief Set the windows size.
void reshape(int w, int h);
//! \brief Set the viewport: the rectangle on the window where to display
//! the web document.
//! \return false if arguments are incorrect.
bool viewport(float x, float y, float w, float h);
//! \brief Get the viewport.
inline glm::vec4 const& viewport() const
{
return m_viewport;
}
//! \brief TODO
// void executeJS(const std::string &cmd);
//! \brief Set the new mouse position
void mouseMove(int x, int y);
//! \brief Set the new mouse state (clicked ...)
void mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up);
//! \brief Set the new keyboard state (char typed ...)
void keyPress(int key, bool pressed);
private:
// *************************************************************************
//! \brief Private implementation to handle CEF events to draw the web page.
// *************************************************************************
class RenderHandler: public CefRenderHandler
{
public:
RenderHandler(glm::vec4 const& viewport);
//! \brief
~RenderHandler();
//! \brief Compile OpenGL shaders and create OpenGL objects (VAO,
//! VBO, texture, locations ...)
bool init();
//! \brief Render OpenGL VAO (rotating a textured square)
void draw(glm::vec4 const& viewport, bool fixed);
//! \brief Resize the view
void reshape(int w, int h);
//! \brief Return the OpenGL texture handle
GLuint texture() const
{
return m_tex;
}
//! \brief CefRenderHandler interface
virtual void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) override;
//! \brief CefRenderHandler interface
//! Update the OpenGL texture.
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList &dirtyRects, const void *buffer,
int width, int height) override;
//! \brief CefBase interface
IMPLEMENT_REFCOUNTING(RenderHandler);
private:
//! \brief Dimension
int m_width;
int m_height;
//! \brief Where to draw on the OpenGL window
glm::vec4 const& m_viewport;
//! \brief OpenGL shader program handle
GLuint m_prog = 0;
//! \brief OpenGL texture handle
GLuint m_tex = 0;
//! \brief OpenGL vertex array object handle
GLuint m_vao = 0;
//! \brief OpenGL vertex buffer obejct handle
GLuint m_vbo = 0;
//! \brief OpenGL shader variable locations for vertices of the
//! rectangle
GLint m_pos_loc = -1;
//! \brief OpenGL shader variable locations for the texture
GLint m_tex_loc = -1;
//! \brief OpenGL shader variable locations for the Model View
//! Projection matrix.
GLint m_mvp_loc = -1;
};
// *************************************************************************
//! \brief Provide access to browser-instance-specific callbacks. A single
//! CefClient instance can be shared among any number of browsers.
// *************************************************************************
class BrowserClient: public CefClient
{
public:
BrowserClient(CefRefPtr<CefRenderHandler> ptr)
: m_renderHandler(ptr)
{}
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override
{
return m_renderHandler;
}
CefRefPtr<CefRenderHandler> m_renderHandler;
IMPLEMENT_REFCOUNTING(BrowserClient);
};
private:
//! \brief Mouse cursor position on the OpenGL window
int m_mouse_x;
int m_mouse_y;
//! \brief Where to draw on the OpenGL window
glm::vec4 m_viewport;
//! \brief Chromium Embedded framework elements
CefRefPtr<CefBrowser> m_browser;
CefRefPtr<BrowserClient> m_client;
RenderHandler* m_render_handler = nullptr;
//! \brief OpenGL has created GPU elements with success
bool m_initialized = false;
public:
//! \brief If set to false then the web page is turning.
bool m_fixed = true;
};
#endif // BROWSERVIEW_HPP

View File

@ -0,0 +1,162 @@
// This code is a modification of the original project that can be found at
// https://github.com/if1live/cef-gl-example
#include "CEFGLWindow.hpp"
#include "GLCore.hpp"
//------------------------------------------------------------------------------
//! \brief Callback when the OpenGL base window has been resized. Dispatch this
//! event to all BrowserView.
//------------------------------------------------------------------------------
static void reshape_callback(GLFWwindow* ptr, int w, int h)
{
assert(nullptr != ptr);
CEFGLWindow* window = static_cast<CEFGLWindow*>(glfwGetWindowUserPointer(ptr));
// Send screen size to browsers
for (auto it: window->browsers())
{
it->reshape(w, h);
}
}
//------------------------------------------------------------------------------
//! \brief Callback when the mouse has clicked inside the OpenGL base window.
//! Dispatch this event to all BrowserView.
//------------------------------------------------------------------------------
static void mouse_callback(GLFWwindow* ptr, int btn, int state, int /*mods*/)
{
assert(nullptr != ptr);
CEFGLWindow* window = static_cast<CEFGLWindow*>(glfwGetWindowUserPointer(ptr));
// Send mouse click to browsers
for (auto it: window->browsers())
{
it->mouseClick(CefBrowserHost::MouseButtonType(btn), state == GLFW_PRESS);
}
}
//------------------------------------------------------------------------------
//! \brief Callback when the mouse has been displaced inside the OpenGL base
//! window. Dispatch this event to all BrowserView.
//------------------------------------------------------------------------------
static void motion_callback(GLFWwindow* ptr, double x, double y)
{
assert(nullptr != ptr);
CEFGLWindow* window = static_cast<CEFGLWindow*>(glfwGetWindowUserPointer(ptr));
// Send mouse movement to browsers
for (auto it: window->browsers())
{
it->mouseMove((int) x, (int) y);
}
}
//------------------------------------------------------------------------------
//! \brief Callback when the keybaord has been pressed inside the OpenGL base
//! window. Dispatch this event to all BrowserView.
//------------------------------------------------------------------------------
static void keyboard_callback(GLFWwindow* ptr, int key, int /*scancode*/,
int action, int /*mods*/)
{
assert(nullptr != ptr);
CEFGLWindow* window = static_cast<CEFGLWindow*>(glfwGetWindowUserPointer(ptr));
// Send key press to browsers
for (auto it: window->browsers())
{
it->keyPress(key, (action == GLFW_PRESS));
}
}
//------------------------------------------------------------------------------
CEFGLWindow::CEFGLWindow(uint32_t const width, uint32_t const height, const char *title, GLFWwindow* window)
: GLWindow(width, height, title, window)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
//------------------------------------------------------------------------------
CEFGLWindow::~CEFGLWindow()
{
m_browsers.clear();
CefShutdown();
}
//------------------------------------------------------------------------------
std::weak_ptr<BrowserView> CEFGLWindow::createBrowser(const std::string &url)
{
auto web_core = std::make_shared<BrowserView>(url);
m_browsers.push_back(web_core);
return web_core;
}
//------------------------------------------------------------------------------
void CEFGLWindow::removeBrowser(std::weak_ptr<BrowserView> web_core)
{
auto elem = web_core.lock();
if (elem)
{
auto found = std::find(m_browsers.begin(), m_browsers.end(), elem);
if (found != m_browsers.end())
{
m_browsers.erase(found);
}
}
}
//------------------------------------------------------------------------------
bool CEFGLWindow::setup()
{
this->init();
std::vector<std::string> urls = {
//"https://youtu.be/rRr19a08mHs",
// "https://www.researchgate.net/profile/Philip-Polack/publication/318810853_The_kinematic_bicycle_model_A_consistent_model_for_planning_feasible_trajectories_for_autonomous_vehicles/links/5addcbc2a6fdcc29358b9c01/The-kinematic-bicycle-model-A-consistent-model-for-planning-feasible-trajectories-for-autonomous-vehicles.pdf",
//"https://www.youtube.com/"
"file:///home/kermit/.local/share/Steam/steamapps/workshop/content/431960/3026516467/Untitled-1.html"
};
// Create BrowserView
for (auto const& url: urls)
{
auto browser = createBrowser(url);
browser.lock()->reshape(m_width, m_height);
}
// Change viewports (vertical split)
m_browsers[0]->viewport(0.0f, 0.0f, 1.0f, 1.0f);
//m_browsers[1]->viewport(0.5f, 0.0f, 1.0f, 1.0f);
// Do rotation animation
// m_browsers[1]->m_fixed = false;
// Windows events
GLCHECK(glfwSetFramebufferSizeCallback(m_window, reshape_callback));
GLCHECK(glfwSetKeyCallback(m_window, keyboard_callback));
GLCHECK(glfwSetCursorPosCallback(m_window, motion_callback));
GLCHECK(glfwSetMouseButtonCallback(m_window, mouse_callback));
// Set OpenGL states
//GLCHECK(glViewport(0, 0, m_width, m_height));
// GLCHECK(glClearColor(0.0, 0.0, 0.0, 0.0));
//GLCHECK(glEnable(GL_CULL_FACE));
// GLCHECK(glEnable(GL_DEPTH_TEST));
// GLCHECK(glDepthFunc(GL_LESS));
// GLCHECK(glDisable(GL_BLEND));
// GLCHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
return true;
}
//------------------------------------------------------------------------------
bool CEFGLWindow::update()
{
GLCHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
for (auto it: m_browsers)
{
it->draw();
}
CefDoMessageLoopWork();
return true;
}

View File

@ -0,0 +1,51 @@
// This code is a modification of the original project that can be found at
// https://github.com/Lecrapouille/OpenGLCppWrapper
#ifndef CEFGLWINDOW_HPP
#define CEFGLWINDOW_HPP
// Base application class
#include "GLWindow.hpp"
#include "BrowserView.hpp"
// ****************************************************************************
//! \brief Extend the OpenGL base window and add Chromium Embedded Framework
//! browser views.
// ****************************************************************************
class CEFGLWindow: public GLWindow
{
public:
//! \brief Default construction: define the window dimension and title
CEFGLWindow(uint32_t const width, uint32_t const height, const char *title, GLFWwindow* window);
//! \brief Destructor
~CEFGLWindow();
//! \brief Non const getter of the list of browsers
inline std::vector<std::shared_ptr<BrowserView>>& browsers()
{
return m_browsers;
}
// private: // Concrete implementation from GLWindow
virtual bool setup() override;
virtual bool update() override;
private:
//! \brief Create a new browser view from a given URL
std::weak_ptr<BrowserView> createBrowser(const std::string &url);
//! \brief Destroy the given browser view.
void removeBrowser(std::weak_ptr<BrowserView> web_core);
private:
//! \brief List of BrowserView managed by createBrowser() and
//! removeBrowser() methods.
std::vector<std::shared_ptr<BrowserView>> m_browsers;
};
#endif // CEFGLWINDOW_HPP

View File

@ -0,0 +1,132 @@
// This code is a modification of the original project that can be found at
// https://github.com/if1live/cef-gl-example
#include "GLCore.hpp"
#include <fstream>
#include <iostream>
void GLCore::checkError(const char* filename, const uint32_t line, const char* expression)
{
GLenum id;
const char* error;
while ((id = glGetError()) != GL_NO_ERROR)
{
switch (id)
{
case GL_INVALID_OPERATION:
error = "GL_INVALID_OPERATION";
break;
case GL_INVALID_ENUM:
error = "GL_INVALID_ENUM";
break;
case GL_INVALID_VALUE:
error = "GL_INVALID_VALUE";
break;
case GL_OUT_OF_MEMORY:
error = "GL_OUT_OF_MEMORY";
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
error = "GL_INVALID_FRAMEBUFFER_OPERATION";
break;
default:
error = "UNKNOWN";
break;
}
// Do not use directly LOG macros because it will catch this
// filename and its line instead of the faulty file/line which
// produced the OpenGL error.
std::cerr << "GLERR: " << filename << " " << line << ": Failed executing "
<< expression << ". Reason was " << error << std::endl;
}
}
GLuint GLCore::compileShaderFromCode(GLenum shader_type, const char *src)
{
GLuint shader = glCreateShader(shader_type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE) {
return shader;
}
// shader compile fail!
fprintf(stderr, "SHADER COMPILE ERROR\n");
GLint info_len = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
if (info_len > 1) {
char *info_log = (char*)malloc(sizeof(char) * info_len);
glGetShaderInfoLog(shader, info_len, NULL, info_log);
fprintf(stderr, "Error compiling shader: \n%s\n", info_log);
free(info_log);
}
glDeleteShader(shader);
return 0;
}
GLuint GLCore::compileShaderFromFile(GLenum shader_type, const char *filepath)
{
std::ifstream ifs(filepath);
std::string shader_str((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
const char *src = shader_str.data();
return compileShaderFromCode(shader_type, src);
}
bool GLCore::deleteShader(GLuint shader)
{
glDeleteShader(shader);
return true;
}
GLuint GLCore::createShaderProgram(const char *vert, const char *frag)
{
GLuint vertShader = compileShaderFromFile(GL_VERTEX_SHADER, vert);
GLuint fragShader = compileShaderFromFile(GL_FRAGMENT_SHADER, frag);
if (vertShader == 0 || fragShader == 0) {
return 0;
}
return createShaderProgram(vertShader, fragShader);
}
GLuint GLCore::createShaderProgram(GLuint vert, GLuint frag)
{
GLuint program = glCreateProgram();
glAttachShader(program, vert);
glAttachShader(program, frag);
glLinkProgram(program);
glDetachShader(program, vert);
glDetachShader(program, frag);
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (linked) {
return program;
}
// fail...
GLint info_len = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_len);
if (info_len > 1) {
char *info_log = (char*)malloc(sizeof(char) * info_len);
glGetProgramInfoLog(program, info_len, NULL, info_log);
fprintf(stderr, "Error linking program: \n%s\n", info_log);
free(info_log);
}
glDeleteProgram(program);
return 0;
}
bool GLCore::deleteProgram(GLuint program)
{
glDeleteProgram(program);
return true;
}

View File

@ -0,0 +1,31 @@
// This code is a modification of the original project that can be found at
// https://github.com/if1live/cef-gl-example
#ifndef GLCORE_HPP
# define GLCORE_HPP
# include <GL/glew.h>
// *****************************************************************************
//! \brief Helper functions for compiling OpenGL shaders.
// *****************************************************************************
class GLCore
{
public:
static void checkError(const char* filename, const uint32_t line, const char* expression);
static GLuint compileShaderFromCode(GLenum shader_type, const char *src);
static GLuint compileShaderFromFile(GLenum shader_type, const char *filepath);
static GLuint createShaderProgram(const char *vert, const char *frag);
static GLuint createShaderProgram(GLuint vert, GLuint frag);
static bool deleteShader(GLuint shader);
static bool deleteProgram(GLuint program);
};
# ifdef CHECK_OPENGL
# define GLCHECK(expr) expr; GLCore::checkError(__FILE__, __LINE__, #expr);
# else
# define GLCHECK(expr) expr;
# endif
#endif

View File

@ -0,0 +1,93 @@
// This code is a modification of the original project that can be found at
// https://github.com/Lecrapouille/OpenGLCppWrapper
#include "GLWindow.hpp"
#include <iostream>
#include <cassert>
static void error_callback(int error, const char* description)
{
std::cerr << error << ": " << description << std::endl;
}
GLWindow::GLWindow(uint32_t const width, uint32_t const height, const char *title, GLFWwindow* window)
: m_width(width), m_height(height), m_title(title), m_window(window)
{}
void GLWindow::init()
{
// // Initialize glfw3
// glfwSetErrorCallback(error_callback);
// if (!glfwInit())
// {
// std::cerr << "glfwInit: failed" << std::endl;
// exit(1);
// }
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// m_window = glfwCreateWindow(static_cast<int>(m_width),
// static_cast<int>(m_height),
// m_title.c_str(), nullptr, nullptr);
// if (!m_window)
// {
// std::cerr << "glfwCreateWindow: failed" << std::endl;
// glfwTerminate();
// exit(1);
// }
// glfwMakeContextCurrent(m_window);
// glfwSwapInterval(1); // Enable vsync
glfwSetWindowUserPointer(m_window, this); // Pass m_window in callbacks
// // Initialize GLEW
// glewExperimental = GL_TRUE; // stops glew crashing on OSX :-/
// if (GLEW_OK != glewInit())
// {
// std::cerr << "glewInit: failed" << std::endl;
// exit(1);
// }
// // Print out some info about the graphics drivers
// std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
// std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
// std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
// std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
// // Make sure OpenGL version 3.2 API is available
// if (!GLEW_VERSION_3_2)
// {
// std::cerr << "OpenGL 3.2 API is not available!" << std::endl;
// }
}
GLWindow::~GLWindow()
{
if (nullptr != m_window)
glfwDestroyWindow(m_window);
glfwTerminate();
}
bool GLWindow::start() //Don't use
{
init();
if (!setup())
return false;
while (!glfwWindowShouldClose(m_window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!update())
return false;
glfwSwapBuffers(m_window);
glfwPollEvents();
}
return true;
}

View File

@ -0,0 +1,45 @@
// This code is a modification of the original project that can be found at
// https://github.com/Lecrapouille/OpenGLCppWrapper
#ifndef GLWINDOW_HPP
# define GLWINDOW_HPP
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <string>
// *****************************************************************************
//! \brief Base class for creating OpenGL window. This class create the OpenGL
//! context, create the windows and call private virtual methods setup() and
//! update(). This must be derived to implement setup() and update().
// *****************************************************************************
class GLWindow
{
public:
GLWindow(uint32_t const width, uint32_t const height, const char *title, GLFWwindow* window);
virtual ~GLWindow();
//! \brief call setup() once and if succeeded call update() within a runtime
//! loop. Return false in case of failure.
bool start();
void init();
private:
//! \brief Implement the init for your application. Return false in case of failure.
virtual bool setup() = 0;
//! \brief Implement the update for your application. Return false in case of failure.
virtual bool update() = 0;
protected:
//! \brief The OpenGL whindows holding the context
GLFWwindow *m_window = nullptr;
uint32_t m_width;
uint32_t m_height;
std::string m_title;
};
#endif

View File

@ -0,0 +1,15 @@
#version 150
in vec2 Texcoord;
out vec4 outputColor;
uniform sampler2D tex;
void main() {
outputColor = texture2D(tex, Texcoord);
if (outputColor.a < 0.1)
{
discard;
}
}

View File

@ -0,0 +1,11 @@
#version 150
uniform mat4 mvp;
in vec2 position;
out vec2 Texcoord;
void main() {
Texcoord = (vec2(position.x + 1.0f, position.y - 1.0f) * 0.5);
Texcoord.y *= -1.0f;
gl_Position = mvp * vec4(position.x, position.y, 0.0f, 1.0f);
}

View File

@ -0,0 +1,15 @@
#version 150
in vec2 Texcoord;
out vec4 outputColor;
uniform sampler2D tex;
void main() {
outputColor = texture2D(tex, Texcoord);
if (outputColor.a < 0.1)
{
discard;
}
}

View File

@ -0,0 +1,11 @@
#version 150
uniform mat4 mvp;
in vec2 position;
out vec2 Texcoord;
void main() {
Texcoord = (vec2(position.x + 1.0f, position.y - 1.0f) * 0.5);
Texcoord.y *= -1.0f;
gl_Position = mvp * vec4(position.x, position.y, 0.0f, 1.0f);
}