Compare commits
42 Commits
temp-llvm-
...
soc-2014-v
Author | SHA1 | Date | |
---|---|---|---|
d9ffc99e66 | |||
551ebaa3dd | |||
50366779e6 | |||
1d8739b014 | |||
4dc1ec4564 | |||
3e454e0c5d | |||
ab86fafed4 | |||
0ef5c183d8 | |||
71ea85cc61 | |||
85fdb5adef | |||
a1d1b07eb6 | |||
62e83b3478 | |||
40b6df7851 | |||
302a5b56df | |||
df3313187f | |||
361ab2ff2e | |||
c39f6c49b7 | |||
407a6dfdc9 | |||
dc627428c9 | |||
653379b15a | |||
1ead782e3c | |||
6741f8e7a0 | |||
b54017edb0 | |||
7c012d906c | |||
d56908df51 | |||
42beba3f73 | |||
4f88d6d74c | |||
4606950e81 | |||
8ecdbe5f98 | |||
d3de9c621e | |||
728bb4d239 | |||
9e402f8866 | |||
25bb89896c | |||
7fd107b320 | |||
ebe89356b5 | |||
5eb9a088fd | |||
1f565b3217 | |||
3ae2dc47e7 | |||
94999949d8 | |||
a8dee3a614 | |||
6da8fa60f5 | |||
e01449fa4b |
333
CMakeLists.txt
333
CMakeLists.txt
@@ -156,27 +156,51 @@ option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
|
||||
mark_as_advanced(WITH_GHOST_DEBUG)
|
||||
|
||||
option(WITH_GHOST_SDL "Enable building blender against SDL for windowing rather then the native APIs" OFF)
|
||||
option(WITH_GHOST_SDL "Enable building blender against SDL for windowing rather then the native APIs" OFF)
|
||||
mark_as_advanced(WITH_GHOST_SDL)
|
||||
|
||||
# Misc...
|
||||
option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
|
||||
mark_as_advanced(WITH_HEADLESS)
|
||||
|
||||
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
|
||||
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
|
||||
mark_as_advanced(WITH_AUDASPACE)
|
||||
|
||||
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
||||
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" ON)
|
||||
set(_WITH_X11 ON)
|
||||
else()
|
||||
set(_WITH_X11 OFF)
|
||||
endif()
|
||||
|
||||
option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
|
||||
option(WITH_X11 "Use X11 library (on any non-unix system this is for development purposes only)" ${_WITH_X11})
|
||||
unset(_WITH_X11)
|
||||
mark_as_advanced(WITH_X11)
|
||||
|
||||
if(WITH_X11)
|
||||
if(APPLE)
|
||||
set(_X11_EXTRAS OFF)
|
||||
else()
|
||||
set(_X11_EXTRAS ON)
|
||||
endif()
|
||||
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" _X11_EXTRAS)
|
||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" _X11_EXTRAS)
|
||||
|
||||
unset(_X11_EXTRAS)
|
||||
|
||||
option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
|
||||
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT_APPLE)
|
||||
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" ON)
|
||||
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
|
||||
else()
|
||||
# not an option for other OS's
|
||||
set(WITH_SYSTEM_GLEW OFF)
|
||||
set(WITH_SYSTEM_GLES OFF)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -315,6 +339,35 @@ endif()
|
||||
# Unit testsing
|
||||
option(WITH_GTESTS "Enable GTest unit testing" OFF)
|
||||
|
||||
# OpenGL
|
||||
|
||||
option(WITH_GLEW_MX "Support multiple GLEW contexts (experimental)" ON )
|
||||
option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
|
||||
option(WITH_GLU "Provide the GL Utility Library (GLU). Only works with the 'compatibiity' profile. (deprecated)" ON )
|
||||
option(WITH_GL_CONTEXT_DESKTOP "Support using the AGL/WGL/XGL system library to initialize OpenGL. Can access 3.2+ core, compatibility, and 2.0 ES profiles." ON )
|
||||
option(WITH_GL_CONTEXT_EMBEDDED "Support using the EGL system library to initialize OpenGL ES." OFF)
|
||||
option(WITH_GL_PROFILE_COMPAT "Support using the OpenGL 'compatibility' profile. (deprecated)" ON )
|
||||
option(WITH_GL_PROFILE_CORE "Support using the OpenGL 3.2+ 'core' profile." OFF)
|
||||
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (thru either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
|
||||
|
||||
mark_as_advanced(
|
||||
WITH_GLEW_MX
|
||||
WITH_GLEW_ES
|
||||
WITH_GLU
|
||||
WITH_GL_CONTEXT_DESKTOP
|
||||
WITH_GL_CONTEXT_EMBEDDED
|
||||
WITH_GL_PROFILE_COMPAT
|
||||
WITH_GL_PROFILE_CORE
|
||||
WITH_GL_PROFILE_ES20
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
option(WITH_ANGLE "Link with the ANGLE library, an OpenGL ES 2.0 implementation based on Direct3D, instead of the system OpenGL library." OFF)
|
||||
mark_as_advanced(WITH_ANGLE)
|
||||
endif()
|
||||
|
||||
# Apple
|
||||
|
||||
if(APPLE)
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
cmake_policy(VERSION 2.8.8)
|
||||
@@ -509,9 +562,10 @@ if(WITH_INSTALL_PORTABLE)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_X11 OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
endif()
|
||||
|
||||
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
@@ -593,6 +647,35 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
|
||||
#-----------------------------------------------------------------------------
|
||||
#Platform specifics
|
||||
|
||||
if(WITH_X11)
|
||||
find_package(X11 REQUIRED)
|
||||
|
||||
find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
|
||||
mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
|
||||
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
|
||||
|
||||
if(WITH_X11_XINPUT)
|
||||
if(X11_Xinput_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
|
||||
else()
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11_XF86VMODE)
|
||||
# XXX, why dont cmake make this available?
|
||||
FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
|
||||
mark_as_advanced(X11_Xxf86vmode_LIB)
|
||||
if(X11_Xxf86vmode_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xxf86vmode_LIB})
|
||||
else()
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
macro(find_package_wrapper)
|
||||
string(TOUPPER ${ARGV0} _NAME_UPPER)
|
||||
@@ -901,33 +984,6 @@ if(UNIX AND NOT APPLE)
|
||||
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
|
||||
list(APPEND PLATFORM_LINKLIBS -lutil -lc -lm -lpthread)
|
||||
|
||||
if((NOT WITH_HEADLESS) AND (NOT WITH_GHOST_SDL))
|
||||
find_package(X11 REQUIRED)
|
||||
find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
|
||||
mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
|
||||
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
|
||||
|
||||
if(WITH_X11_XINPUT)
|
||||
if(X11_Xinput_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
|
||||
else()
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11_XF86VMODE)
|
||||
# XXX, why dont cmake make this available?
|
||||
find_library(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
|
||||
mark_as_advanced(X11_Xxf86vmode_LIB)
|
||||
if(X11_Xxf86vmode_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xxf86vmode_LIB})
|
||||
else()
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if(NOT WITH_PYTHON_MODULE)
|
||||
# binreloc is linux only
|
||||
@@ -982,7 +1038,6 @@ elseif(WIN32)
|
||||
add_definitions(-DWIN32)
|
||||
|
||||
if(MSVC)
|
||||
|
||||
# needed for some MSVC installations
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||
@@ -1057,7 +1112,7 @@ elseif(WIN32)
|
||||
set(CXX_WARNINGS "${_WARNINGS}")
|
||||
unset(_WARNINGS)
|
||||
|
||||
set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
|
||||
set(PLATFORM_LINKFLAGS "/SAFESEH:NO /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
|
||||
|
||||
# MSVC only, Mingw doesnt need
|
||||
if(CMAKE_CL_64)
|
||||
@@ -1100,6 +1155,10 @@ elseif(WIN32)
|
||||
set(ZLIB_INCLUDE_DIR ${LIBDIR}/zlib/include)
|
||||
set(ZLIB_LIBRARY ${LIBDIR}/zlib/lib/libz_st.lib)
|
||||
set(ZLIB_DIR ${LIBDIR}/zlib)
|
||||
# XXX: Cmake bug(?) workaround for zlib and png:
|
||||
# FindPNG.cmake calls find_package(zlib) and for some reason that redundant call causes both zlib and png to not be found properly.
|
||||
# (Or, at least they complain, as this does not seem to cause a build error later)
|
||||
# Since zlib will be found by find_package(png), it should be OK to not call find_package(zlib) explicitly.
|
||||
#find_package(zlib) # we want to find before finding things that depend on it like png
|
||||
|
||||
|
||||
@@ -2069,10 +2128,113 @@ endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenGL.
|
||||
find_package(OpenGL)
|
||||
blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
|
||||
# unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake
|
||||
# unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake
|
||||
|
||||
if(APPLE AND WITH_X11)
|
||||
set(OPENGL_gl_LIBRARY "/usr/X11R6/lib/libGL.dylib")
|
||||
set(OPENGL_glu_LIBRARY "/usr/X11R6/lib/libGLU.dylib")
|
||||
elseif(WITH_GL_CONTEXT_DESKTOP OR WITH_GLU OR (WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI))
|
||||
find_package(OpenGL)
|
||||
endif()
|
||||
|
||||
if(WITH_GLU)
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_glu_LIBRARY}")
|
||||
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GLU")
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_GL_CONTEXT_DESKTOP)
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_gl_LIBRARY}")
|
||||
|
||||
elseif(WITH_GL_CONTEXT_EMBEDDED)
|
||||
if(WITH_SYSTEM_GLES)
|
||||
find_package_wrapper(OpenGLES)
|
||||
|
||||
if(OPENGLES_FOUND)
|
||||
list(APPEND BLENDER_GL_LIBRARIES OPENGLES_LIBRARIES)
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to find OpenGL ES libraries. Install them or disable WITH_SYSTEM_GLES.")
|
||||
endif()
|
||||
|
||||
else()
|
||||
set(OPENGLES_LIBRARY "" CACHE FILEPATH "OpenGL ES 2.0 library file")
|
||||
set(OPENGLES_EGL_LIBRARY "" CACHE FILEPATH "EGL library file")
|
||||
|
||||
mark_as_advanced(
|
||||
OPENGLES_LIBRARY
|
||||
OPENGLES_EGL_LIBRARY
|
||||
)
|
||||
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}" "${OPENGLES_EGL_LIBRARY}")
|
||||
|
||||
if (OPENGLES_LIBRARY STREQUAL "")
|
||||
message(FATAL_ERROR "To compile WITH_GL_CONTEXT_EMBEDDED you need to set OPENGLES_LIBRARY to the file path of an OpenGL ES 2.0 library.")
|
||||
endif()
|
||||
|
||||
if (OPENGLES_EGL_LIBRARY STREQUAL "")
|
||||
message(FATAL_ERROR "To compile WITH_GL_CONTEXT_EMBEDDED you need to set OPENGLES_EGL_LIBRARY to the file path of an EGL library.")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Setup paths to files needed to install and redistribute Windows Blender with OpenGL ES
|
||||
|
||||
set(OPENGLES_DLL "" CACHE FILEPATH "OpenGL ES 2.0 redistributable DLL file")
|
||||
set(OPENGLES_EGL_DLL "" CACHE FILEPATH "EGL redistributable DLL file")
|
||||
|
||||
mark_as_advanced(
|
||||
OPENGLES_DLL
|
||||
OPENGLES_EGL_DLL
|
||||
)
|
||||
|
||||
if (OPENGLES_DLL STREQUAL "")
|
||||
message(FATAL_ERROR "To compile WITH_GL_CONTEXT_EMBEDDED you need to set OPENGLES_DLL to the file path of an OpenGL ES runtime dynamic link library (DLL).")
|
||||
endif()
|
||||
|
||||
if (OPENGLES_EGL_DLL STREQUAL "")
|
||||
message(FATAL_ERROR "To compile WITH_GL_CONTEXT_EMBEDDED you need to set OPENGLES_EGL_DLL to the file path of an EGL runtime dynamic link library (DLL).")
|
||||
endif()
|
||||
|
||||
if(WITH_ANGLE)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_ANGLE")
|
||||
|
||||
set(D3DCOMPILER_DLL "" CACHE FILEPATH "Direct3D Compiler redistributable DLL file (needed by ANGLE)")
|
||||
|
||||
get_filename_component(D3DCOMPILER_FILENAME "${D3DCOMPILER_DLL}" NAME)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DD3DCOMPILER=\"\\\"${D3DCOMPILER_FILENAME}\\\"\"")
|
||||
|
||||
mark_as_advanced(D3DCOMPILER_DLL)
|
||||
|
||||
if (D3DCOMPILER_DLL STREQUAL "")
|
||||
message(FATAL_ERROR "To compile WITH_ANGLE you need to set D3DCOMPILER_DLL to the file path of a copy of the DirectX redistributable DLL file: D3DCompiler_46.dll")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_COMPAT)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GL_PROFILE_COMPAT")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_CORE)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GL_PROFILE_CORE")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GL_PROFILE_ES20")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_CONTEXT_DESKTOP)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GL_CONTEXT_DESKTOP")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_CONTEXT_EMBEDDED)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_GL_CONTEXT_EMBEDDED")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenMP.
|
||||
@@ -2094,19 +2256,88 @@ endif()
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure GLEW
|
||||
|
||||
if(WITH_GLEW_MX)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_MX")
|
||||
endif()
|
||||
|
||||
if(APPLE AND WITH_X11)
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_APPLE_GLX)
|
||||
endif()
|
||||
|
||||
if(WITH_SYSTEM_GLEW)
|
||||
find_package(GLEW)
|
||||
|
||||
# Note: There is an assumption here that the system GLEW is not a static library.
|
||||
|
||||
if(NOT GLEW_FOUND)
|
||||
message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW")
|
||||
message(FATAL_ERROR "GLEW is required to build Blender. Install it or disable WITH_SYSTEM_GLEW.")
|
||||
endif()
|
||||
|
||||
set(GLEW_INCLUDE_PATH "${GLEW_INCLUDE_DIRS}")
|
||||
mark_as_advanced(
|
||||
GLEW_LIBRARY
|
||||
GLEW_INCLUDE_PATH
|
||||
)
|
||||
|
||||
set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
|
||||
else()
|
||||
# set(GLEW_LIBRARY "") # unused
|
||||
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
|
||||
if(WITH_GLEW_ES)
|
||||
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew-es/include")
|
||||
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_STATIC -DWITH_GLEW_ES")
|
||||
|
||||
# These definitions remove APIs from glew.h, making GLEW smaller, and catching unguarded API usage
|
||||
if(NOT WITH_GL_PROFILE_ES20)
|
||||
# No ES functions are needed
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_NO_ES")
|
||||
elseif(NOT (WITH_GL_PROFILE_CORE OR WITH_GL_PROFILE_COMPAT))
|
||||
# ES is enabled, but the other functions are all disabled
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_ES_ONLY")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
if(WITH_GL_CONTEXT_EMBEDDED)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_USE_LIB_ES20")
|
||||
endif()
|
||||
|
||||
# XXX: This is an experiment to eliminate ES 1 symbols,
|
||||
# GLEW doesn't really properly provide this level of control
|
||||
# (for example, without modification it eliminates too many symbols)
|
||||
# so there are lots of modifications to GLEW to make this work,
|
||||
# and no attempt to make it work beyond Blender at this point.
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGL_ES_VERSION_1_0=0")
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGL_ES_VERSION_CL_1_1=0")
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGL_ES_VERSION_CM_1_1=0")
|
||||
endif()
|
||||
|
||||
if(WITH_GL_CONTEXT_EMBEDDED)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_INC_EGL")
|
||||
endif()
|
||||
|
||||
set(BLENDER_GLEW_LIBRARIES extern_glew_es bf_intern_glew_mx)
|
||||
|
||||
else()
|
||||
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
|
||||
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_STATIC")
|
||||
|
||||
# This won't affect the non-experimental glew library,
|
||||
# but is used for conditional compilation elsewhere.
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_NO_ES")
|
||||
|
||||
set(BLENDER_GLEW_LIBRARIES extern_glew)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_GLEW_MX)
|
||||
list(APPEND BLENDER_GLEW_LIBRARIES bf_intern_glew_mx)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_GLU)
|
||||
set(GL_DEFINITIONS "${GL_DEFINITIONS} -DGLEW_NO_GLU")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Bullet
|
||||
@@ -2472,6 +2703,18 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_MOD_FLUID)
|
||||
info_cfg_option(WITH_MOD_OCEANSIM)
|
||||
|
||||
info_cfg_text("OpenGL:")
|
||||
info_cfg_option(WITH_GLEW_ES)
|
||||
info_cfg_option(WITH_GLU)
|
||||
info_cfg_option(WITH_GL_CONTEXT_DESKTOP)
|
||||
info_cfg_option(WITH_GL_CONTEXT_EMBEDDED)
|
||||
info_cfg_option(WITH_GL_PROFILE_COMPAT)
|
||||
info_cfg_option(WITH_GL_PROFILE_CORE)
|
||||
info_cfg_option(WITH_GL_PROFILE_ES20)
|
||||
if(WIN32)
|
||||
info_cfg_option(WITH_ANGLE)
|
||||
endif()
|
||||
|
||||
info_cfg_text("Other:")
|
||||
info_cfg_option(WITH_OPENNL)
|
||||
|
||||
|
51
build_files/cmake/Modules/FindOpenGLES.cmake
Normal file
51
build_files/cmake/Modules/FindOpenGLES.cmake
Normal file
@@ -0,0 +1,51 @@
|
||||
# - Try to find OpenGLES
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENGLES_FOUND - system has OpenGLES and EGL
|
||||
# OPENGL_EGL_FOUND - system has EGL
|
||||
# OPENGLES_INCLUDE_DIR - the GLES include directory
|
||||
# OPENGLES_LIBRARY - the GLES library
|
||||
# OPENGLES_EGL_INCLUDE_DIR - the EGL include directory
|
||||
# OPENGLES_EGL_LIBRARY - the EGL library
|
||||
# OPENGLES_LIBRARIES - all libraries needed for OpenGLES
|
||||
# OPENGLES_INCLUDES - all includes needed for OpenGLES
|
||||
|
||||
FIND_PATH(OPENGLES_INCLUDE_DIR GLES2/gl2.h
|
||||
/usr/openwin/share/include
|
||||
/opt/graphics/OpenGL/include /usr/X11R6/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENGLES_LIBRARY
|
||||
NAMES GLESv2
|
||||
PATHS /opt/graphics/OpenGL/lib
|
||||
/usr/openwin/lib
|
||||
/usr/shlib /usr/X11R6/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
FIND_PATH(OPENGLES_EGL_INCLUDE_DIR EGL/egl.h
|
||||
/usr/openwin/share/include
|
||||
/opt/graphics/OpenGL/include /usr/X11R6/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENGLES_EGL_LIBRARY
|
||||
NAMES EGL
|
||||
PATHS /usr/shlib /usr/X11R6/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
SET(OPENGL_EGL_FOUND "NO")
|
||||
IF(OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR)
|
||||
SET(OPENGL_EGL_FOUND "YES")
|
||||
ENDIF()
|
||||
|
||||
SET(OPENGLES_FOUND "NO")
|
||||
IF(OPENGLES_LIBRARY AND OPENGLES_INCLUDE_DIR AND
|
||||
OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR)
|
||||
SET(OPENGLES_LIBRARIES ${OPENGLES_LIBRARY} ${OPENGLES_LIBRARIES}
|
||||
${OPENGLES_EGL_LIBRARY})
|
||||
SET(OPENGLES_INCLUDES ${OPENGLES_INCLUDE_DIR} ${OPENGLES_EGL_INCLUDE_DIR})
|
||||
SET(OPENGLES_FOUND "YES")
|
||||
ENDIF()
|
@@ -60,7 +60,8 @@ if(EXISTS ${SOURCE_DIR}/.git)
|
||||
execute_process(COMMAND git log HEAD..@{u}
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE _git_below_check
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
if(NOT _git_below_check STREQUAL "")
|
||||
# If there're commits between HEAD and upstream this means
|
||||
# that we're reset-ed to older revision. Use it's hash then.
|
||||
|
@@ -284,8 +284,7 @@ macro(setup_liblinks
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
|
||||
target_link_libraries(${target}
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${OPENGL_glu_LIBRARY}
|
||||
${BLENDER_GL_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${FREETYPE_LIBRARY})
|
||||
@@ -305,7 +304,7 @@ macro(setup_liblinks
|
||||
endif()
|
||||
|
||||
if(WITH_SYSTEM_GLEW)
|
||||
target_link_libraries(${target} ${GLEW_LIBRARY})
|
||||
target_link_libraries(${target} ${BLENDER_GLEW_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
||||
target_link_libraries(${target} ${BULLET_LIBRARIES})
|
||||
@@ -359,9 +358,12 @@ macro(setup_liblinks
|
||||
endif()
|
||||
if(WITH_CODEC_FFMPEG)
|
||||
|
||||
# Strange!, without this ffmpeg gives linking errors (on linux)
|
||||
# even though its linked above
|
||||
target_link_libraries(${target} ${OPENGL_glu_LIBRARY})
|
||||
# Strange! Without this ffmpeg gives linking errors (on linux),
|
||||
# even though it's linked above.
|
||||
# XXX: Does FFMPEG depend on GLU?
|
||||
if(WITH_GLU)
|
||||
target_link_libraries(${target} ${OPENGL_glu_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${target} ${FFMPEG_LIBRARIES})
|
||||
endif()
|
||||
@@ -574,7 +576,7 @@ macro(SETUP_BLENDER_SORTED_LIBS)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
list(APPEND BLENDER_SORTED_LIBS extern_glew)
|
||||
list(APPEND BLENDER_SORTED_LIBS ${BLENDER_GLEW_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_BINRELOC)
|
||||
|
15
extern/CMakeLists.txt
vendored
15
extern/CMakeLists.txt
vendored
@@ -47,7 +47,14 @@ if(WITH_BINRELOC)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
add_subdirectory(glew)
|
||||
if((NOT WITH_GLEW_ES) OR (WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI))
|
||||
add_subdirectory(glew)
|
||||
endif()
|
||||
|
||||
if(WITH_GLEW_ES)
|
||||
add_subdirectory(glew-es)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_GAMEENGINE)
|
||||
@@ -79,10 +86,8 @@ if(WITH_MOD_BOOLEAN)
|
||||
add_subdirectory(carve)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_XDND)
|
||||
if(UNIX AND NOT APPLE)
|
||||
add_subdirectory(xdnd)
|
||||
endif()
|
||||
if(WITH_X11 AND WITH_GHOST_XDND)
|
||||
add_subdirectory(xdnd)
|
||||
endif()
|
||||
|
||||
if(WITH_GTESTS)
|
||||
|
52
extern/glew-es/CMakeLists.txt
vendored
Normal file
52
extern/glew-es/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2013, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jason Wilkins
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
list(APPEND INC_SYS
|
||||
${X11_X11_INCLUDE_PATH}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
src/glew.c
|
||||
|
||||
include/GL/eglew.h
|
||||
include/GL/glesew.h
|
||||
include/GL/glew.h
|
||||
include/GL/glxew.h
|
||||
include/GL/wglew.h
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(extern_glew_es "${SRC}" "${INC}" "${INC_SYS}")
|
1466
extern/glew-es/include/GL/eglew.h
vendored
Normal file
1466
extern/glew-es/include/GL/eglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4318
extern/glew-es/include/GL/glesew.h
vendored
Normal file
4318
extern/glew-es/include/GL/glesew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20525
extern/glew-es/include/GL/glew.h
vendored
Normal file
20525
extern/glew-es/include/GL/glew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1649
extern/glew-es/include/GL/glxew.h
vendored
Normal file
1649
extern/glew-es/include/GL/glxew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1424
extern/glew-es/include/GL/wglew.h
vendored
Normal file
1424
extern/glew-es/include/GL/wglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22405
extern/glew-es/src/glew.c
vendored
Normal file
22405
extern/glew-es/src/glew.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
extern/glew/CMakeLists.txt
vendored
2
extern/glew/CMakeLists.txt
vendored
@@ -45,6 +45,6 @@ set(SRC
|
||||
include/GL/wglew.h
|
||||
)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(extern_glew "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -31,6 +31,7 @@ add_subdirectory(memutil)
|
||||
add_subdirectory(opencolorio)
|
||||
add_subdirectory(mikktspace)
|
||||
add_subdirectory(raskter)
|
||||
add_subdirectory(glew-mx)
|
||||
|
||||
if(WITH_AUDASPACE)
|
||||
add_subdirectory(audaspace)
|
||||
|
@@ -20,9 +20,9 @@ set(LIBRARIES
|
||||
cycles_subd
|
||||
cycles_util
|
||||
${BOOST_LIBRARIES}
|
||||
${OPENEXR_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
${CYCLES_GLEW_LIBRARY}
|
||||
${CYCLES_APP_GLEW_LIBRARY}
|
||||
bf_intern_glew_mx
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${JPEG_LIBRARIES}
|
||||
@@ -32,6 +32,8 @@ set(LIBRARIES
|
||||
extern_cuew
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND LIBRARIES ${PTHREADS_LIBRARIES})
|
||||
endif()
|
||||
@@ -55,14 +57,30 @@ if(WITH_CYCLES_STANDALONE)
|
||||
cycles_xml.cpp
|
||||
cycles_xml.h
|
||||
)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
|
||||
|
||||
add_executable(cycles ${SRC})
|
||||
|
||||
list(APPEND LIBRARIES ${PLATFORM_LINKLIBS})
|
||||
target_link_libraries(cycles ${LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
|
||||
if(WIN32 AND NOT UNIX AND NOT CMAKE_COMPILER_IS_GNUCC)
|
||||
file_list_suffix(OPENEXR_LIBRARIES_DEBUG "${OPENEXR_LIBRARIES}" "_d")
|
||||
target_link_libraries_debug(cycles "${OPENEXR_LIBRARIES_DEBUG}")
|
||||
target_link_libraries_optimized(cycles "${OPENEXR_LIBRARIES}")
|
||||
unset(OPENEXR_LIBRARIES_DEBUG)
|
||||
else()
|
||||
target_link_libraries(cycles ${OPENEXR_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
set_target_properties(cycles PROPERTIES INSTALL_RPATH $ORIGIN/lib)
|
||||
endif()
|
||||
|
||||
unset(SRC)
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
@@ -77,4 +95,3 @@ if(WITH_CYCLES_NETWORK)
|
||||
endif()
|
||||
unset(SRC)
|
||||
endif()
|
||||
|
||||
|
@@ -6,6 +6,7 @@ set(INC
|
||||
../kernel/svm
|
||||
../util
|
||||
../subd
|
||||
../../glew-mx
|
||||
../../guardedalloc
|
||||
../../mikktspace
|
||||
../../../source/blender/makesdna
|
||||
@@ -46,7 +47,7 @@ set(ADDON_FILES
|
||||
addon/version_update.py
|
||||
)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
###########################################################################
|
||||
# GLUT
|
||||
|
||||
@@ -14,10 +13,15 @@ if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_SYSTEM_GLEW)
|
||||
set(CYCLES_GLEW_LIBRARY ${GLEW_LIBRARY})
|
||||
else()
|
||||
set(CYCLES_GLEW_LIBRARY extern_glew)
|
||||
###########################################################################
|
||||
# GLEW
|
||||
|
||||
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
|
||||
if(WITH_SYSTEM_GLEW)
|
||||
set(CYCLES_APP_GLEW_LIBRARY ${GLEW_LIBRARY})
|
||||
else()
|
||||
set(CYCLES_APP_GLEW_LIBRARY extern_glew) # Cycles Standalone should not use the experimental glew-es
|
||||
endif()
|
||||
endif()
|
||||
|
||||
###########################################################################
|
||||
@@ -32,4 +36,3 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
set(WITH_CYCLES_CUDA_BINARIES OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@@ -6,10 +6,10 @@ set(INC
|
||||
../kernel/osl
|
||||
../util
|
||||
../render
|
||||
../../glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
../../../extern/cuew/include
|
||||
../../../extern/clew/include
|
||||
@@ -38,7 +38,7 @@ set(SRC_HEADERS
|
||||
device_task.h
|
||||
)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
include_directories(${INC})
|
||||
include_directories(SYSTEM ${INC_SYS})
|
||||
|
@@ -128,8 +128,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if(transparent)
|
||||
if (transparent) {
|
||||
glDisable(GL_BLEND);
|
||||
glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
|
||||
|
@@ -922,9 +922,11 @@ public:
|
||||
draw_params.unbind_display_space_shader_cb();
|
||||
}
|
||||
|
||||
if(transparent)
|
||||
if (transparent) {
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
|
@@ -7,6 +7,7 @@ set(INC
|
||||
../kernel/osl
|
||||
../bvh
|
||||
../util
|
||||
../../glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -76,5 +77,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
|
||||
include_directories(${INC})
|
||||
include_directories(SYSTEM ${INC_SYS})
|
||||
|
||||
add_library(cycles_render ${SRC} ${SRC_HEADERS})
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
add_library(cycles_render ${SRC} ${SRC_HEADERS})
|
||||
|
@@ -1,11 +1,11 @@
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
@@ -69,4 +69,6 @@ set(SRC_HEADERS
|
||||
include_directories(${INC})
|
||||
include_directories(SYSTEM ${INC_SYS})
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
add_library(cycles_util ${SRC} ${SRC_HEADERS})
|
||||
|
@@ -20,7 +20,6 @@
|
||||
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
|
||||
* platform differences in one central place. */
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include "glew-mx.h"
|
||||
|
||||
#endif /* __UTIL_OPENGL_H__ */
|
||||
|
||||
|
@@ -66,7 +66,6 @@ void view_display_info(const char *info)
|
||||
const int height = 20;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
|
||||
glRectf(0.0f, V.height - height, V.width, V.height);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -90,7 +89,6 @@ void view_display_help()
|
||||
const int y2 = y1 + h;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
|
||||
glRectf(x1, y1, x2, y2);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -248,10 +246,13 @@ void view_main_loop(const char *title, int width, int height,
|
||||
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
|
||||
glutCreateWindow(title);
|
||||
|
||||
glewSetContext(glewCreateContext());
|
||||
glewInit();
|
||||
|
||||
view_reshape(width, height);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glutDisplayFunc(view_display);
|
||||
glutIdleFunc(view_idle);
|
||||
glutReshapeFunc(view_reshape);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
set(INC
|
||||
.
|
||||
../glew-mx
|
||||
../string
|
||||
../../source/blender/imbuf
|
||||
../../source/blender/makesdna
|
||||
@@ -38,6 +39,8 @@ set(SRC
|
||||
intern/GHOST_Buttons.cpp
|
||||
intern/GHOST_C-api.cpp
|
||||
intern/GHOST_CallbackEventConsumer.cpp
|
||||
intern/GHOST_Context.cpp
|
||||
intern/GHOST_ContextNone.cpp
|
||||
intern/GHOST_DisplayManager.cpp
|
||||
intern/GHOST_EventManager.cpp
|
||||
intern/GHOST_ISystem.cpp
|
||||
@@ -63,6 +66,8 @@ set(SRC
|
||||
|
||||
intern/GHOST_Buttons.h
|
||||
intern/GHOST_CallbackEventConsumer.h
|
||||
intern/GHOST_Context.h
|
||||
intern/GHOST_ContextNone.h
|
||||
intern/GHOST_Debug.h
|
||||
intern/GHOST_DisplayManager.h
|
||||
intern/GHOST_Event.h
|
||||
@@ -128,60 +133,38 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
|
||||
add_definitions(-DWITH_GHOST_SDL)
|
||||
endif()
|
||||
|
||||
|
||||
# ack, this is still system dependent
|
||||
if(APPLE)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsCocoa.mm
|
||||
intern/GHOST_SystemPathsCocoa.h
|
||||
)
|
||||
|
||||
elseif(UNIX)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsX11.cpp
|
||||
intern/GHOST_SystemPathsX11.h
|
||||
)
|
||||
|
||||
if(NOT WITH_INSTALL_PORTABLE)
|
||||
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
|
||||
elseif(WIN32)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsWin32.cpp
|
||||
|
||||
intern/GHOST_SystemPathsWin32.h
|
||||
)
|
||||
|
||||
list(APPEND INC
|
||||
../utfconv
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_HEADLESS)
|
||||
list(APPEND INC_SYS
|
||||
${SDL_INCLUDE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
elseif(APPLE)
|
||||
elseif(APPLE AND NOT WITH_X11)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_DisplayManagerCocoa.mm
|
||||
intern/GHOST_SystemCocoa.mm
|
||||
intern/GHOST_SystemPathsCocoa.mm
|
||||
intern/GHOST_WindowCocoa.mm
|
||||
|
||||
intern/GHOST_DisplayManagerCocoa.h
|
||||
intern/GHOST_SystemCocoa.h
|
||||
intern/GHOST_SystemPathsCocoa.h
|
||||
intern/GHOST_WindowCocoa.h
|
||||
)
|
||||
|
||||
if (WITH_GL_CONTEXT_DESKTOP)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextCGL.mm
|
||||
|
||||
intern/GHOST_ContextCGL.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_INPUT_NDOF)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_NDOFManagerCocoa.mm
|
||||
|
||||
intern/GHOST_NDOFManagerCocoa.h
|
||||
)
|
||||
|
||||
list(APPEND SRC_NDOF3DCONNEXION
|
||||
intern/GHOST_NDOFManager3Dconnexion.c
|
||||
intern/GHOST_NDOFManager3Dconnexion.h
|
||||
@@ -192,8 +175,7 @@ elseif(APPLE)
|
||||
add_definitions(-DWITH_QUICKTIME)
|
||||
endif()
|
||||
|
||||
elseif(UNIX)
|
||||
|
||||
elseif(WITH_X11)
|
||||
list(APPEND INC_SYS
|
||||
${X11_X11_INCLUDE_PATH}
|
||||
)
|
||||
@@ -201,15 +183,21 @@ elseif(UNIX)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_DisplayManagerX11.cpp
|
||||
intern/GHOST_SystemX11.cpp
|
||||
intern/GHOST_SystemPathsX11.cpp
|
||||
intern/GHOST_WindowX11.cpp
|
||||
|
||||
intern/GHOST_DisplayManagerX11.h
|
||||
intern/GHOST_SystemX11.h
|
||||
intern/GHOST_SystemPathsX11.h
|
||||
intern/GHOST_WindowX11.h
|
||||
)
|
||||
|
||||
if (WITH_GL_CONTEXT_DESKTOP)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextGLX.cpp
|
||||
|
||||
intern/GHOST_ContextGLX.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_XDND)
|
||||
add_definitions(-DWITH_XDND)
|
||||
|
||||
@@ -257,6 +245,8 @@ elseif(UNIX)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(-DWITH_X11)
|
||||
|
||||
elseif(WIN32)
|
||||
## Warnings as errors, this is too strict!
|
||||
#if(MSVC)
|
||||
@@ -274,18 +264,24 @@ elseif(WIN32)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_DisplayManagerWin32.cpp
|
||||
intern/GHOST_SystemWin32.cpp
|
||||
intern/GHOST_SystemPathsWin32.cpp
|
||||
intern/GHOST_WindowWin32.cpp
|
||||
intern/GHOST_DropTargetWin32.cpp
|
||||
|
||||
intern/GHOST_DisplayManagerWin32.h
|
||||
intern/GHOST_DropTargetWin32.h
|
||||
intern/GHOST_SystemWin32.h
|
||||
intern/GHOST_SystemPathsWin32.h
|
||||
intern/GHOST_WindowWin32.h
|
||||
intern/GHOST_TaskbarWin32.h
|
||||
)
|
||||
|
||||
if (WITH_GL_CONTEXT_DESKTOP)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextWGL.cpp
|
||||
|
||||
intern/GHOST_ContextWGL.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_INPUT_NDOF)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_NDOFManagerWin32.cpp
|
||||
@@ -296,7 +292,42 @@ elseif(WIN32)
|
||||
|
||||
endif()
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
if(WITH_GL_CONTEXT_EMBEDDED AND NOT (WITH_HEADLESS OR WITH_GHOST_SDL))
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextEGL.cpp
|
||||
|
||||
intern/GHOST_ContextEGL.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsCocoa.mm
|
||||
intern/GHOST_SystemPathsCocoa.h
|
||||
)
|
||||
|
||||
elseif(UNIX)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsX11.cpp
|
||||
intern/GHOST_SystemPathsX11.h
|
||||
)
|
||||
|
||||
if(NOT WITH_INSTALL_PORTABLE)
|
||||
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
|
||||
elseif(WIN32)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_SystemPathsWin32.cpp
|
||||
intern/GHOST_SystemPathsWin32.h
|
||||
)
|
||||
|
||||
list(APPEND INC
|
||||
../utfconv
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
||||
|
@@ -674,9 +674,16 @@ extern GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return An integer.
|
||||
* \param pointer to location to store the swap interval if successful
|
||||
* \return Whether the swap interval was successfully read.
|
||||
*/
|
||||
extern int GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle);
|
||||
extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return Number of AA Samples (0 if there is no multisample buffer)
|
||||
*/
|
||||
extern GHOST_TUns16 GHOST_GetNumOfAASamples(GHOST_WindowHandle windowhandle);
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
|
@@ -212,9 +212,16 @@ public:
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return An integer.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
virtual int getSwapInterval() = 0;
|
||||
virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return Number of AA Samples (0 if there is no multisample buffer)
|
||||
*/
|
||||
virtual GHOST_TUns16 getNumOfAASamples() = 0;
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
|
@@ -144,15 +144,9 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
|
||||
bool bstereoVisual;
|
||||
|
||||
if (stereoVisual)
|
||||
bstereoVisual = true;
|
||||
else
|
||||
bstereoVisual = false;
|
||||
|
||||
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
|
||||
state, type, bstereoVisual, false,
|
||||
state, type, stereoVisual != 0, false,
|
||||
numOfAASamples);
|
||||
}
|
||||
|
||||
@@ -698,14 +692,21 @@ GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int interv
|
||||
return window->setSwapInterval(interval);
|
||||
}
|
||||
|
||||
int GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle)
|
||||
GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int* intervalOut)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
|
||||
|
||||
return window->getSwapInterval();
|
||||
return window->getSwapInterval(*intervalOut);
|
||||
}
|
||||
|
||||
|
||||
GHOST_TUns16 GHOST_GetNumOfAASamples(GHOST_WindowHandle windowhandle)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
|
||||
|
||||
return window->getNumOfAASamples();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
|
||||
|
152
intern/ghost/intern/GHOST_Context.cpp
Normal file
152
intern/ghost/intern/GHOST_Context.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_Context.cpp
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_Context class.
|
||||
*/
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
|
||||
static const char* get_glew_error_message_string(GLenum error)
|
||||
{
|
||||
switch (error) {
|
||||
case GLEW_OK: /* also GLEW_NO_ERROR */
|
||||
return "OK";
|
||||
|
||||
case GLEW_ERROR_NO_GL_VERSION:
|
||||
return "Unable to determine GL version.";
|
||||
|
||||
case GLEW_ERROR_GL_VERSION_10_ONLY:
|
||||
return "OpenGL 1.1 or later is required.";
|
||||
|
||||
case GLEW_ERROR_GLX_VERSION_11_ONLY:
|
||||
return "GLX 1.2 or later is required.";
|
||||
|
||||
#ifdef WITH_GLEW_ES
|
||||
case GLEW_ERROR_NOT_GLES_VERSION:
|
||||
return "OpenGL ES is required.";
|
||||
|
||||
case GLEW_ERROR_GLES_VERSION:
|
||||
return "A non-ES version of OpenGL is required.";
|
||||
|
||||
case GLEW_ERROR_NO_EGL_VERSION:
|
||||
return "Unabled to determine EGL version.";
|
||||
|
||||
case GLEW_ERROR_EGL_VERSION_10_ONLY:
|
||||
return "EGL 1.1 or later is required.";
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char* get_glew_error_enum_string(GLenum error)
|
||||
{
|
||||
switch (error) {
|
||||
case GLEW_OK: /* also GLEW_NO_ERROR */
|
||||
return "GLEW_OK";
|
||||
|
||||
case GLEW_ERROR_NO_GL_VERSION:
|
||||
return "GLEW_ERROR_NO_GL_VERSION";
|
||||
|
||||
case GLEW_ERROR_GL_VERSION_10_ONLY:
|
||||
return "GLEW_ERROR_GL_VERSION_10_ONLY";
|
||||
|
||||
case GLEW_ERROR_GLX_VERSION_11_ONLY:
|
||||
return "GLEW_ERROR_GLX_VERSION_11_ONLY";
|
||||
|
||||
#ifdef WITH_GLEW_ES
|
||||
case GLEW_ERROR_NOT_GLES_VERSION:
|
||||
return "GLEW_ERROR_NOT_GLES_VERSION";
|
||||
|
||||
case GLEW_ERROR_GLES_VERSION:
|
||||
return "GLEW_ERROR_GLES_VERSION";
|
||||
|
||||
case GLEW_ERROR_NO_EGL_VERSION:
|
||||
return "GLEW_ERROR_NO_EGL_VERSION";
|
||||
|
||||
case GLEW_ERROR_EGL_VERSION_10_ONLY:
|
||||
return "GLEW_ERROR_EGL_VERSION_10_ONLY";
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLenum glew_chk(GLenum error, const char* file, int line, const char* text)
|
||||
{
|
||||
if (error != GLEW_OK) {
|
||||
const char* code = get_glew_error_enum_string(error);
|
||||
const char* msg = get_glew_error_message_string(error);
|
||||
|
||||
#ifndef NDEBUG
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s(%d):[%s] -> GLEW Error (0x%04X): %s: %s\n",
|
||||
file,
|
||||
line,
|
||||
text,
|
||||
error,
|
||||
code ? code : "<no symbol>",
|
||||
msg ? msg : "<no message>");
|
||||
#else
|
||||
fprintf(
|
||||
stderr,
|
||||
"GLEW Error (%04X): %s: %s\n",
|
||||
error,
|
||||
code ? code : "<no symbol>",
|
||||
msg ? msg : "<no message>");
|
||||
#endif
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GHOST_Context::initContextGLEW()
|
||||
{
|
||||
glewDestroyContext(m_glewContext);
|
||||
|
||||
glewSetContext(glewCreateContext());
|
||||
|
||||
m_glewContext = glewGetContext();
|
||||
|
||||
GLEW_CHK(glewInit());
|
||||
}
|
157
intern/ghost/intern/GHOST_Context.h
Normal file
157
intern/ghost/intern/GHOST_Context.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_Context.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_Context class.
|
||||
*/
|
||||
|
||||
#ifndef __GHOST_CONTEXT_H__
|
||||
#define __GHOST_CONTEXT_H__
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
|
||||
#include "glew-mx.h"
|
||||
|
||||
#include <cstdlib> // for NULL
|
||||
|
||||
|
||||
|
||||
class GHOST_Context
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* \param stereoVisual Stereo visual for quad buffered stereo.
|
||||
* \param numOfAASamples Number of samples used for AA (zero if no AA)
|
||||
*/
|
||||
GHOST_Context(bool stereoVisual, GHOST_TUns16 numOfAASamples)
|
||||
: m_stereoVisual (stereoVisual)
|
||||
, m_numOfAASamples(numOfAASamples)
|
||||
, m_glewContext(NULL)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~GHOST_Context() {
|
||||
glewDestroyContext(m_glewContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers() = 0;
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext() = 0;
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext() = 0;
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window. Needed
|
||||
* whenever the window is changed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess updateDrawingContext() {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if it is OK for a remove the native display
|
||||
* \return Indication as to whether removal has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles() = 0;
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
virtual GHOST_TSuccess getSwapInterval(int&) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
/** Stereo visual created. Only necessary for 'real' stereo support,
|
||||
* ie quad buffered stereo. This is not always possible, depends on
|
||||
* the graphics h/w
|
||||
*/
|
||||
inline bool isStereoVisual() const {
|
||||
return m_stereoVisual;
|
||||
}
|
||||
|
||||
/** Number of samples used in anti-aliasing, set to 0 if no AA **/
|
||||
inline GHOST_TUns16 getNumOfAASamples() const {
|
||||
return m_numOfAASamples;
|
||||
}
|
||||
|
||||
protected:
|
||||
void initContextGLEW();
|
||||
|
||||
inline void activateGLEW() const {
|
||||
glewSetContext(m_glewContext);
|
||||
}
|
||||
|
||||
bool m_stereoVisual;
|
||||
|
||||
GHOST_TUns16 m_numOfAASamples;
|
||||
|
||||
private:
|
||||
GLEWContext* m_glewContext;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
GLenum glew_chk(GLenum error, const char* file, int line, const char* text);
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define GLEW_CHK(x) glew_chk((x), __FILE__, __LINE__, #x)
|
||||
#else
|
||||
#define GLEW_CHK(x) x
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // __GHOST_CONTEXT_H__
|
161
intern/ghost/intern/GHOST_ContextCGL.h
Normal file
161
intern/ghost/intern/GHOST_ContextCGL.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextCGL.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_ContextCGL class.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_CONTEXTCGL_H_
|
||||
#define _GHOST_CONTEXTCGL_H_
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
//#define cglewGetContext() cglewContext
|
||||
//#include <GL/cglew.h>
|
||||
//extern "C" CGLEWContext* cglewContext;
|
||||
|
||||
|
||||
|
||||
#ifndef GHOST_OPENGL_CGL_CONTEXT_FLAGS
|
||||
#define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY
|
||||
#define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@class NSWindow;
|
||||
@class NSOpenGLView;
|
||||
@class NSOpenGLContext;
|
||||
|
||||
|
||||
|
||||
class GHOST_ContextCGL : public GHOST_Context
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ContextCGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
NSWindow *window,
|
||||
NSOpenGLView *openGLView,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~GHOST_ContextCGL();
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
virtual GHOST_TSuccess getSwapInterval(int&);
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window.
|
||||
* Needed whenever the window is changed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
//protected:
|
||||
// inline void activateCGLEW() const {
|
||||
// cglewContext = m_cglewContext;
|
||||
// }
|
||||
|
||||
private:
|
||||
//void initContextCGLEW()
|
||||
|
||||
/** The window containing the OpenGL view */
|
||||
NSWindow *m_window;
|
||||
|
||||
/** The openGL view */
|
||||
NSOpenGLView *m_openGLView;
|
||||
|
||||
const int m_contextProfileMask;
|
||||
const int m_contextMajorVersion;
|
||||
const int m_contextMinorVersion;
|
||||
const int m_contextFlags;
|
||||
const int m_contextResetNotificationStrategy;
|
||||
|
||||
/** The opgnGL drawing context */
|
||||
NSOpenGLContext *m_openGLContext;
|
||||
|
||||
//static CGLEWContext* s_cglewContext;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static NSOpenGLContext *s_sharedOpenGLContext;
|
||||
static int s_sharedCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _GHOST_CONTEXTCGL_H_
|
364
intern/ghost/intern/GHOST_ContextCGL.mm
Normal file
364
intern/ghost/intern/GHOST_ContextCGL.mm
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextCGL.mm
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_ContextCGL class.
|
||||
*/
|
||||
|
||||
#include "GHOST_ContextCGL.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#ifdef GHOST_MULTITHREADED_OPENGL
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil;
|
||||
int GHOST_ContextCGL::s_sharedCount = 0;
|
||||
|
||||
|
||||
|
||||
GHOST_ContextCGL::GHOST_ContextCGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
NSWindow *window,
|
||||
NSOpenGLView *openGLView,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
)
|
||||
: GHOST_Context(stereoVisual, numOfAASamples)
|
||||
, m_window (window)
|
||||
, m_openGLView(openGLView)
|
||||
, m_contextProfileMask (contextProfileMask)
|
||||
, m_contextMajorVersion (contextMajorVersion)
|
||||
, m_contextMinorVersion (contextMinorVersion)
|
||||
, m_contextFlags (contextFlags)
|
||||
, m_contextResetNotificationStrategy(contextResetNotificationStrategy)
|
||||
, m_openGLContext(nil)
|
||||
{
|
||||
assert(window != nil);
|
||||
assert(openGLView != nil);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_ContextCGL::~GHOST_ContextCGL()
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
if (m_openGLContext == [NSOpenGLContext currentContext])
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
[m_openGLView clearGLContext];
|
||||
|
||||
if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
|
||||
assert(s_sharedCount > 0);
|
||||
|
||||
s_sharedCount--;
|
||||
|
||||
if (s_sharedCount == 0)
|
||||
s_sharedOpenGLContext = nil;
|
||||
|
||||
[m_openGLContext release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::swapBuffers()
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext flushBuffer];
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::setSwapInterval(int interval)
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
GLint interval;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
[pool drain];
|
||||
|
||||
intervalOut = static_cast<int>(interval);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext()
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext makeCurrentContext];
|
||||
|
||||
activateGLEW();
|
||||
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
|
||||
{
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext update];
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void makeAttribList(
|
||||
std::vector<NSOpenGLPixelFormatAttribute>& attribs,
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil)
|
||||
{
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
||||
|
||||
// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext object's flushBuffer
|
||||
// needed for 'Draw Overlap' drawing method
|
||||
attribs.push_back(NSOpenGLPFABackingStore);
|
||||
|
||||
// Force software OpenGL, for debugging
|
||||
if (getenv("BLENDER_SOFTWAREGL")) { // XXX jwilkins: fixed this to work on Intel macs? useful feature for Windows and Linux too? Maybe a command line flag is better...
|
||||
attribs.push_back(NSOpenGLPFARendererID);
|
||||
#if defined(__ppc__) || defined(__ppc64__)
|
||||
attribs.push_back(kCGLRendererAppleSWID);
|
||||
#else
|
||||
attribs.push_back(kCGLRendererGenericFloatID);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
attribs.push_back(NSOpenGLPFAAccelerated);
|
||||
}
|
||||
|
||||
//attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
attribs.push_back(NSOpenGLPFADepthSize);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
|
||||
|
||||
if (stereoVisual)
|
||||
attribs.push_back(NSOpenGLPFAStereo);
|
||||
|
||||
if (needAlpha) {
|
||||
attribs.push_back(NSOpenGLPFAAlphaSize);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
|
||||
}
|
||||
|
||||
if (needStencil) {
|
||||
attribs.push_back(NSOpenGLPFAStencilSize);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
|
||||
}
|
||||
|
||||
if (numOfAASamples > 0) {
|
||||
// Multisample anti-aliasing
|
||||
attribs.push_back(NSOpenGLPFAMultisample);
|
||||
|
||||
attribs.push_back(NSOpenGLPFASampleBuffers);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 1);
|
||||
|
||||
attribs.push_back(NSOpenGLPFASamples);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples);
|
||||
|
||||
attribs.push_back(NSOpenGLPFANoRecovery);
|
||||
}
|
||||
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
std::vector<NSOpenGLPixelFormatAttribute> attribs;
|
||||
attribs.reserve(40);
|
||||
|
||||
NSOpenGLContext *prev_openGLContext = [m_openGLView openGLContext];
|
||||
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
static const bool needAlpha = true;
|
||||
#else
|
||||
static const bool needAlpha = false;
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_OPENGL_STENCIL
|
||||
static const bool needStencil = true;
|
||||
#else
|
||||
static const bool needStencil = false;
|
||||
#endif
|
||||
|
||||
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil);
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||
|
||||
// Fall back to no multisampling if Antialiasing init failed
|
||||
if (m_numOfAASamples > 0 && pixelFormat == nil) {
|
||||
// XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples?
|
||||
// Does this need to explicitly try for a lesser match before giving up?
|
||||
// (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
|
||||
|
||||
attribs.clear();
|
||||
makeAttribList(attribs, m_stereoVisual, 0, needAlpha, needStencil);
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||
}
|
||||
|
||||
if (pixelFormat == nil)
|
||||
goto error;
|
||||
|
||||
if (m_numOfAASamples > 0) { //Set m_numOfAASamples to the actual value
|
||||
GLint actualSamples;
|
||||
[pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
|
||||
|
||||
if (m_numOfAASamples != (GHOST_TUns16)actualSamples) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! Unable to find a multisample pixel format that supports exactly %d samples. Substituting one that uses %d samples.\n",
|
||||
m_numOfAASamples,
|
||||
actualSamples);
|
||||
|
||||
m_numOfAASamples = (GHOST_TUns16)actualSamples;
|
||||
}
|
||||
}
|
||||
|
||||
[m_openGLView setPixelFormat:pixelFormat];
|
||||
|
||||
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
|
||||
|
||||
if (m_openGLContext == nil)
|
||||
goto error;
|
||||
|
||||
if (s_sharedCount == 0)
|
||||
s_sharedOpenGLContext = m_openGLContext;
|
||||
|
||||
s_sharedCount++;
|
||||
|
||||
#ifdef GHOST_MULTITHREADED_OPENGL
|
||||
//Switch openGL to multhreaded mode
|
||||
CGLContextObj cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj];
|
||||
if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError)
|
||||
printf("\nSwitched openGL to multithreaded mode\n");
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_WAIT_FOR_VSYNC
|
||||
{
|
||||
GLint swapInt = 1;
|
||||
/* wait for vsync, to avoid tearing artifacts */
|
||||
[m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
#endif
|
||||
|
||||
[m_openGLView setOpenGLContext:m_openGLContext];
|
||||
[m_openGLContext setView:m_openGLView];
|
||||
|
||||
initContextGLEW();
|
||||
|
||||
glClearColor(0.447, 0.447, 0.447, 0.000);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.000, 0.000, 0.000, 0.000);
|
||||
|
||||
[pool drain];
|
||||
|
||||
return GHOST_kSuccess;
|
||||
|
||||
error:
|
||||
|
||||
[m_openGLView setOpenGLContext:prev_openGLContext];
|
||||
|
||||
[pool drain];
|
||||
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
|
||||
{
|
||||
GHOST_TSuccess success = m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure;
|
||||
|
||||
m_openGLContext = NULL;
|
||||
m_openGLView = NULL;
|
||||
|
||||
return success;
|
||||
}
|
657
intern/ghost/intern/GHOST_ContextEGL.cpp
Normal file
657
intern/ghost/intern/GHOST_ContextEGL.cpp
Normal file
@@ -0,0 +1,657 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextEGL.cpp
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_ContextEGL class.
|
||||
*/
|
||||
|
||||
#include "GHOST_ContextEGL.h"
|
||||
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
||||
EGLEWContext* eglewContext = NULL;
|
||||
|
||||
|
||||
|
||||
static const char* get_egl_error_enum_string(EGLenum error)
|
||||
{
|
||||
switch(error) {
|
||||
case EGL_SUCCESS:
|
||||
return "EGL_SUCCESS";
|
||||
|
||||
case EGL_NOT_INITIALIZED:
|
||||
return "EGL_NOT_INITIALIZED";
|
||||
|
||||
case EGL_BAD_ACCESS:
|
||||
return "EGL_BAD_ALLOC";
|
||||
|
||||
case EGL_BAD_ALLOC:
|
||||
return "EGL_BAD_ALLOC";
|
||||
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
return "EGL_BAD_ATTRIBUTE";
|
||||
|
||||
case EGL_BAD_CONTEXT:
|
||||
return "EGL_BAD_CONTEXT";
|
||||
|
||||
case EGL_BAD_CONFIG:
|
||||
return "EGL_BAD_CONFIG";
|
||||
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
return "EGL_BAD_CURRENT_SURFACE";
|
||||
|
||||
case EGL_BAD_DISPLAY:
|
||||
return "EGL_BAD_DISPLAY";
|
||||
|
||||
case EGL_BAD_SURFACE:
|
||||
return "EGL_BAD_SURFACE";
|
||||
|
||||
case EGL_BAD_MATCH:
|
||||
return "EGL_BAD_MATCH";
|
||||
|
||||
case EGL_BAD_PARAMETER:
|
||||
return "EGL_BAD_PARAMETER";
|
||||
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
return "EGL_BAD_NATIVE_PIXMAP";
|
||||
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
return "EGL_BAD_NATIVE_WINDOW";
|
||||
|
||||
case EGL_CONTEXT_LOST:
|
||||
return "EGL_CONTEXT_LOST";
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* get_egl_error_message_string(EGLenum error)
|
||||
{
|
||||
switch(error) {
|
||||
case EGL_SUCCESS:
|
||||
return "The last function succeeded without error.";
|
||||
|
||||
case EGL_NOT_INITIALIZED:
|
||||
return "EGL is not initialized, or could not be initialized, for the specified EGL display connection.";
|
||||
|
||||
case EGL_BAD_ACCESS:
|
||||
return "EGL cannot access a requested resource (for example a context is bound in another thread).";
|
||||
|
||||
case EGL_BAD_ALLOC:
|
||||
return "EGL failed to allocate resources for the requested operation.";
|
||||
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
return "An unrecognized attribute or attribute value was passed in the attribute list.";
|
||||
|
||||
case EGL_BAD_CONTEXT:
|
||||
return "An EGLContext argument does not name a valid EGL rendering context.";
|
||||
|
||||
case EGL_BAD_CONFIG:
|
||||
return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
|
||||
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid.";
|
||||
|
||||
case EGL_BAD_DISPLAY:
|
||||
return "An EGLDisplay argument does not name a valid EGL display connection.";
|
||||
|
||||
case EGL_BAD_SURFACE:
|
||||
return "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering.";
|
||||
|
||||
case EGL_BAD_MATCH:
|
||||
return "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface).";
|
||||
|
||||
case EGL_BAD_PARAMETER:
|
||||
return "One or more argument values are invalid.";
|
||||
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
return "A NativePixmapType argument does not refer to a valid native pixmap.";
|
||||
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
return "A NativeWindowType argument does not refer to a valid native window.";
|
||||
|
||||
case EGL_CONTEXT_LOST:
|
||||
return "A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering.";
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool egl_chk(bool result, const char* file = NULL, int line = 0, const char* text = NULL)
|
||||
{
|
||||
if (!result) {
|
||||
EGLenum error = eglGetError();
|
||||
|
||||
const char* code = get_egl_error_enum_string(error);
|
||||
const char* msg = get_egl_error_message_string(error);
|
||||
|
||||
#ifndef NDEBUG
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n",
|
||||
file,
|
||||
line,
|
||||
text,
|
||||
error,
|
||||
code ? code : "<Unknown>",
|
||||
msg ? msg : "<Unknown>");
|
||||
#else
|
||||
fprintf(
|
||||
stderr,
|
||||
"EGL Error (0x%04X): %s: %s\n",
|
||||
error,
|
||||
code ? code : "<Unknown>",
|
||||
msg ? msg : "<Unknown>");
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, #x)
|
||||
#else
|
||||
#define EGL_CHK(x) egl_chk(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static inline bool bindAPI(EGLenum api)
|
||||
{
|
||||
if (eglewContext != NULL && EGLEW_VERSION_1_2)
|
||||
return EGL_CHK(eglBindAPI(api)) == EGL_TRUE;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(WITH_ANGLE)
|
||||
HMODULE GHOST_ContextEGL::s_d3dcompiler = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT;
|
||||
EGLint GHOST_ContextEGL::s_gl_sharedCount = 0;
|
||||
|
||||
EGLContext GHOST_ContextEGL::s_gles_sharedContext = EGL_NO_CONTEXT;
|
||||
EGLint GHOST_ContextEGL::s_gles_sharedCount = 0;
|
||||
|
||||
EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT;
|
||||
EGLint GHOST_ContextEGL::s_vg_sharedCount = 0;
|
||||
|
||||
|
||||
#pragma warning(disable : 4715)
|
||||
|
||||
template <typename T>
|
||||
T& choose_api(EGLenum api, T& a, T& b, T& c)
|
||||
{
|
||||
switch(api) {
|
||||
case EGL_OPENGL_API:
|
||||
return a;
|
||||
case EGL_OPENGL_ES_API:
|
||||
return b;
|
||||
case EGL_OPENVG_API:
|
||||
return c;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_ContextEGL::GHOST_ContextEGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
EGLNativeWindowType nativeWindow,
|
||||
EGLNativeDisplayType nativeDisplay,
|
||||
EGLint contextProfileMask,
|
||||
EGLint contextMajorVersion,
|
||||
EGLint contextMinorVersion,
|
||||
EGLint contextFlags,
|
||||
EGLint contextResetNotificationStrategy,
|
||||
EGLenum api
|
||||
)
|
||||
: GHOST_Context(stereoVisual, numOfAASamples)
|
||||
, m_nativeWindow (nativeWindow)
|
||||
, m_nativeDisplay(nativeDisplay)
|
||||
, m_contextProfileMask (contextProfileMask)
|
||||
, m_contextMajorVersion (contextMajorVersion)
|
||||
, m_contextMinorVersion (contextMinorVersion)
|
||||
, m_contextFlags (contextFlags)
|
||||
, m_contextResetNotificationStrategy(contextResetNotificationStrategy)
|
||||
, m_api(api)
|
||||
, m_swap_interval(1)
|
||||
, m_display(EGL_NO_DISPLAY)
|
||||
, m_surface(EGL_NO_SURFACE)
|
||||
, m_context(EGL_NO_CONTEXT)
|
||||
, m_sharedContext(choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext))
|
||||
, m_sharedCount (choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
|
||||
, m_eglewContext(NULL)
|
||||
{
|
||||
assert(m_nativeWindow != NULL);
|
||||
assert(m_nativeDisplay != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_ContextEGL::~GHOST_ContextEGL()
|
||||
{
|
||||
if (m_display != EGL_NO_DISPLAY) {
|
||||
activateEGLEW();
|
||||
|
||||
bindAPI(m_api);
|
||||
|
||||
if (m_context != EGL_NO_CONTEXT) {
|
||||
if (m_context == ::eglGetCurrentContext())
|
||||
EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
|
||||
|
||||
if (m_context != m_sharedContext || m_sharedCount == 1) {
|
||||
assert(m_sharedCount > 0);
|
||||
|
||||
m_sharedCount--;
|
||||
|
||||
if (m_sharedCount == 0)
|
||||
m_sharedContext = EGL_NO_CONTEXT;
|
||||
|
||||
EGL_CHK(::eglDestroyContext(m_display, m_context));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_surface != EGL_NO_SURFACE)
|
||||
EGL_CHK(::eglDestroySurface(m_display, m_surface));
|
||||
|
||||
EGL_CHK(::eglTerminate(m_display));
|
||||
|
||||
delete m_eglewContext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::swapBuffers()
|
||||
{
|
||||
return EGL_CHK(eglSwapBuffers(m_display, m_surface)) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::setSwapInterval(int interval)
|
||||
{
|
||||
if (EGLEW_VERSION_1_1) {
|
||||
if (EGL_CHK(::eglSwapInterval(m_display, interval))) {
|
||||
m_swap_interval = interval;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
intervalOut = m_swap_interval; // XXX jwilkins: make sure there is no way to query this?
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
|
||||
{
|
||||
if (m_display) {
|
||||
activateEGLEW();
|
||||
activateGLEW();
|
||||
|
||||
bindAPI(m_api);
|
||||
|
||||
return EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GHOST_ContextEGL::initContextEGLEW()
|
||||
{
|
||||
eglewContext = new EGLEWContext;
|
||||
memset(eglewContext, 0, sizeof(EGLEWContext));
|
||||
|
||||
delete m_eglewContext;
|
||||
m_eglewContext = eglewContext;
|
||||
|
||||
GLEW_CHK(eglewInit(m_display));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::set<std::string> split(const std::string s, char delim = ' ')
|
||||
{
|
||||
std::set<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
|
||||
while (std::getline(ss, item, delim))
|
||||
elems.insert(item);
|
||||
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const std::string& api_string(EGLenum api)
|
||||
{
|
||||
static const std::string a("OpenGL" );
|
||||
static const std::string b("OpenGL ES");
|
||||
static const std::string c("OpenVG" );
|
||||
|
||||
return choose_api(api, a, b, c);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
{
|
||||
// objects have to be declared here due to the use of goto
|
||||
std::vector<EGLint> attrib_list;
|
||||
|
||||
if (m_stereoVisual)
|
||||
fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n");
|
||||
|
||||
m_stereoVisual = false; // It doesn't matter what the Window wants.
|
||||
|
||||
#if defined(WITH_ANGLE)
|
||||
// d3dcompiler_XX.dll needs to be loaded before ANGLE will work
|
||||
if (s_d3dcompiler == NULL) {
|
||||
s_d3dcompiler = LoadLibrary(D3DCOMPILER);
|
||||
|
||||
if (s_d3dcompiler == NULL) {
|
||||
fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n");
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
EGLDisplay prev_display = eglGetCurrentDisplay();
|
||||
EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
|
||||
EGLSurface prev_read = eglGetCurrentSurface(EGL_READ);
|
||||
EGLContext prev_context = eglGetCurrentContext();
|
||||
|
||||
m_display = ::eglGetDisplay(m_nativeDisplay);
|
||||
|
||||
if (!EGL_CHK(m_display != EGL_NO_DISPLAY))
|
||||
return GHOST_kFailure;
|
||||
|
||||
EGLint egl_major, egl_minor;
|
||||
|
||||
if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)))
|
||||
goto error;
|
||||
|
||||
fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor);
|
||||
|
||||
if (!EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)))
|
||||
goto error;
|
||||
|
||||
initContextEGLEW();
|
||||
|
||||
if (!bindAPI(m_api))
|
||||
goto error;
|
||||
|
||||
|
||||
// build attribute list
|
||||
|
||||
attrib_list.reserve(20);
|
||||
|
||||
if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
|
||||
// According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE,
|
||||
// but some implementations (ANGLE) do not seem to care.
|
||||
|
||||
if (m_contextMajorVersion == 1) {
|
||||
attrib_list.push_back(EGL_RENDERABLE_TYPE);
|
||||
attrib_list.push_back(EGL_OPENGL_ES_BIT);
|
||||
}
|
||||
else if (m_contextMajorVersion == 2) {
|
||||
attrib_list.push_back(EGL_RENDERABLE_TYPE);
|
||||
attrib_list.push_back(EGL_OPENGL_ES2_BIT);
|
||||
}
|
||||
else if (m_contextMajorVersion == 3) {
|
||||
attrib_list.push_back(EGL_RENDERABLE_TYPE);
|
||||
attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning! Unable to request an ES context of version %d.%d\n", m_contextMajorVersion, m_contextMinorVersion);
|
||||
}
|
||||
|
||||
if (!((m_contextMajorVersion == 1) ||
|
||||
(m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) ||
|
||||
(m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) ||
|
||||
(m_contextMajorVersion == 3 && EGLEW_VERSION_1_5)))
|
||||
{
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! May not be able to create a version %d.%d ES context with version %d.%d of EGL\n",
|
||||
m_contextMajorVersion,
|
||||
m_contextMinorVersion,
|
||||
egl_major,
|
||||
egl_minor);
|
||||
}
|
||||
}
|
||||
|
||||
attrib_list.push_back(EGL_RED_SIZE);
|
||||
attrib_list.push_back(8);
|
||||
|
||||
attrib_list.push_back(EGL_GREEN_SIZE);
|
||||
attrib_list.push_back(8);
|
||||
|
||||
attrib_list.push_back(EGL_BLUE_SIZE);
|
||||
attrib_list.push_back(8);
|
||||
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
attrib_list.push_back(EGL_ALPHA_SIZE);
|
||||
attrib_list.push_back(8);
|
||||
#endif
|
||||
|
||||
attrib_list.push_back(EGL_DEPTH_SIZE);
|
||||
attrib_list.push_back(24);
|
||||
|
||||
#ifdef GHOST_OPENGL_STENCIL
|
||||
attrib_list.push_back(EGL_STENCIL_SIZE);
|
||||
attrib_list.push_back(8);
|
||||
#endif
|
||||
|
||||
if (m_numOfAASamples > 0) {
|
||||
attrib_list.push_back(EGL_SAMPLE_BUFFERS);
|
||||
attrib_list.push_back(1);
|
||||
|
||||
attrib_list.push_back(EGL_SAMPLES);
|
||||
attrib_list.push_back(m_numOfAASamples);
|
||||
}
|
||||
|
||||
attrib_list.push_back(EGL_NONE);
|
||||
|
||||
EGLConfig config;
|
||||
EGLint num_config = 0;
|
||||
|
||||
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
|
||||
goto error;
|
||||
|
||||
// A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
|
||||
if (num_config != 1) // num_config should be exactly 1
|
||||
goto error;
|
||||
|
||||
if (m_numOfAASamples > 0) {
|
||||
EGLint actualSamples;
|
||||
|
||||
if (!EGL_CHK(::eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &actualSamples)))
|
||||
goto error;
|
||||
|
||||
if (m_numOfAASamples != actualSamples) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! Unable to find a multisample pixel format that supports exactly %d samples. Substituting one that uses %d samples.\n",
|
||||
m_numOfAASamples,
|
||||
actualSamples);
|
||||
|
||||
m_numOfAASamples = (GHOST_TUns16)actualSamples;
|
||||
}
|
||||
}
|
||||
|
||||
m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL);
|
||||
|
||||
if (!EGL_CHK(m_surface != EGL_NO_SURFACE))
|
||||
goto error;
|
||||
|
||||
attrib_list.clear();
|
||||
|
||||
if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) {
|
||||
if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) {
|
||||
if (m_contextMajorVersion != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
|
||||
attrib_list.push_back(m_contextMajorVersion);
|
||||
}
|
||||
|
||||
if (m_contextMinorVersion != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
|
||||
attrib_list.push_back(m_contextMinorVersion);
|
||||
}
|
||||
|
||||
if (m_contextFlags != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR);
|
||||
attrib_list.push_back(m_contextFlags);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0)
|
||||
fprintf(stderr, "Warning! Cannot request specific versions of %s contexts.", api_string(m_api));
|
||||
|
||||
if (m_contextFlags != 0)
|
||||
fprintf(stderr, "Warning! Flags cannot be set on %s contexts.", api_string(m_api));
|
||||
}
|
||||
|
||||
if (m_api == EGL_OPENGL_API) {
|
||||
if (m_contextProfileMask != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
|
||||
attrib_list.push_back(m_contextProfileMask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_contextProfileMask != 0)
|
||||
fprintf(stderr, "Warning! Cannot select profile for %s contexts.", api_string(m_api));
|
||||
}
|
||||
|
||||
if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) {
|
||||
if (m_contextResetNotificationStrategy != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
|
||||
attrib_list.push_back(m_contextResetNotificationStrategy);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_contextResetNotificationStrategy != 0)
|
||||
fprintf(stderr, "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.", egl_major, egl_minor, api_string(m_api));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_api == EGL_OPENGL_ES_API) {
|
||||
if (m_contextMajorVersion != 0) {
|
||||
attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION);
|
||||
attrib_list.push_back(m_contextMajorVersion);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0)
|
||||
fprintf(stderr, "Warning! EGL %d.%d is unable to select between versions of %s.", egl_major, egl_minor, api_string(m_api));
|
||||
}
|
||||
|
||||
if (m_contextFlags != 0)
|
||||
fprintf(stderr, "Warning! EGL %d.%d is unable to set context flags.", egl_major, egl_minor);
|
||||
|
||||
if (m_contextProfileMask != 0)
|
||||
fprintf(stderr, "Warning! EGL %d.%d is unable to select between profiles.", egl_major, egl_minor);
|
||||
|
||||
if (m_contextResetNotificationStrategy != 0)
|
||||
fprintf(stderr, "Warning! EGL %d.%d is unable to set the reset notification strategies.", egl_major, egl_minor);
|
||||
}
|
||||
|
||||
attrib_list.push_back(EGL_NONE);
|
||||
|
||||
m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
|
||||
|
||||
if (!EGL_CHK(m_context != EGL_NO_CONTEXT))
|
||||
goto error;
|
||||
|
||||
if (m_sharedContext == EGL_NO_CONTEXT)
|
||||
m_sharedContext = m_context;
|
||||
|
||||
m_sharedCount++;
|
||||
|
||||
if (!EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)))
|
||||
goto error;
|
||||
|
||||
initContextGLEW();
|
||||
|
||||
glClearColor(0.447, 0.447, 0.447, 0.000);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.000, 0.000, 0.000, 0.000);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
|
||||
error:
|
||||
if (prev_display != EGL_NO_DISPLAY)
|
||||
EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context));
|
||||
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::releaseNativeHandles()
|
||||
{
|
||||
m_nativeWindow = NULL;
|
||||
m_nativeDisplay = NULL;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
162
intern/ghost/intern/GHOST_ContextEGL.h
Normal file
162
intern/ghost/intern/GHOST_ContextEGL.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextEGL.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_ContextEGL class.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_CONTEXTEGL_H_
|
||||
#define _GHOST_CONTEXTEGL_H_
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#define eglewGetContext() eglewContext
|
||||
#include <GL/eglew.h>
|
||||
extern "C" EGLEWContext* eglewContext;
|
||||
|
||||
|
||||
|
||||
#ifndef GHOST_OPENGL_EGL_CONTEXT_FLAGS
|
||||
#define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY
|
||||
#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class GHOST_ContextEGL : public GHOST_Context
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ContextEGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
EGLNativeWindowType nativeWindow,
|
||||
EGLNativeDisplayType nativeDisplay,
|
||||
EGLint contextProfileMask,
|
||||
EGLint contextMajorVersion,
|
||||
EGLint contextMinorVersion,
|
||||
EGLint contextFlags,
|
||||
EGLint contextResetNotificationStrategy,
|
||||
EGLenum api
|
||||
);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~GHOST_ContextEGL();
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
|
||||
protected:
|
||||
inline void activateEGLEW() const {
|
||||
eglewContext = m_eglewContext;
|
||||
}
|
||||
|
||||
private:
|
||||
void initContextEGLEW();
|
||||
|
||||
EGLNativeDisplayType m_nativeDisplay;
|
||||
EGLNativeWindowType m_nativeWindow;
|
||||
|
||||
const EGLint m_contextProfileMask;
|
||||
const EGLint m_contextMajorVersion;
|
||||
const EGLint m_contextMinorVersion;
|
||||
const EGLint m_contextFlags;
|
||||
const EGLint m_contextResetNotificationStrategy;
|
||||
|
||||
const EGLenum m_api;
|
||||
|
||||
EGLContext m_context;
|
||||
EGLSurface m_surface;
|
||||
EGLDisplay m_display;
|
||||
|
||||
EGLint m_swap_interval;
|
||||
|
||||
EGLEWContext* m_eglewContext;
|
||||
|
||||
EGLContext& m_sharedContext;
|
||||
EGLint& m_sharedCount;
|
||||
|
||||
static EGLContext s_gl_sharedContext;
|
||||
static EGLint s_gl_sharedCount;
|
||||
|
||||
static EGLContext s_gles_sharedContext;
|
||||
static EGLint s_gles_sharedCount;
|
||||
|
||||
static EGLContext s_vg_sharedContext;
|
||||
static EGLint s_vg_sharedCount;
|
||||
|
||||
#if defined(WITH_ANGLE)
|
||||
static HMODULE s_d3dcompiler;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _GHOST_CONTEXTEGL_H_
|
338
intern/ghost/intern/GHOST_ContextGLX.cpp
Normal file
338
intern/ghost/intern/GHOST_ContextGLX.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextGLX.cpp
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_ContextGLX class.
|
||||
*/
|
||||
|
||||
#include "GHOST_ContextGLX.h"
|
||||
#include "GHOST_SystemX11.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
GLXEWContext* glxewContext = NULL;
|
||||
|
||||
|
||||
|
||||
GLXContext GHOST_ContextGLX::s_sharedContext = None;
|
||||
int GHOST_ContextGLX::s_sharedCount = 0;
|
||||
|
||||
|
||||
|
||||
GHOST_ContextGLX::GHOST_ContextGLX(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
Window window,
|
||||
Display* display,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
)
|
||||
: GHOST_Context(stereoVisual, numOfAASamples)
|
||||
, m_window (window)
|
||||
, m_display(display)
|
||||
, m_contextProfileMask (contextProfileMask)
|
||||
, m_contextMajorVersion (contextMajorVersion)
|
||||
, m_contextMinorVersion (contextMinorVersion)
|
||||
, m_contextFlags (contextFlags)
|
||||
, m_contextResetNotificationStrategy(contextResetNotificationStrategy)
|
||||
, m_visualInfo (NULL)
|
||||
, m_context (None)
|
||||
, m_glxewContext(NULL)
|
||||
{
|
||||
assert(m_window != 0);
|
||||
assert(m_display != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_ContextGLX::~GHOST_ContextGLX()
|
||||
{
|
||||
if (m_display != NULL) {
|
||||
activateGLXEW();
|
||||
|
||||
if (m_context != None) {
|
||||
if (m_window != 0 && m_context == ::glXGetCurrentContext())
|
||||
::glXMakeCurrent(m_display, m_window, NULL);
|
||||
|
||||
if (m_context != s_sharedContext || s_sharedCount == 1) {
|
||||
assert(s_sharedCount > 0);
|
||||
|
||||
s_sharedCount--;
|
||||
|
||||
if (s_sharedCount == 0)
|
||||
s_sharedContext = NULL;
|
||||
|
||||
::glXDestroyContext(m_display, m_context);
|
||||
}
|
||||
}
|
||||
|
||||
delete m_glxewContext;
|
||||
}
|
||||
|
||||
XFree(m_visualInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::swapBuffers()
|
||||
{
|
||||
::glXSwapBuffers(m_display, m_window);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::activateDrawingContext()
|
||||
{
|
||||
if (m_display) {
|
||||
activateGLXEW();
|
||||
activateGLEW();
|
||||
|
||||
return ::glXMakeCurrent(m_display, m_window, m_context) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GHOST_ContextGLX::initContextGLXEW()
|
||||
{
|
||||
glxewContext = new GLXEWContext;
|
||||
memset(glxewContext, 0, sizeof(GLXEWContext));
|
||||
|
||||
delete m_glxewContext;
|
||||
m_glxewContext = glxewContext;
|
||||
|
||||
GLEW_CHK(glxewInit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
||||
{
|
||||
/* Set up the minimum atrributes that we require and see if
|
||||
* X can find us a visual matching those requirements. */
|
||||
|
||||
std::vector<int> attribs;
|
||||
attribs.reserve(40);
|
||||
|
||||
int glx_major, glx_minor; /* GLX version: major.minor */
|
||||
|
||||
if (!glXQueryVersion(m_display, &glx_major, &glx_minor)) {
|
||||
fprintf(stderr, "%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
|
||||
/* exit if this is the first window */
|
||||
if (s_sharedContext == NULL) {
|
||||
fprintf(stderr, "initial window could not find the GLX extension, exit!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
static const bool needAlpha = true;
|
||||
#else
|
||||
static const bool needAlpha = false;
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_OPENGL_STENCIL
|
||||
static const bool needStencil = true;
|
||||
#else
|
||||
static const bool needStencil = false;
|
||||
#endif
|
||||
|
||||
/* Find the display with highest samples, starting at level requested */
|
||||
int actualSamples = m_numOfAASamples;
|
||||
for(;;) {
|
||||
attribs.clear();
|
||||
|
||||
if (m_stereoVisual)
|
||||
attribs.push_back(GLX_STEREO);
|
||||
|
||||
attribs.push_back(GLX_RGBA);
|
||||
|
||||
attribs.push_back(GLX_DOUBLEBUFFER);
|
||||
|
||||
attribs.push_back(GLX_RED_SIZE);
|
||||
attribs.push_back(1);
|
||||
|
||||
attribs.push_back(GLX_BLUE_SIZE);
|
||||
attribs.push_back(1);
|
||||
|
||||
attribs.push_back(GLX_GREEN_SIZE);
|
||||
attribs.push_back(1);
|
||||
|
||||
attribs.push_back(GLX_DEPTH_SIZE);
|
||||
attribs.push_back(1);
|
||||
|
||||
if (needAlpha) {
|
||||
attribs.push_back(GLX_ALPHA_SIZE);
|
||||
attribs.push_back(1);
|
||||
}
|
||||
|
||||
if (needStencil) {
|
||||
attribs.push_back(GLX_STENCIL_SIZE);
|
||||
attribs.push_back(1);
|
||||
}
|
||||
|
||||
/* GLX >= 1.4 required for multi-sample */
|
||||
if (actualSamples > 0 && (glx_major >= 1) && (glx_minor >= 4)) {
|
||||
attribs.push_back(GLX_SAMPLE_BUFFERS);
|
||||
attribs.push_back(1);
|
||||
|
||||
attribs.push_back(GLX_SAMPLES);
|
||||
attribs.push_back(actualSamples);
|
||||
}
|
||||
|
||||
attribs.push_back(None);
|
||||
|
||||
m_visualInfo = glXChooseVisual(m_display, DefaultScreen(m_display), &attribs[0]);
|
||||
|
||||
/* Any sample level or even zero, which means oversampling disabled, is good
|
||||
* but we need a valid visual to continue */
|
||||
if (m_visualInfo != NULL) {
|
||||
if (actualSamples < m_numOfAASamples) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! Unable to find a multisample pixel format that supports exactly %d samples. Substituting one that uses %d samples.\n",
|
||||
m_numOfAASamples,
|
||||
actualSamples);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (actualSamples == 0) {
|
||||
/* All options exhausted, cannot continue */
|
||||
fprintf(stderr, "%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
|
||||
if (s_sharedContext == None) {
|
||||
fprintf(stderr, "initial window could not find the GLX extension, exit!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
--actualSamples;
|
||||
}
|
||||
}
|
||||
|
||||
m_numOfAASamples = actualSamples;
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* use our own event handlers to avoid exiting blender,
|
||||
* this would happen for eg:
|
||||
* if you open blender, unplug a tablet, then open a new window. */
|
||||
XErrorHandler old_handler = XSetErrorHandler (GHOST_X11_ApplicationErrorHandler );
|
||||
XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
|
||||
#endif
|
||||
|
||||
m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True);
|
||||
|
||||
GHOST_TSuccess success;
|
||||
|
||||
if (m_context != NULL) {
|
||||
if (!s_sharedContext)
|
||||
s_sharedContext = m_context;
|
||||
|
||||
glXMakeCurrent(m_display, m_window, m_context);
|
||||
|
||||
initContextGLEW();
|
||||
initContextGLXEW(); // XXX jwilkins: seems that this has to be called after MakeCurrent, which means we cannot use extensions until after we create a context
|
||||
|
||||
glClearColor(0.447, 0.447, 0.447, 0.000);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.000, 0.000, 0.000, 0.000);
|
||||
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* Restore handler */
|
||||
XSetErrorHandler (old_handler);
|
||||
XSetIOErrorHandler(old_handler_io);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles()
|
||||
{
|
||||
m_window = 0;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval)
|
||||
{
|
||||
if (GLXEW_EXT_swap_control) {
|
||||
::glXSwapIntervalEXT(m_display, m_window, interval);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
if (GLXEW_EXT_swap_control) {
|
||||
unsigned int interval = 0;
|
||||
|
||||
::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
|
||||
|
||||
intervalOut = static_cast<int>(interval);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
145
intern/ghost/intern/GHOST_ContextGLX.h
Normal file
145
intern/ghost/intern/GHOST_ContextGLX.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextGLX.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_ContextGLX class.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_CONTEXTGLX_H_
|
||||
#define _GHOST_CONTEXTGLX_H_
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#define glxewGetContext() glxewContext
|
||||
#include <GL/glxew.h>
|
||||
extern "C" GLXEWContext* glxewContext;
|
||||
|
||||
|
||||
|
||||
#ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS
|
||||
#define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY
|
||||
#define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class GHOST_ContextGLX : public GHOST_Context
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ContextGLX(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
Window window,
|
||||
Display* display,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~GHOST_ContextGLX();
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
virtual GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
|
||||
protected:
|
||||
inline void activateGLXEW() const {
|
||||
glxewContext = m_glxewContext;
|
||||
}
|
||||
|
||||
private:
|
||||
void initContextGLXEW();
|
||||
|
||||
Display *m_display;
|
||||
Window m_window;
|
||||
|
||||
const int m_contextProfileMask;
|
||||
const int m_contextMajorVersion;
|
||||
const int m_contextMinorVersion;
|
||||
const int m_contextFlags;
|
||||
const int m_contextResetNotificationStrategy;
|
||||
|
||||
XVisualInfo *m_visualInfo;
|
||||
|
||||
GLXContext m_context;
|
||||
|
||||
GLXEWContext* m_glxewContext;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static GLXContext s_sharedContext;
|
||||
static int s_sharedCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _GHOST_CONTEXTGLX_H_
|
85
intern/ghost/intern/GHOST_ContextNone.cpp
Normal file
85
intern/ghost/intern/GHOST_ContextNone.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextNone.cpp
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_ContextNone class.
|
||||
*/
|
||||
|
||||
#include "GHOST_ContextNone.h"
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::swapBuffers()
|
||||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::activateDrawingContext()
|
||||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::updateDrawingContext()
|
||||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::initializeDrawingContext()
|
||||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::releaseNativeHandles()
|
||||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::setSwapInterval(int interval)
|
||||
{
|
||||
m_swapInterval = interval;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextNone::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
intervalOut = m_swapInterval;
|
||||
return GHOST_kSuccess;
|
||||
}
|
98
intern/ghost/intern/GHOST_ContextNone.h
Normal file
98
intern/ghost/intern/GHOST_ContextNone.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextNone.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_Context class.
|
||||
*/
|
||||
|
||||
#ifndef __GHOST_CONTEXTNONE_H__
|
||||
#define __GHOST_CONTEXTNONE_H__
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
|
||||
|
||||
class GHOST_ContextNone : public GHOST_Context
|
||||
{
|
||||
public:
|
||||
|
||||
GHOST_ContextNone(bool stereoVisual, GHOST_TUns16 numOfAASamples)
|
||||
: GHOST_Context(stereoVisual, numOfAASamples)
|
||||
, m_swapInterval(1)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Dummy function
|
||||
* \param intervalOut Gets whatever was set by setSwapInterval
|
||||
* \return Always succeeds
|
||||
*/
|
||||
virtual GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
|
||||
private:
|
||||
int m_swapInterval;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __GHOST_CONTEXTNONE_H__
|
976
intern/ghost/intern/GHOST_ContextWGL.cpp
Normal file
976
intern/ghost/intern/GHOST_ContextWGL.cpp
Normal file
@@ -0,0 +1,976 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextWGL.cpp
|
||||
* \ingroup GHOST
|
||||
* Definition of GHOST_ContextWGL class.
|
||||
*/
|
||||
|
||||
#include "GHOST_ContextWGL.h"
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
WGLEWContext* wglewContext = NULL;
|
||||
|
||||
|
||||
|
||||
HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL;
|
||||
int GHOST_ContextWGL::s_sharedCount = 0;
|
||||
|
||||
bool GHOST_ContextWGL::s_singleContextMode = false;
|
||||
|
||||
|
||||
|
||||
/* Intel videocards don't work fine with multiple contexts and
|
||||
* have to share the same context for all windows.
|
||||
* But if we just share context for all windows it could work incorrect
|
||||
* with multiple videocards configuration. Suppose, that Intel videocards
|
||||
* can't be in multiple-devices configuration. */
|
||||
static bool is_crappy_intel_card()
|
||||
{
|
||||
return strstr((const char*)glGetString(GL_VENDOR), "Intel") != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool win32_chk(bool result, const char* file = NULL, int line = 0, const char* text = NULL)
|
||||
{
|
||||
if (!result) {
|
||||
LPTSTR formattedMsg = NULL;
|
||||
|
||||
DWORD error = GetLastError();
|
||||
|
||||
const char* msg;
|
||||
|
||||
DWORD count = 0;
|
||||
|
||||
switch (error) {
|
||||
case ERROR_INVALID_VERSION_ARB:
|
||||
msg = "The specified OpenGL version and feature set are either invalid or not supported.\n";
|
||||
break;
|
||||
|
||||
case ERROR_INVALID_PROFILE_ARB:
|
||||
msg = "The specified OpenGL profile and feature set are either invalid or not supported.\n";
|
||||
break;
|
||||
|
||||
case ERROR_INVALID_PIXEL_TYPE_ARB:
|
||||
msg = "The specified pixel type is invalid.\n";
|
||||
break;
|
||||
|
||||
case ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB:
|
||||
msg = "The device contexts specified are not compatible. This can occur if the device contexts are managed by different drivers or possibly on different graphics adapters.\n";
|
||||
break;
|
||||
|
||||
#if WITH_GLEW_ES
|
||||
case ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV:
|
||||
msg = "The device context(s) and rendering context have non-matching affinity masks.\n";
|
||||
break;
|
||||
|
||||
case ERROR_MISSING_AFFINITY_MASK_NV:
|
||||
msg = "The rendering context does not have an affinity mask set.\n";
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ERROR_PROFILE_DOES_NOT_MATCH_DEVICE:
|
||||
msg = "The specified profile is intended for a device of a different type than the specified device.\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
count =
|
||||
FormatMessage(
|
||||
(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS),
|
||||
NULL,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)(&formattedMsg),
|
||||
0,
|
||||
NULL);
|
||||
|
||||
msg = count > 0 ? formattedMsg : "<no system message>\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
_ftprintf(
|
||||
stderr,
|
||||
"%s(%d):[%s] -> Win32 Error# (%d): %s",
|
||||
file,
|
||||
line,
|
||||
text,
|
||||
error,
|
||||
msg);
|
||||
#else
|
||||
_ftprintf(
|
||||
stderr,
|
||||
"Win32 Error# (%d): %s",
|
||||
error,
|
||||
msg);
|
||||
#endif
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
if (count != 0)
|
||||
LocalFree(formattedMsg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define WIN32_CHK(x) win32_chk((x), __FILE__, __LINE__, #x)
|
||||
#else
|
||||
#define WIN32_CHK(x) win32_chk(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
GHOST_ContextWGL::GHOST_ContextWGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
HWND hWnd,
|
||||
HDC hDC,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
)
|
||||
: GHOST_Context(stereoVisual, numOfAASamples)
|
||||
, m_hWnd(hWnd)
|
||||
, m_hDC (hDC)
|
||||
, m_contextProfileMask (contextProfileMask)
|
||||
, m_contextMajorVersion (contextMajorVersion)
|
||||
, m_contextMinorVersion (contextMinorVersion)
|
||||
, m_contextFlags (contextFlags)
|
||||
, m_contextResetNotificationStrategy(contextResetNotificationStrategy)
|
||||
, m_hGLRC(NULL)
|
||||
, m_wglewContext(NULL)
|
||||
#ifndef NDEBUG
|
||||
, m_dummyVendor (NULL)
|
||||
, m_dummyRenderer(NULL)
|
||||
, m_dummyVersion (NULL)
|
||||
#endif
|
||||
{
|
||||
assert(m_hWnd);
|
||||
assert(m_hDC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_ContextWGL::~GHOST_ContextWGL()
|
||||
{
|
||||
if (m_hGLRC != NULL) {
|
||||
if (m_hGLRC == ::wglGetCurrentContext())
|
||||
WIN32_CHK(::wglMakeCurrent(NULL, NULL));
|
||||
|
||||
if (m_hGLRC != s_sharedHGLRC || s_sharedCount == 1) {
|
||||
assert(s_sharedCount > 0);
|
||||
|
||||
s_sharedCount--;
|
||||
|
||||
if (s_sharedCount == 0)
|
||||
s_sharedHGLRC = NULL;
|
||||
|
||||
WIN32_CHK(::wglDeleteContext(m_hGLRC));
|
||||
}
|
||||
}
|
||||
|
||||
delete m_wglewContext;
|
||||
|
||||
#ifndef NDEBUG
|
||||
delete m_dummyRenderer;
|
||||
delete m_dummyVendor;
|
||||
delete m_dummyVersion;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::swapBuffers()
|
||||
{
|
||||
return WIN32_CHK(::SwapBuffers(m_hDC)) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::setSwapInterval(int interval)
|
||||
{
|
||||
if (WGLEW_EXT_swap_control)
|
||||
return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
else
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
if (WGLEW_EXT_swap_control) {
|
||||
intervalOut = ::wglGetSwapIntervalEXT();
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::activateDrawingContext()
|
||||
{
|
||||
if (WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
|
||||
activateGLEW();
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Ron Fosner's code for weighting pixel formats and forcing software.
|
||||
* See http://www.opengl.org/resources/faq/technical/weight.cpp */
|
||||
|
||||
static int weight_pixel_format(PIXELFORMATDESCRIPTOR& pfd)
|
||||
{
|
||||
int weight = 0;
|
||||
|
||||
/* assume desktop color depth is 32 bits per pixel */
|
||||
|
||||
/* cull unusable pixel formats */
|
||||
/* if no formats can be found, can we determine why it was rejected? */
|
||||
if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) ||
|
||||
!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
|
||||
!(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
|
||||
!(pfd.iPixelType == PFD_TYPE_RGBA) ||
|
||||
(pfd.cDepthBits < 16) ||
|
||||
(pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
weight = 1; /* it's usable */
|
||||
|
||||
/* the bigger the depth buffer the better */
|
||||
/* give no weight to a 16-bit depth buffer, because those are crap */
|
||||
weight += pfd.cDepthBits - 16;
|
||||
|
||||
weight += pfd.cColorBits - 8;
|
||||
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
if (pfd.cAlphaBits > 0)
|
||||
weight++;
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_OPENGL_STENCIL
|
||||
if (pfd.cStencilBits >= 8)
|
||||
weight++;
|
||||
#endif
|
||||
|
||||
/* want swap copy capability -- it matters a lot */
|
||||
if (pfd.dwFlags & PFD_SWAP_COPY)
|
||||
weight += 16;
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A modification of Ron Fosner's replacement for ChoosePixelFormat
|
||||
* returns 0 on error, else returns the pixel format number to be used
|
||||
*/
|
||||
static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR& preferredPFD)
|
||||
{
|
||||
int iPixelFormat = 0;
|
||||
int weight = 0;
|
||||
|
||||
int iStereoPixelFormat = 0;
|
||||
int stereoWeight = 0;
|
||||
|
||||
/* choose a pixel format using the useless Windows function in case we come up empty handed */
|
||||
int iLastResortPixelFormat = ::ChoosePixelFormat(hDC, &preferredPFD);
|
||||
|
||||
WIN32_CHK(iLastResortPixelFormat != 0);
|
||||
|
||||
int lastPFD = ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
|
||||
|
||||
WIN32_CHK(lastPFD != 0);
|
||||
|
||||
for (int i = 1; i <= lastPFD; i++) {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int check = ::DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
WIN32_CHK(check == lastPFD);
|
||||
|
||||
int w = weight_pixel_format(pfd);
|
||||
|
||||
if (w > weight) {
|
||||
weight = w;
|
||||
iPixelFormat = i;
|
||||
}
|
||||
|
||||
if (w > stereoWeight && (preferredPFD.dwFlags & pfd.dwFlags & PFD_STEREO)) {
|
||||
stereoWeight = w;
|
||||
iStereoPixelFormat = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* choose any available stereo format over a non-stereo format */
|
||||
if (iStereoPixelFormat != 0)
|
||||
iPixelFormat = iStereoPixelFormat;
|
||||
|
||||
if (iPixelFormat == 0) {
|
||||
fprintf(stderr, "Warning! Using result of ChoosePixelFormat.\n");
|
||||
iPixelFormat = iLastResortPixelFormat;
|
||||
}
|
||||
|
||||
return iPixelFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Clone a window for the purpose of creating a temporary context to initialize WGL extensions.
|
||||
* There is no generic way to clone the lpParam parameter, so the caller is responsible for cloning it themselves.
|
||||
*/
|
||||
|
||||
static HWND clone_window(HWND hWnd, LPVOID lpParam)
|
||||
{
|
||||
int count;
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
WCHAR lpClassName[100] = L"";
|
||||
count = GetClassNameW(hWnd, lpClassName, sizeof(lpClassName));
|
||||
WIN32_CHK(count != 0);
|
||||
|
||||
WCHAR lpWindowName[100] = L"";
|
||||
count = GetWindowTextW(hWnd, lpWindowName, sizeof(lpWindowName));
|
||||
WIN32_CHK(count != 0);
|
||||
|
||||
DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
RECT rect;
|
||||
GetWindowRect(hWnd, &rect);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HWND hWndParent = (HWND)GetWindowLong(hWnd, GWL_HWNDPARENT);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HMENU hMenu = GetMenu(hWnd);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HWND hwndCloned =
|
||||
CreateWindowExW(
|
||||
dwExStyle,
|
||||
lpClassName,
|
||||
lpWindowName,
|
||||
dwStyle,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
hWndParent,
|
||||
hMenu,
|
||||
hInstance,
|
||||
lpParam);
|
||||
|
||||
WIN32_CHK(hwndCloned != NULL);
|
||||
|
||||
return hwndCloned;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR& preferredPFD)
|
||||
{
|
||||
wglewContext = new WGLEWContext;
|
||||
memset(wglewContext, 0, sizeof(WGLEWContext));
|
||||
|
||||
delete m_wglewContext;
|
||||
m_wglewContext = wglewContext;
|
||||
|
||||
HWND dummyHWND = NULL;
|
||||
HDC dummyHDC = NULL;
|
||||
HGLRC dummyHGLRC = NULL;
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
HDC prevHDC = ::wglGetCurrentDC();
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HGLRC prevHGLRC = ::wglGetCurrentContext();
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
dummyHWND = clone_window(m_hWnd, NULL);
|
||||
|
||||
if (dummyHWND == NULL)
|
||||
goto finalize;
|
||||
|
||||
dummyHDC = GetDC(dummyHWND);
|
||||
|
||||
if (!WIN32_CHK(dummyHDC != NULL))
|
||||
goto finalize;
|
||||
|
||||
int iPixelFormat = choose_pixel_format_legacy(dummyHDC, preferredPFD);
|
||||
|
||||
if (iPixelFormat == 0)
|
||||
goto finalize;
|
||||
|
||||
PIXELFORMATDESCRIPTOR chosenPFD;
|
||||
if (!WIN32_CHK(::DescribePixelFormat(dummyHDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
|
||||
goto finalize;
|
||||
|
||||
if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD)))
|
||||
goto finalize;
|
||||
|
||||
dummyHGLRC = ::wglCreateContext(dummyHDC);
|
||||
|
||||
if (!WIN32_CHK(dummyHGLRC != NULL))
|
||||
goto finalize;
|
||||
|
||||
if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
|
||||
goto finalize;
|
||||
|
||||
if (wglewInit() != GLEW_OK)
|
||||
fprintf(stderr, "Warning! WGLEW failed to initialize properly.\n");
|
||||
|
||||
// the following are not technially WGLEW, but they also require a context to work
|
||||
|
||||
#ifndef NDEBUG
|
||||
delete m_dummyRenderer;
|
||||
delete m_dummyVendor;
|
||||
delete m_dummyVersion;
|
||||
|
||||
m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
|
||||
m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
|
||||
m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION)));
|
||||
#endif
|
||||
|
||||
s_singleContextMode = is_crappy_intel_card();
|
||||
|
||||
finalize:
|
||||
WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC));
|
||||
|
||||
if (dummyHGLRC != NULL)
|
||||
WIN32_CHK(::wglDeleteContext(dummyHGLRC));
|
||||
|
||||
if (dummyHWND != NULL) {
|
||||
if (dummyHDC != NULL)
|
||||
WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC));
|
||||
|
||||
WIN32_CHK(::DestroyWindow(dummyHWND));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void makeAttribList(
|
||||
std::vector<int>& out,
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
int swapMethod,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB)
|
||||
{
|
||||
out.clear();
|
||||
out.reserve(30);
|
||||
|
||||
out.push_back(WGL_SUPPORT_OPENGL_ARB);
|
||||
out.push_back(GL_TRUE);
|
||||
|
||||
out.push_back(WGL_DRAW_TO_WINDOW_ARB);
|
||||
out.push_back(GL_TRUE);
|
||||
|
||||
out.push_back(WGL_DOUBLE_BUFFER_ARB);
|
||||
out.push_back(GL_TRUE);
|
||||
|
||||
out.push_back(WGL_ACCELERATION_ARB);
|
||||
out.push_back(WGL_FULL_ACCELERATION_ARB);
|
||||
|
||||
out.push_back(WGL_SWAP_METHOD_ARB);
|
||||
out.push_back(swapMethod);
|
||||
|
||||
if (stereoVisual) {
|
||||
out.push_back(WGL_STEREO_ARB);
|
||||
out.push_back(GL_TRUE);
|
||||
}
|
||||
|
||||
out.push_back(WGL_PIXEL_TYPE_ARB);
|
||||
out.push_back(WGL_TYPE_RGBA_ARB);
|
||||
|
||||
out.push_back(WGL_COLOR_BITS_ARB);
|
||||
out.push_back(24);
|
||||
|
||||
out.push_back(WGL_DEPTH_BITS_ARB);
|
||||
out.push_back(24);
|
||||
|
||||
if (needAlpha) {
|
||||
out.push_back(WGL_ALPHA_BITS_ARB);
|
||||
out.push_back(8);
|
||||
}
|
||||
|
||||
if (needStencil) {
|
||||
out.push_back(WGL_STENCIL_BITS_ARB);
|
||||
out.push_back(8);
|
||||
}
|
||||
|
||||
if (numOfAASamples > 0) {
|
||||
out.push_back(WGL_SAMPLES_ARB);
|
||||
out.push_back(numOfAASamples);
|
||||
|
||||
out.push_back(WGL_SAMPLE_BUFFERS_ARB);
|
||||
out.push_back(1);
|
||||
}
|
||||
|
||||
if (sRGB) {
|
||||
out.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||
out.push_back(GL_TRUE);
|
||||
}
|
||||
|
||||
out.push_back(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GHOST_ContextWGL::_choose_pixel_format_arb_2(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB,
|
||||
int swapMethod)
|
||||
{
|
||||
std::vector<int> iAttributes;
|
||||
|
||||
int iPixelFormat = 0;
|
||||
|
||||
int samples;
|
||||
|
||||
// guard against some insanely high number of samples
|
||||
if (numOfAASamples > 64) {
|
||||
fprintf(stderr, "Warning! Clamping number of samples to 64.\n");
|
||||
samples = 64;
|
||||
}
|
||||
else {
|
||||
samples = numOfAASamples;
|
||||
}
|
||||
|
||||
// request a format with as many samples as possible, but not more than requested
|
||||
while (samples >= 0) {
|
||||
makeAttribList(
|
||||
iAttributes,
|
||||
stereoVisual,
|
||||
samples,
|
||||
swapMethod,
|
||||
needAlpha,
|
||||
needStencil,
|
||||
sRGB);
|
||||
|
||||
UINT nNumFormats;
|
||||
WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, 1, &iPixelFormat, &nNumFormats));
|
||||
|
||||
if (nNumFormats > 0) // total number of formats that match (regardless of size of iPixelFormat array) (see WGL_ARB_pixel_format extension spec)
|
||||
break;
|
||||
|
||||
iPixelFormat = 0; // if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB (see WGL_ARB_pixel_format extension spec)
|
||||
|
||||
samples--;
|
||||
}
|
||||
|
||||
// check how many samples were actually gotten
|
||||
if (iPixelFormat != 0) {
|
||||
int iQuery[] = { WGL_SAMPLES_ARB };
|
||||
int actualSamples;
|
||||
wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples);
|
||||
|
||||
if (actualSamples != numOfAASamples) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! Unable to find a multisample pixel format that supports exactly %d samples. Substituting one that uses %d samples.\n",
|
||||
numOfAASamples,
|
||||
actualSamples);
|
||||
|
||||
m_numOfAASamples = actualSamples; // set context property to actual value
|
||||
}
|
||||
}
|
||||
|
||||
return iPixelFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GHOST_ContextWGL::_choose_pixel_format_arb_1(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB,
|
||||
int& swapMethodOut)
|
||||
{
|
||||
int iPixelFormat;
|
||||
|
||||
swapMethodOut = WGL_SWAP_COPY_ARB;
|
||||
iPixelFormat = _choose_pixel_format_arb_2(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB, swapMethodOut);
|
||||
|
||||
if (iPixelFormat == 0) {
|
||||
swapMethodOut = WGL_SWAP_UNDEFINED_ARB;
|
||||
iPixelFormat = _choose_pixel_format_arb_2(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB, swapMethodOut);
|
||||
}
|
||||
|
||||
if (iPixelFormat == 0) {
|
||||
swapMethodOut = WGL_SWAP_EXCHANGE_ARB;
|
||||
iPixelFormat = _choose_pixel_format_arb_2(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB, swapMethodOut);
|
||||
}
|
||||
|
||||
return iPixelFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GHOST_ContextWGL::choose_pixel_format_arb(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB)
|
||||
{
|
||||
int iPixelFormat;
|
||||
int swapMethodOut;
|
||||
|
||||
iPixelFormat =
|
||||
_choose_pixel_format_arb_1(
|
||||
stereoVisual,
|
||||
numOfAASamples,
|
||||
needAlpha,
|
||||
needStencil,
|
||||
sRGB,
|
||||
swapMethodOut);
|
||||
|
||||
if (iPixelFormat == 0 && stereoVisual) {
|
||||
fprintf(stderr, "Warning! Unable to find a stereo pixel format.\n");
|
||||
|
||||
iPixelFormat =
|
||||
_choose_pixel_format_arb_1(
|
||||
false,
|
||||
numOfAASamples,
|
||||
needAlpha,
|
||||
needStencil,
|
||||
sRGB,
|
||||
swapMethodOut);
|
||||
|
||||
m_stereoVisual = false; // set context property to actual value
|
||||
}
|
||||
|
||||
if (swapMethodOut != WGL_SWAP_COPY_ARB) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning! Unable to find a pixel format that supports WGL_SWAP_COPY_ARB. Substituting one that uses %s.\n",
|
||||
swapMethodOut == WGL_SWAP_UNDEFINED_ARB ? "WGL_SWAP_UNDEFINED_ARB" : "WGL_SWAP_EXCHANGE_ARB");
|
||||
}
|
||||
|
||||
return iPixelFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GHOST_ContextWGL::choose_pixel_format(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR preferredPFD = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR), /* size */
|
||||
1, /* version */
|
||||
PFD_SUPPORT_OPENGL |
|
||||
PFD_DRAW_TO_WINDOW |
|
||||
PFD_SWAP_COPY | /* support swap copy */
|
||||
PFD_DOUBLEBUFFER | /* support double-buffering */
|
||||
(stereoVisual ? PFD_STEREO : 0), /* support stereo */
|
||||
PFD_TYPE_RGBA, /* color type */
|
||||
24, /* preferred color depth */
|
||||
0, 0, 0, 0, 0, 0, /* color bits (ignored) */
|
||||
needAlpha ? 8 : 0, /* alpha buffer */
|
||||
0, /* alpha shift (ignored) */
|
||||
0, /* no accumulation buffer */
|
||||
0, 0, 0, 0, /* accum bits (ignored) */
|
||||
24, /* depth buffer */
|
||||
needStencil ? 8 : 0, /* stencil buffer */
|
||||
0, /* no auxiliary buffers */
|
||||
PFD_MAIN_PLANE, /* main layer */
|
||||
0, /* reserved */
|
||||
0, 0, 0 /* layer, visible, and damage masks (ignored) */
|
||||
};
|
||||
|
||||
initContextWGLEW(preferredPFD);
|
||||
|
||||
if (numOfAASamples > 0 && !WGLEW_ARB_multisample) {
|
||||
fprintf(stderr, "Warning! Unable to request a multisample framebuffer.\n");
|
||||
numOfAASamples = 0;
|
||||
}
|
||||
|
||||
if (sRGB && !(WGLEW_ARB_framebuffer_sRGB || WGLEW_EXT_framebuffer_sRGB)) {
|
||||
fprintf(stderr, "Warning! Unable to request an sRGB framebuffer.\n");
|
||||
sRGB = false;
|
||||
}
|
||||
|
||||
int iPixelFormat = 0;
|
||||
|
||||
if (WGLEW_ARB_pixel_format)
|
||||
iPixelFormat = choose_pixel_format_arb(stereoVisual, numOfAASamples, needAlpha, needStencil, sRGB);
|
||||
|
||||
if (iPixelFormat == 0)
|
||||
iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
|
||||
|
||||
return iPixelFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
static void reportContextString(const char* name, const char* dummy, const char* context)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", name, context);
|
||||
|
||||
if (strcmp(dummy, context) != 0)
|
||||
fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
|
||||
{
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
HGLRC prevHGLRC = ::wglGetCurrentContext();
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
HDC prevHDC = ::wglGetCurrentDC();
|
||||
WIN32_CHK(GetLastError() == NO_ERROR);
|
||||
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
static const bool needAlpha = true;
|
||||
#else
|
||||
static const bool needAlpha = false;
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_OPENGL_STENCIL
|
||||
static const bool needStencil = true;
|
||||
#else
|
||||
static const bool needStencil = false;
|
||||
#endif
|
||||
|
||||
#ifdef GHOST_OPENGL_SRGB
|
||||
static const bool sRGB = true;
|
||||
#else
|
||||
static const bool sRGB = false;
|
||||
#endif
|
||||
|
||||
int iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB);
|
||||
|
||||
if (iPixelFormat == 0)
|
||||
goto error;
|
||||
|
||||
PIXELFORMATDESCRIPTOR chosenPFD;
|
||||
|
||||
int lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
|
||||
|
||||
if (!WIN32_CHK(lastPFD != 0))
|
||||
goto error;
|
||||
|
||||
if (needAlpha && chosenPFD.cAlphaBits == 0)
|
||||
fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n");
|
||||
|
||||
if (needStencil && chosenPFD.cStencilBits == 0)
|
||||
fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n");
|
||||
|
||||
if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD)))
|
||||
goto error;
|
||||
|
||||
activateWGLEW();
|
||||
|
||||
if (WGLEW_ARB_create_context) {
|
||||
int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
|
||||
#if WITH_GLEW_ES
|
||||
int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT;
|
||||
#endif
|
||||
|
||||
if (!WGLEW_ARB_create_context_profile && profileBitCore)
|
||||
fprintf(stderr, "Warning! OpenGL core profile not available.\n");
|
||||
|
||||
if (!WGLEW_ARB_create_context_profile && profileBitCompat)
|
||||
fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
|
||||
|
||||
#if WITH_GLEW_ES
|
||||
if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
|
||||
fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
|
||||
|
||||
if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
|
||||
fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
|
||||
#endif
|
||||
|
||||
int profileMask = 0;
|
||||
|
||||
if (WGLEW_ARB_create_context_profile && profileBitCore)
|
||||
profileMask |= profileBitCore;
|
||||
|
||||
if (WGLEW_ARB_create_context_profile && profileBitCompat)
|
||||
profileMask |= profileBitCompat;
|
||||
|
||||
#if WITH_GLEW_ES
|
||||
if (WGLEW_EXT_create_context_es_profile && profileBitES)
|
||||
profileMask |= profileBitES;
|
||||
#endif
|
||||
|
||||
if (profileMask != m_contextProfileMask)
|
||||
fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
|
||||
|
||||
std::vector<int> iAttributes;
|
||||
|
||||
if (profileMask) {
|
||||
iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
|
||||
iAttributes.push_back(profileMask);
|
||||
}
|
||||
|
||||
if (m_contextMajorVersion != 0) {
|
||||
iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
|
||||
iAttributes.push_back(m_contextMajorVersion);
|
||||
}
|
||||
|
||||
if (m_contextMinorVersion != 0) {
|
||||
iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
|
||||
iAttributes.push_back(m_contextMinorVersion);
|
||||
}
|
||||
|
||||
if (m_contextFlags != 0) {
|
||||
iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
|
||||
iAttributes.push_back(m_contextFlags);
|
||||
}
|
||||
|
||||
if (m_contextResetNotificationStrategy != 0) {
|
||||
if (WGLEW_ARB_create_context_robustness) {
|
||||
iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
|
||||
iAttributes.push_back(m_contextResetNotificationStrategy);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
|
||||
}
|
||||
}
|
||||
|
||||
iAttributes.push_back(0);
|
||||
|
||||
if (!s_singleContextMode || s_sharedHGLRC == NULL)
|
||||
m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0]));
|
||||
else
|
||||
m_hGLRC = s_sharedHGLRC;
|
||||
}
|
||||
else {
|
||||
if (m_contextProfileMask != 0)
|
||||
fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL profiles.");
|
||||
|
||||
if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0)
|
||||
fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL versions.");
|
||||
|
||||
if (m_contextFlags != 0)
|
||||
fprintf(stderr, "Warning! Legacy WGL is unable to set context flags.");
|
||||
|
||||
if (!s_singleContextMode || s_sharedHGLRC == NULL)
|
||||
m_hGLRC = ::wglCreateContext(m_hDC);
|
||||
else
|
||||
m_hGLRC = s_sharedHGLRC;
|
||||
}
|
||||
|
||||
if (!WIN32_CHK(m_hGLRC != NULL))
|
||||
goto error;
|
||||
|
||||
if (s_sharedHGLRC == NULL)
|
||||
s_sharedHGLRC = m_hGLRC;
|
||||
|
||||
s_sharedCount++;
|
||||
|
||||
if (!s_singleContextMode && s_sharedHGLRC != m_hGLRC && !WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC)))
|
||||
goto error;
|
||||
|
||||
if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC)))
|
||||
goto error;
|
||||
|
||||
initContextGLEW();
|
||||
|
||||
glClearColor(0.447, 0.447, 0.447, 0.000);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.000, 0.000, 0.000, 0.000);
|
||||
|
||||
#ifndef NDEBUG
|
||||
reportContextString("Vendor", m_dummyVendor, reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
|
||||
reportContextString("Renderer", m_dummyRenderer, reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
|
||||
reportContextString("Version", m_dummyVersion, reinterpret_cast<const char*>(glGetString(GL_VERSION)));
|
||||
#endif
|
||||
|
||||
return GHOST_kSuccess;
|
||||
|
||||
error:
|
||||
::wglMakeCurrent(prevHDC, prevHGLRC);
|
||||
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles()
|
||||
{
|
||||
GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure;
|
||||
|
||||
m_hWnd = NULL;
|
||||
m_hDC = NULL;
|
||||
|
||||
return success;
|
||||
}
|
180
intern/ghost/intern/GHOST_ContextWGL.h
Normal file
180
intern/ghost/intern/GHOST_ContextWGL.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file ghost/intern/GHOST_ContextWGL.h
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_ContextWGL class.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_CONTEXTWGL_H_
|
||||
#define _GHOST_CONTEXTWGL_H_
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#define wglewGetContext() wglewContext
|
||||
#include <GL/wglew.h>
|
||||
extern "C" WGLEWContext* wglewContext;
|
||||
|
||||
|
||||
|
||||
#ifndef GHOST_OPENGL_WGL_CONTEXT_FLAGS
|
||||
#define GHOST_OPENGL_WGL_CONTEXT_FLAGS 0
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
|
||||
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class GHOST_ContextWGL : public GHOST_Context
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ContextWGL(
|
||||
bool stereoVisual,
|
||||
GHOST_TUns16 numOfAASamples,
|
||||
HWND hWnd,
|
||||
HDC hDC,
|
||||
int contextProfileMask,
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int contextFlags,
|
||||
int contextResetNotificationStrategy
|
||||
);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~GHOST_ContextWGL();
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
virtual GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
|
||||
protected:
|
||||
inline void activateWGLEW() const {
|
||||
wglewContext = m_wglewContext;
|
||||
}
|
||||
|
||||
private:
|
||||
int choose_pixel_format(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB);
|
||||
|
||||
int choose_pixel_format_arb(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB);
|
||||
|
||||
int _choose_pixel_format_arb_1(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB,
|
||||
int& swapMethodOut);
|
||||
|
||||
int _choose_pixel_format_arb_2(
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
bool needStencil,
|
||||
bool sRGB,
|
||||
int swapMethod);
|
||||
|
||||
void initContextWGLEW(PIXELFORMATDESCRIPTOR& preferredPFD);
|
||||
|
||||
HDC m_hDC;
|
||||
HWND m_hWnd;
|
||||
|
||||
const int m_contextProfileMask;
|
||||
const int m_contextMajorVersion;
|
||||
const int m_contextMinorVersion;
|
||||
const int m_contextFlags;
|
||||
const int m_contextResetNotificationStrategy;
|
||||
|
||||
HGLRC m_hGLRC;
|
||||
|
||||
WGLEWContext* m_wglewContext;
|
||||
|
||||
#ifndef NDEBUG
|
||||
const char* m_dummyVendor;
|
||||
const char* m_dummyRenderer;
|
||||
const char* m_dummyVersion;
|
||||
#endif
|
||||
|
||||
static HGLRC s_sharedHGLRC;
|
||||
static int s_sharedCount;
|
||||
|
||||
static bool s_singleContextMode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _GHOST_CONTEXTWGL_H_
|
@@ -38,21 +38,22 @@
|
||||
|
||||
#include "GHOST_ISystem.h"
|
||||
|
||||
#ifdef WITH_HEADLESS
|
||||
# include "GHOST_SystemNULL.h"
|
||||
#elif defined(WITH_GHOST_SDL)
|
||||
# include "GHOST_SystemSDL.h"
|
||||
#elif defined(WIN32)
|
||||
# include "GHOST_SystemWin32.h"
|
||||
#ifdef WITH_X11
|
||||
# include "GHOST_SystemX11.h"
|
||||
#else
|
||||
# ifdef __APPLE__
|
||||
# include "GHOST_SystemCocoa.h"
|
||||
# ifdef WITH_HEADLESS
|
||||
# include "GHOST_SystemNULL.h"
|
||||
# elif defined(WITH_GHOST_SDL)
|
||||
# include "GHOST_SystemSDL.h"
|
||||
# elif defined(WIN32)
|
||||
# include "GHOST_SystemWin32.h"
|
||||
# else
|
||||
# include "GHOST_SystemX11.h"
|
||||
# ifdef __APPLE__
|
||||
# include "GHOST_SystemCocoa.h"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
GHOST_ISystem *GHOST_ISystem::m_system = 0;
|
||||
|
||||
|
||||
@@ -60,19 +61,21 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
if (!m_system) {
|
||||
#ifdef WITH_HEADLESS
|
||||
m_system = new GHOST_SystemNULL();
|
||||
#elif defined(WITH_GHOST_SDL)
|
||||
m_system = new GHOST_SystemSDL();
|
||||
#elif defined(WIN32)
|
||||
m_system = new GHOST_SystemWin32();
|
||||
#else
|
||||
# ifdef __APPLE__
|
||||
m_system = new GHOST_SystemCocoa();
|
||||
# else
|
||||
#ifdef WITH_X11
|
||||
m_system = new GHOST_SystemX11();
|
||||
#else
|
||||
# ifdef WITH_HEADLESS
|
||||
m_system = new GHOST_SystemNULL();
|
||||
# elif defined(WITH_GHOST_SDL)
|
||||
m_system = new GHOST_SystemSDL();
|
||||
# elif defined(WIN32)
|
||||
m_system = new GHOST_SystemWin32();
|
||||
# else
|
||||
# ifdef __APPLE__
|
||||
m_system = new GHOST_SystemCocoa();
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
success = m_system != 0 ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
|
@@ -254,27 +254,6 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
|
||||
}
|
||||
|
||||
|
||||
#pragma mark defines for 10.6 api not documented in 10.5
|
||||
|
||||
#pragma mark Utility functions
|
||||
|
||||
#define FIRSTFILEBUFLG 512
|
||||
static bool g_hasFirstFile = false;
|
||||
static char g_firstFileBuf[512];
|
||||
|
||||
//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
|
||||
{
|
||||
if (g_hasFirstFile) {
|
||||
strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
|
||||
buf[FIRSTFILEBUFLG - 1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Cocoa objects
|
||||
|
||||
/**
|
||||
@@ -338,8 +317,6 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
|
||||
|
||||
#pragma mark initialization/finalization
|
||||
|
||||
char GHOST_user_locale[128]; // Global current user locale
|
||||
|
||||
GHOST_SystemCocoa::GHOST_SystemCocoa()
|
||||
{
|
||||
int mib[2];
|
||||
@@ -377,15 +354,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
|
||||
rstring = NULL;
|
||||
|
||||
m_ignoreWindowSizedMessages = false;
|
||||
|
||||
//Get current locale
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
|
||||
NSLocale * myNSLocale = (NSLocale *) myCFLocale;
|
||||
[myNSLocale autorelease];
|
||||
NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
||||
strncpy(GHOST_user_locale, [nsIdentifier UTF8String], sizeof(GHOST_user_locale) - 1);
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
GHOST_SystemCocoa::~GHOST_SystemCocoa()
|
||||
@@ -566,25 +534,21 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
|
||||
window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, stereoVisual, numOfAASamples);
|
||||
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
//Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
//Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");
|
||||
GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
return window;
|
||||
}
|
||||
|
@@ -227,6 +227,12 @@ void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns3
|
||||
}
|
||||
|
||||
GHOST_IWindow *GHOST_SystemWin32::createWindow(
|
||||
<<<<<<< HEAD
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state, GHOST_TDrawingContextType type,
|
||||
bool wantStereoVisual, const bool exclusive, const GHOST_TUns16 wantNumOfAASamples, const GHOST_TEmbedderWindowID parentWindow)
|
||||
=======
|
||||
const STR_String &title,
|
||||
GHOST_TInt32 left, GHOST_TInt32 top,
|
||||
GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
@@ -235,40 +241,35 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
|
||||
const bool exclusive,
|
||||
const GHOST_TUns16 numOfAASamples,
|
||||
const GHOST_TEmbedderWindowID parentWindow)
|
||||
>>>>>>> master
|
||||
{
|
||||
GHOST_Window *window = 0;
|
||||
window = new GHOST_WindowWin32(this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples, parentWindow);
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
// if (state != GHOST_kWindowStateFullScreen) {
|
||||
GHOST_Window *window =
|
||||
new GHOST_WindowWin32(
|
||||
this,
|
||||
title,
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
state,
|
||||
type,
|
||||
wantStereoVisual,
|
||||
wantNumOfAASamples,
|
||||
parentWindow);
|
||||
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
//if (state != GHOST_kWindowStateFullScreen) {
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
// }
|
||||
}
|
||||
else {
|
||||
|
||||
// Invalid parent window hwnd
|
||||
if (((GHOST_WindowWin32 *)window)->getNextWindow() == NULL) {
|
||||
delete window;
|
||||
window = 0;
|
||||
return window;
|
||||
}
|
||||
|
||||
// An invalid window could be one that was used to test for AA
|
||||
window = ((GHOST_WindowWin32 *)window)->getNextWindow();
|
||||
|
||||
// If another window is found, let the wm know about that one, but not the old one
|
||||
if (window->getValid()) {
|
||||
m_windowManager->addWindow(window);
|
||||
}
|
||||
else {
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n");
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
@@ -55,6 +55,7 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/XKBlib.h> /* allow detectable autorepeate */
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef WITH_XF86KEYSYM
|
||||
#include <X11/XF86keysym.h>
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#define __GHOST_SYSTEMX11_H__
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include "GHOST_System.h"
|
||||
#include "../GHOST_Types.h"
|
||||
|
@@ -38,21 +38,26 @@
|
||||
|
||||
#include "GHOST_Window.h"
|
||||
|
||||
#include "GHOST_ContextNone.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
GHOST_Window::GHOST_Window(
|
||||
GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const bool exclusive,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
: m_drawingContextType(type),
|
||||
m_cursorVisible(true),
|
||||
m_cursorGrab(GHOST_kGrabDisable),
|
||||
m_cursorShape(GHOST_kStandardCursorDefault),
|
||||
m_stereoVisual(stereoVisual),
|
||||
m_numOfAASamples(numOfAASamples)
|
||||
GHOST_TUns32 width, GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
const bool wantStereoVisual,
|
||||
const bool exclusive,
|
||||
const GHOST_TUns16 wantNumOfAASamples
|
||||
)
|
||||
: m_drawingContextType(GHOST_kDrawingContextTypeNone)
|
||||
, m_cursorVisible(true)
|
||||
, m_cursorGrab(GHOST_kGrabDisable)
|
||||
, m_cursorShape(GHOST_kStandardCursorDefault)
|
||||
, m_wantStereoVisual(wantStereoVisual)
|
||||
, m_wantNumOfAASamples(wantNumOfAASamples)
|
||||
, m_context(new GHOST_ContextNone(false, 0))
|
||||
{
|
||||
m_isUnsavedChanges = false;
|
||||
m_canAcceptDragOperation = false;
|
||||
@@ -65,6 +70,7 @@ GHOST_Window::GHOST_Window(
|
||||
m_nativePixelSize = 1.0f;
|
||||
|
||||
m_fullScreen = state == GHOST_kWindowStateFullScreen;
|
||||
|
||||
if (m_fullScreen) {
|
||||
m_fullScreenWidth = width;
|
||||
m_fullScreenHeight = height;
|
||||
@@ -72,29 +78,77 @@ GHOST_Window::GHOST_Window(
|
||||
}
|
||||
|
||||
|
||||
|
||||
GHOST_Window::~GHOST_Window()
|
||||
{
|
||||
delete m_context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *GHOST_Window::getOSWindow() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kSuccess;
|
||||
if (type != m_drawingContextType) {
|
||||
success = removeDrawingContext();
|
||||
if (success) {
|
||||
success = installDrawingContext(type);
|
||||
delete m_context;
|
||||
m_context = NULL;
|
||||
|
||||
if (type != GHOST_kDrawingContextTypeNone)
|
||||
m_context = newDrawingContext(type);
|
||||
|
||||
if (m_context != NULL) {
|
||||
m_drawingContextType = type;
|
||||
}
|
||||
else {
|
||||
m_context = new GHOST_ContextNone(m_wantStereoVisual, m_wantNumOfAASamples);
|
||||
m_drawingContextType = GHOST_kDrawingContextTypeNone;
|
||||
}
|
||||
|
||||
return (type == m_drawingContextType) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
return success;
|
||||
else {
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::swapBuffers()
|
||||
{
|
||||
return m_context->swapBuffers();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::setSwapInterval(int interval)
|
||||
{
|
||||
return m_context->setSwapInterval(interval);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
return m_context->getSwapInterval(intervalOut);
|
||||
}
|
||||
|
||||
GHOST_TUns16 GHOST_Window::getNumOfAASamples()
|
||||
{
|
||||
return m_context->getNumOfAASamples();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::activateDrawingContext()
|
||||
{
|
||||
return m_context->activateDrawingContext();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::updateDrawingContext()
|
||||
{
|
||||
return m_context->updateDrawingContext();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::releaseNativeHandles()
|
||||
{
|
||||
return m_context->releaseNativeHandles();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "GHOST_IWindow.h"
|
||||
|
||||
class STR_String;
|
||||
class GHOST_Context;
|
||||
|
||||
/**
|
||||
* Platform independent implementation of GHOST_IWindow.
|
||||
@@ -49,29 +50,6 @@ class STR_String;
|
||||
class GHOST_Window : public GHOST_IWindow
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \section Interface inherited from GHOST_IWindow left for derived class
|
||||
* implementation.
|
||||
* virtual bool getValid() const = 0;
|
||||
* virtual void setTitle(const STR_String& title) = 0;
|
||||
* virtual void getTitle(STR_String& title) const = 0;
|
||||
* virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
|
||||
* virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
|
||||
* virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
|
||||
* virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0;
|
||||
* virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0;
|
||||
* virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
|
||||
* virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const = 0;
|
||||
* virtual GHOST_TWindowState getState() const = 0;
|
||||
* virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
|
||||
* virtual GHOST_TWindowOrder getOrder(void) = 0;
|
||||
* virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
|
||||
* virtual GHOST_TSuccess swapBuffers() = 0;
|
||||
* virtual GHOST_TSuccess setSwapInterval() = 0;
|
||||
* virtual int getSwapInterval() = 0;
|
||||
* virtual GHOST_TSuccess activateDrawingContext() = 0;
|
||||
* virtual GHOST_TSuccess invalidate() = 0;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -90,10 +68,9 @@ public:
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false,
|
||||
const bool wantStereoVisual = false,
|
||||
const bool exclusive = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0);
|
||||
const GHOST_TUns16 wantNumOfAASamples = 0);
|
||||
|
||||
/**
|
||||
* \section Interface inherited from GHOST_IWindow left for derived class
|
||||
@@ -113,17 +90,25 @@ public:
|
||||
* virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0;
|
||||
* virtual GHOST_TSuccess swapBuffers() = 0;
|
||||
* virtual GHOST_TSuccess setSwapInterval() = 0;
|
||||
* virtual int getSwapInterval() = 0;
|
||||
* virtual GHOST_TSuccess getSwapInterval(int& intervalOut) = 0;
|
||||
* virtual GHOST_TSuccess activateDrawingContext() = 0;
|
||||
* virtual GHOST_TSuccess invalidate() = 0;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Closes the window and disposes resources allocated.
|
||||
*/
|
||||
virtual ~GHOST_Window();
|
||||
|
||||
/**
|
||||
* Returns indication as to whether the window is valid.
|
||||
* \return The validity of the window.
|
||||
*/
|
||||
virtual bool getValid() const {
|
||||
return m_context != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associated OS object/handle
|
||||
* \return The associated OS object/handle
|
||||
@@ -213,18 +198,20 @@ public:
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return An integer.
|
||||
*/
|
||||
virtual int getSwapInterval() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return Number of AA Samples (0 if there is no multisample buffer)
|
||||
*/
|
||||
virtual GHOST_TUns16 getNumOfAASamples();
|
||||
|
||||
/**
|
||||
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
|
||||
*/
|
||||
@@ -257,13 +244,32 @@ public:
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* Child classes do not need to overload this method.
|
||||
* They should overload the installDrawingContext and removeDrawingContext instead.
|
||||
* Child classes do not need to overload this method,
|
||||
* They should overload newDrawingContext instead.
|
||||
* \param type The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window. Needed
|
||||
* whenever the window is changed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
/**
|
||||
* Returns the window user data.
|
||||
* \return The window user data.
|
||||
@@ -295,13 +301,7 @@ protected:
|
||||
* \param type The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type) = 0;
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* \return Indication as to whether removal has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess removeDrawingContext() = 0;
|
||||
virtual GHOST_Context* newDrawingContext(GHOST_TDrawingContextType type) = 0;
|
||||
|
||||
/**
|
||||
* Sets the cursor visibility on the window using
|
||||
@@ -333,6 +333,9 @@ protected:
|
||||
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
|
||||
int szx, int szy, int hotX, int hotY, int fg, int bg) = 0;
|
||||
|
||||
GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/** The the of drawing context installed in this window. */
|
||||
GHOST_TDrawingContextType m_drawingContextType;
|
||||
|
||||
@@ -369,14 +372,11 @@ protected:
|
||||
/** Stores whether this is a full screen window. */
|
||||
bool m_fullScreen;
|
||||
|
||||
/** Stereo visual created. Only necessary for 'real' stereo support,
|
||||
* ie quad buffered stereo. This is not always possible, depends on
|
||||
* the graphics h/w
|
||||
*/
|
||||
bool m_stereoVisual;
|
||||
|
||||
/** Number of samples used in anti-aliasing, set to 0 if no AA **/
|
||||
GHOST_TUns16 m_numOfAASamples;
|
||||
/** Whether to attempt to initialize a context with a stereo framebuffer. */
|
||||
bool m_wantStereoVisual;
|
||||
|
||||
/** Attempt to initialize a context with this many samples. */
|
||||
GHOST_TUns16 m_wantNumOfAASamples;
|
||||
|
||||
/** Full-screen width */
|
||||
GHOST_TUns32 m_fullScreenWidth;
|
||||
@@ -385,6 +385,9 @@ protected:
|
||||
|
||||
/* OSX only, retina screens */
|
||||
float m_nativePixelSize;
|
||||
|
||||
private:
|
||||
GHOST_Context* m_context;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -42,6 +42,8 @@
|
||||
|
||||
@class CocoaWindow;
|
||||
@class CocoaOpenGLView;
|
||||
@class NSCursor;
|
||||
@class NSScreen;
|
||||
|
||||
class GHOST_SystemCocoa;
|
||||
|
||||
@@ -53,6 +55,7 @@ class GHOST_SystemCocoa;
|
||||
* which is called the gutter.
|
||||
* When OpenGL contexts are active, GHOST will use AGL_BUFFER_RECT to prevent
|
||||
* OpenGL drawing outside the reduced client rectangle.
|
||||
* XXX jwilkins: This comment seems out of date since we neither use Carbon nor AGL
|
||||
* \author Maarten Gribnau
|
||||
* \date May 23, 2001
|
||||
*/
|
||||
@@ -220,28 +223,8 @@ public:
|
||||
*/
|
||||
virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window. Needed
|
||||
* whenever the window is changed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
|
||||
|
||||
|
||||
const GHOST_TabletData *GetTabletData()
|
||||
{
|
||||
return &m_tablet;
|
||||
@@ -278,19 +261,13 @@ public:
|
||||
bool getImmediateDraw(void) const { return m_immediateDraw; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param type The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* \return Indication as to whether removal has succeeded.
|
||||
* \param type The type of rendering context create.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess removeDrawingContext();
|
||||
|
||||
virtual GHOST_Context* newDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Invalidates the contents of this window.
|
||||
* \return Indication of success.
|
||||
@@ -330,15 +307,9 @@ protected:
|
||||
/** The openGL view */
|
||||
CocoaOpenGLView *m_openGLView;
|
||||
|
||||
/** The opgnGL drawing context */
|
||||
NSOpenGLContext *m_openGLContext;
|
||||
|
||||
/** The mother SystemCocoa class to send events */
|
||||
GHOST_SystemCocoa *m_systemCocoa;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static NSOpenGLContext *s_firstOpenGLcontext;
|
||||
|
||||
|
||||
NSCursor *m_customCursor;
|
||||
|
||||
GHOST_TabletData m_tablet;
|
||||
@@ -349,4 +320,3 @@ protected:
|
||||
};
|
||||
|
||||
#endif // __GHOST_WINDOWCOCOA_H__
|
||||
|
||||
|
@@ -20,12 +20,26 @@
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Maarten Gribnau 05/2001
|
||||
Damien Plisson 10/2009
|
||||
* Contributor(s): Maarten Gribnau 05/2001
|
||||
* Damien Plisson 10/2009
|
||||
* Jason Wilkins 02/2014
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "GHOST_WindowCocoa.h"
|
||||
#include "GHOST_SystemCocoa.h"
|
||||
#include "GHOST_ContextNone.h"
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
#include "GHOST_ContextCGL.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
#include "GHOST_ContextEGL.h"
|
||||
#endif
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
|
||||
@@ -33,17 +47,8 @@
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/CGLRenderers.h>
|
||||
/***** Multithreaded opengl code : uncomment for enabling
|
||||
#include <OpenGL/OpenGL.h>
|
||||
*/
|
||||
|
||||
|
||||
#include "GHOST_WindowCocoa.h"
|
||||
#include "GHOST_SystemCocoa.h"
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
|
||||
@@ -535,8 +540,6 @@ enum {
|
||||
@end
|
||||
#endif
|
||||
|
||||
NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil;
|
||||
|
||||
GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
GHOST_SystemCocoa *systemCocoa,
|
||||
const STR_String& title,
|
||||
@@ -546,185 +549,92 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual, const GHOST_TUns16 numOfAASamples
|
||||
const bool stereoVisual,
|
||||
const GHOST_TUns16 numOfAASamples
|
||||
) :
|
||||
GHOST_Window(width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual, false, numOfAASamples),
|
||||
GHOST_Window(width, height, state, stereoVisual, false, numOfAASamples),
|
||||
m_customCursor(0)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40];
|
||||
NSOpenGLPixelFormat *pixelFormat = nil;
|
||||
int i;
|
||||
|
||||
m_systemCocoa = systemCocoa;
|
||||
m_fullScreen = false;
|
||||
m_immediateDraw = false;
|
||||
m_lionStyleFullScreen = false;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
//Creates the window
|
||||
NSRect rect;
|
||||
NSSize minSize;
|
||||
|
||||
|
||||
rect.origin.x = left;
|
||||
rect.origin.y = bottom;
|
||||
rect.size.width = width;
|
||||
rect.size.height = height;
|
||||
|
||||
|
||||
m_window = [[CocoaWindow alloc] initWithContentRect:rect
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
|
||||
if (m_window == nil) {
|
||||
[pool drain];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
|
||||
|
||||
|
||||
//Forbid to resize the window below the blender defined minimum one
|
||||
minSize.width = 320;
|
||||
minSize.height = 240;
|
||||
[m_window setContentMinSize:minSize];
|
||||
|
||||
|
||||
setTitle(title);
|
||||
|
||||
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
i=0;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
|
||||
|
||||
// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext object's flushBuffer
|
||||
// needed for 'Draw Overlap' drawing method
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
|
||||
|
||||
// Force software OpenGL, for debugging
|
||||
if (getenv("BLENDER_SOFTWAREGL")) {
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
|
||||
pixelFormatAttrsWindow[i++] = kCGLRendererAppleSWID;
|
||||
}
|
||||
else
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
|
||||
|
||||
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccumSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
if (numOfAASamples > 0) {
|
||||
// Multisample anti-aliasing
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAMultisample;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFASampleBuffers;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFASamples;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) numOfAASamples;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFANoRecovery;
|
||||
}
|
||||
|
||||
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
|
||||
|
||||
//Fall back to no multisampling if Antialiasing init failed
|
||||
if (pixelFormat == nil) {
|
||||
i=0;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
|
||||
|
||||
// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext object's flushBuffer
|
||||
// needed for 'Draw Overlap' drawing method
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
|
||||
|
||||
// Force software OpenGL, for debugging
|
||||
if (getenv("BLENDER_SOFTWAREGL")) {
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
|
||||
pixelFormatAttrsWindow[i++] = kCGLRendererAppleSWID;
|
||||
}
|
||||
else
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
|
||||
|
||||
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccumSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
|
||||
}
|
||||
|
||||
if (numOfAASamples > 0) { //Set m_numOfAASamples to the actual value
|
||||
GLint gli;
|
||||
[pixelFormat getValues:&gli forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
|
||||
if (m_numOfAASamples != (GHOST_TUns16)gli) {
|
||||
m_numOfAASamples = (GHOST_TUns16)gli;
|
||||
printf("GHOST_Window could be created with anti-aliasing of only %i samples\n",m_numOfAASamples);
|
||||
}
|
||||
}
|
||||
|
||||
//Creates the OpenGL View inside the window
|
||||
m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
|
||||
pixelFormat:pixelFormat];
|
||||
m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect];
|
||||
|
||||
[m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
|
||||
|
||||
[pixelFormat release];
|
||||
|
||||
m_openGLContext = [m_openGLView openGLContext]; //This context will be replaced by the proper one just after
|
||||
|
||||
|
||||
[m_window setContentView:m_openGLView];
|
||||
[m_window setInitialFirstResponder:m_openGLView];
|
||||
|
||||
|
||||
[m_window makeKeyAndOrderFront:nil];
|
||||
|
||||
|
||||
setDrawingContextType(type);
|
||||
updateDrawingContext();
|
||||
activateDrawingContext();
|
||||
|
||||
// XXX jwilkins: This seems like it belongs in GHOST_ContextCGL, but probably not GHOST_ContextEGL
|
||||
if (m_systemCocoa->m_nativePixel) {
|
||||
if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
|
||||
[m_openGLView setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
|
||||
NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
|
||||
m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_tablet.Active = GHOST_kTabletModeNone;
|
||||
|
||||
|
||||
CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
|
||||
[windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
|
||||
[m_window setDelegate:windowDelegate];
|
||||
|
||||
|
||||
[m_window setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
NSView *view = [m_window contentView];
|
||||
[view setAcceptsTouchEvents:YES];
|
||||
#endif
|
||||
|
||||
|
||||
[m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
|
||||
NSStringPboardType, NSTIFFPboardType, nil]];
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
if (state != GHOST_kWindowStateFullScreen) {
|
||||
[m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (state == GHOST_kWindowStateFullScreen)
|
||||
setState(GHOST_kWindowStateFullScreen);
|
||||
|
||||
@@ -736,7 +646,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
if(darwin_ver[0] == '1' && darwin_ver[1] >= '3') {
|
||||
m_lionStyleFullScreen = true;
|
||||
}
|
||||
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
@@ -750,12 +660,14 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
m_customCursor = nil;
|
||||
}
|
||||
|
||||
releaseNativeHandles();
|
||||
|
||||
[m_openGLView release];
|
||||
|
||||
|
||||
if (m_window) {
|
||||
[m_window close];
|
||||
}
|
||||
|
||||
|
||||
// Check for other blender opened windows and make the frontmost key
|
||||
// Note: for some reason the closed window is still in the list
|
||||
NSArray *windowsList = [NSApp orderedWindows];
|
||||
@@ -774,7 +686,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
|
||||
bool GHOST_WindowCocoa::getValid() const
|
||||
{
|
||||
return (m_window != 0);
|
||||
return GHOST_Window::getValid() && m_window != 0 && m_openGLView != 0;
|
||||
}
|
||||
|
||||
void* GHOST_WindowCocoa::getOSWindow() const
|
||||
@@ -1266,131 +1178,97 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
||||
|
||||
#pragma mark Drawing context
|
||||
|
||||
/*#define WAIT_FOR_VSYNC 1*/
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
|
||||
GHOST_Context* GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext flushBuffer];
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
|
||||
{
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext update];
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
||||
{
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_openGLContext != nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[m_openGLContext makeCurrentContext];
|
||||
|
||||
// Disable AA by default
|
||||
if (m_numOfAASamples > 0) glDisable(GL_MULTISAMPLE_ARB);
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
NSOpenGLContext *tmpOpenGLContext;
|
||||
|
||||
/***** Multithreaded opengl code : uncomment for enabling
|
||||
CGLContextObj cglCtx;
|
||||
*/
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
if (!getValid()) break;
|
||||
|
||||
pixelFormat = [m_openGLView pixelFormat];
|
||||
tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
|
||||
shareContext:s_firstOpenGLcontext];
|
||||
if (tmpOpenGLContext == nil) {
|
||||
success = GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
//Switch openGL to multhreaded mode
|
||||
/******* Multithreaded opengl code : uncomment for enabling
|
||||
cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj];
|
||||
if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError)
|
||||
printf("\nSwitched openGL to multithreaded mode\n");
|
||||
*/
|
||||
|
||||
if (!s_firstOpenGLcontext) s_firstOpenGLcontext = tmpOpenGLContext;
|
||||
#ifdef WAIT_FOR_VSYNC
|
||||
{
|
||||
GLint swapInt = 1;
|
||||
/* wait for vsync, to avoid tearing artifacts */
|
||||
[tmpOpenGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextCGL(
|
||||
m_initStereoVisual,
|
||||
m_initNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
CGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextCGL(
|
||||
m_initStereoVisual,
|
||||
m_initNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
CGL_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextCGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
[m_openGLView setOpenGLContext:tmpOpenGLContext];
|
||||
[tmpOpenGLContext setView:m_openGLView];
|
||||
|
||||
m_openGLContext = tmpOpenGLContext;
|
||||
break;
|
||||
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[pool drain];
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
switch (m_drawingContextType) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
if (m_openGLContext) {
|
||||
[m_openGLView clearGLContext];
|
||||
if (s_firstOpenGLcontext == m_openGLContext) s_firstOpenGLcontext = nil;
|
||||
m_openGLContext = nil;
|
||||
}
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
break;
|
||||
default:
|
||||
[pool drain];
|
||||
return GHOST_kFailure;
|
||||
|
||||
#elif defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#pragma mark invalidate
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
|
||||
{
|
||||
|
@@ -26,7 +26,8 @@
|
||||
|
||||
#include "GHOST_WindowSDL.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include <GL/glew.h>
|
||||
#include "glew-mx.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static SDL_GLContext s_firstContext = NULL;
|
||||
@@ -646,8 +647,9 @@ GHOST_WindowSDL::setSwapInterval(int interval)
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
int
|
||||
GHOST_WindowSDL::getSwapInterval()
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowSDL::getSwapInterval(int& intervalOut)
|
||||
{
|
||||
return SDL_GL_GetSwapInterval();
|
||||
intervalOut = SDL_GL_GetSwapInterval();
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
@@ -174,7 +174,7 @@ protected:
|
||||
GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
|
||||
|
||||
GHOST_TSuccess setSwapInterval(int interval);
|
||||
int getSwapInterval();
|
||||
GHOST_TSuccess getSwapInterval(int& intervalOut);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -29,32 +29,34 @@
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "GHOST_WindowWin32.h"
|
||||
#include "GHOST_SystemWin32.h"
|
||||
#include "GHOST_DropTargetWin32.h"
|
||||
#include "GHOST_ContextNone.h"
|
||||
#include "utfconv.h"
|
||||
#include "utf_winfunc.h"
|
||||
|
||||
// Need glew for some defines
|
||||
#include <GL/glew.h>
|
||||
#include <GL/wglew.h>
|
||||
#include <math.h>
|
||||
|
||||
// MSVC6 still doesn't define M_PI
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.1415926536
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
#include "GHOST_ContextWGL.h"
|
||||
#endif
|
||||
|
||||
// Some more multisample defines
|
||||
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#if defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
#include "GHOST_ContextEGL.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
|
||||
const int GHOST_WindowWin32::s_maxTitleLength = 128;
|
||||
HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL;
|
||||
HDC GHOST_WindowWin32::s_firstHDC = NULL;
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
static int WeightPixelFormat(PIXELFORMATDESCRIPTOR &pfd);
|
||||
static int EnumPixelFormats(HDC hdc);
|
||||
|
||||
@@ -97,14 +99,9 @@ static PIXELFORMATDESCRIPTOR sPreferredFormat = {
|
||||
static int is_crappy_intel_card(void)
|
||||
{
|
||||
static short is_crappy = -1;
|
||||
>>>>>>> master
|
||||
|
||||
if (is_crappy == -1) {
|
||||
const char *vendor = (const char *)glGetString(GL_VENDOR);
|
||||
is_crappy = (strstr(vendor, "Intel") != NULL);
|
||||
}
|
||||
|
||||
return is_crappy;
|
||||
}
|
||||
|
||||
/* force NVidia Optimus to used dedicated graphics */
|
||||
extern "C" {
|
||||
@@ -112,6 +109,34 @@ extern "C" {
|
||||
}
|
||||
|
||||
GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
<<<<<<< HEAD
|
||||
GHOST_SystemWin32 *system,
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
bool wantStereoVisual,
|
||||
GHOST_TUns16 wantNumOfAASamples,
|
||||
GHOST_TEmbedderWindowID parentwindowhwnd
|
||||
)
|
||||
: GHOST_Window(width, height, state, wantStereoVisual, false, wantNumOfAASamples),
|
||||
m_inLiveResize(false),
|
||||
m_system(system),
|
||||
m_hDC(0),
|
||||
m_hasMouseCaptured(false),
|
||||
m_hasGrabMouse(false),
|
||||
m_nPressedButtons(0),
|
||||
m_customCursor(0),
|
||||
m_wintab(NULL),
|
||||
m_tabletData(NULL),
|
||||
m_tablet(0),
|
||||
m_maxPressure(0),
|
||||
m_normal_state(GHOST_kWindowStateNormal),
|
||||
m_parentWindowHwnd(parentwindowhwnd)
|
||||
=======
|
||||
GHOST_SystemWin32 *system,
|
||||
const STR_String &title,
|
||||
GHOST_TInt32 left,
|
||||
@@ -152,6 +177,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
m_stereo(stereoVisual),
|
||||
m_nextWindow(NULL),
|
||||
m_parentWindowHwnd(parentwindowhwnd)
|
||||
>>>>>>> master
|
||||
{
|
||||
OSVERSIONINFOEX versionInfo;
|
||||
bool hasMinVersionForTaskbar = false;
|
||||
@@ -272,6 +298,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
0); // pointer to window-creation data
|
||||
free(title_16);
|
||||
}
|
||||
|
||||
if (m_hWnd) {
|
||||
// Register this window as a droptarget. Requires m_hWnd to be valid.
|
||||
// Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32.
|
||||
@@ -286,35 +313,37 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
// Store the device context
|
||||
m_hDC = ::GetDC(m_hWnd);
|
||||
|
||||
if (!s_firstHDC) {
|
||||
s_firstHDC = m_hDC;
|
||||
}
|
||||
|
||||
// Show the window
|
||||
int nCmdShow;
|
||||
switch (state) {
|
||||
case GHOST_kWindowStateMaximized:
|
||||
nCmdShow = SW_SHOWMAXIMIZED;
|
||||
break;
|
||||
case GHOST_kWindowStateMinimized:
|
||||
nCmdShow = SW_SHOWMINIMIZED;
|
||||
break;
|
||||
case GHOST_kWindowStateNormal:
|
||||
default:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
break;
|
||||
}
|
||||
GHOST_TSuccess success;
|
||||
success = setDrawingContextType(type);
|
||||
GHOST_TSuccess success = setDrawingContextType(type);
|
||||
|
||||
if (success) {
|
||||
// Show the window
|
||||
int nCmdShow;
|
||||
switch (state) {
|
||||
case GHOST_kWindowStateMaximized:
|
||||
nCmdShow = SW_SHOWMAXIMIZED;
|
||||
break;
|
||||
case GHOST_kWindowStateMinimized:
|
||||
nCmdShow = SW_SHOWMINIMIZED;
|
||||
break;
|
||||
case GHOST_kWindowStateNormal:
|
||||
default:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
if (success) {
|
||||
>>>>>>> master
|
||||
::ShowWindow(m_hWnd, nCmdShow);
|
||||
|
||||
// Force an initial paint of the window
|
||||
::UpdateWindow(m_hWnd);
|
||||
}
|
||||
else {
|
||||
//invalidate the window
|
||||
m_hWnd = 0;
|
||||
::DestroyWindow(m_hWnd);
|
||||
m_hWnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +444,10 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
m_customCursor = NULL;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles())
|
||||
::ReleaseDC(m_hWnd, m_hDC);
|
||||
=======
|
||||
::wglMakeCurrent(NULL, NULL);
|
||||
m_multisampleEnabled = GHOST_kFailure;
|
||||
m_multisample = 0;
|
||||
@@ -424,6 +457,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
::ReleaseDC(m_hWnd, m_hDC);
|
||||
m_hDC = 0;
|
||||
}
|
||||
>>>>>>> master
|
||||
|
||||
if (m_hWnd) {
|
||||
if (m_dropTarget) {
|
||||
@@ -438,14 +472,9 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_Window *GHOST_WindowWin32::getNextWindow()
|
||||
{
|
||||
return m_nextWindow;
|
||||
}
|
||||
|
||||
bool GHOST_WindowWin32::getValid() const
|
||||
{
|
||||
return m_hWnd != 0;
|
||||
return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0;
|
||||
}
|
||||
|
||||
HWND GHOST_WindowWin32::getHWND() const
|
||||
@@ -678,49 +707,6 @@ GHOST_TSuccess GHOST_WindowWin32::setOrder(GHOST_TWindowOrder order)
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::swapBuffers()
|
||||
{
|
||||
HDC hDC = m_hDC;
|
||||
|
||||
if (is_crappy_intel_card())
|
||||
hDC = ::wglGetCurrentDC();
|
||||
|
||||
return ::SwapBuffers(hDC) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::setSwapInterval(int interval)
|
||||
{
|
||||
if (!WGL_EXT_swap_control)
|
||||
return GHOST_kFailure;
|
||||
return wglSwapIntervalEXT(interval) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
int GHOST_WindowWin32::getSwapInterval()
|
||||
{
|
||||
if (WGL_EXT_swap_control)
|
||||
return wglGetSwapIntervalEXT();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::activateDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_hDC && m_hGlRc) {
|
||||
success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::invalidate()
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
@@ -733,264 +719,116 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
|
||||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
|
||||
|
||||
|
||||
GHOST_Context* GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
int pixelFormat;
|
||||
bool success = FALSE;
|
||||
UINT numFormats;
|
||||
HDC hDC = GetDC(getHWND());
|
||||
float fAttributes[] = {0, 0};
|
||||
UINT nMaxFormats = 1;
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
|
||||
// The attributes to look for
|
||||
int iAttributes[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||
WGL_COLOR_BITS_ARB, pfd.cColorBits,
|
||||
WGL_DEPTH_BITS_ARB, pfd.cDepthBits,
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
WGL_ALPHA_BITS_ARB, pfd.cAlphaBits,
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
WGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_WGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_WGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_WGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
WGL_STENCIL_BITS_ARB, pfd.cStencilBits,
|
||||
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||
WGL_SAMPLES_ARB, m_multisample,
|
||||
0, 0
|
||||
};
|
||||
|
||||
// Get the function
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
#elif defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
=======
|
||||
if (!wglChoosePixelFormatARB) {
|
||||
m_multisampleEnabled = GHOST_kFailure;
|
||||
return GHOST_kFailure;
|
||||
>>>>>>> master
|
||||
}
|
||||
|
||||
// iAttributes[17] is the initial multisample. If not valid try to use the closest valid value under it.
|
||||
while (iAttributes[17] > 0) {
|
||||
// See if the format is valid
|
||||
success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, nMaxFormats, &pixelFormat, &numFormats);
|
||||
GHOST_PRINTF("WGL_SAMPLES_ARB = %i --> success = %i, %i formats\n", iAttributes[17], success, numFormats);
|
||||
|
||||
if (success && numFormats >= 1 && m_multisampleEnabled == GHOST_kFailure) {
|
||||
GHOST_PRINTF("valid pixel format with %i multisamples\n", iAttributes[17]);
|
||||
m_multisampleEnabled = GHOST_kSuccess;
|
||||
m_msPixelFormat = pixelFormat;
|
||||
}
|
||||
iAttributes[17] -= 1;
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
if (m_multisampleEnabled == GHOST_kSuccess) {
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
GHOST_PRINT("no available pixel format\n");
|
||||
return GHOST_kFailure;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
{
|
||||
// If this window has multisample enabled, use the supplied format
|
||||
if (m_multisampleEnabled)
|
||||
{
|
||||
if (SetPixelFormat(m_hDC, m_msPixelFormat, &sPreferredFormat) == FALSE)
|
||||
{
|
||||
success = GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the context
|
||||
m_hGlRc = ::wglCreateContext(m_hDC);
|
||||
if (m_hGlRc) {
|
||||
if (::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE) {
|
||||
if (s_firsthGLRc) {
|
||||
if (is_crappy_intel_card()) {
|
||||
if (::wglMakeCurrent(NULL, NULL) == TRUE) {
|
||||
::wglDeleteContext(m_hGlRc);
|
||||
m_hGlRc = s_firsthGLRc;
|
||||
}
|
||||
else {
|
||||
::wglDeleteContext(m_hGlRc);
|
||||
m_hGlRc = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
::wglCopyContext(s_firsthGLRc, m_hGlRc, GL_ALL_ATTRIB_BITS);
|
||||
::wglShareLists(s_firsthGLRc, m_hGlRc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
s_firsthGLRc = m_hGlRc;
|
||||
}
|
||||
|
||||
if (m_hGlRc) {
|
||||
success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
|
||||
if (success == GHOST_kFailure) {
|
||||
printf("Failed to get a context....\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_stereoVisual)
|
||||
sPreferredFormat.dwFlags |= PFD_STEREO;
|
||||
|
||||
// Attempt to match device context pixel format to the preferred format
|
||||
int iPixelFormat = EnumPixelFormats(m_hDC);
|
||||
if (iPixelFormat == 0) {
|
||||
success = GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
if (::SetPixelFormat(m_hDC, iPixelFormat, &sPreferredFormat) == FALSE) {
|
||||
success = GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
// For debugging only: retrieve the pixel format chosen
|
||||
PIXELFORMATDESCRIPTOR preferredFormat;
|
||||
::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &preferredFormat);
|
||||
|
||||
// Create the context
|
||||
m_hGlRc = ::wglCreateContext(m_hDC);
|
||||
if (m_hGlRc) {
|
||||
if (::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE) {
|
||||
if (s_firsthGLRc) {
|
||||
if (is_crappy_intel_card()) {
|
||||
if (::wglMakeCurrent(NULL, NULL) == TRUE) {
|
||||
::wglDeleteContext(m_hGlRc);
|
||||
m_hGlRc = s_firsthGLRc;
|
||||
}
|
||||
else {
|
||||
::wglDeleteContext(m_hGlRc);
|
||||
m_hGlRc = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
::wglShareLists(s_firsthGLRc, m_hGlRc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
s_firsthGLRc = m_hGlRc;
|
||||
}
|
||||
|
||||
if (m_hGlRc) {
|
||||
success = ::wglMakeCurrent(m_hDC, m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
|
||||
if (success == GHOST_kFailure) {
|
||||
printf("Failed to get a context....\n");
|
||||
}
|
||||
|
||||
// Attempt to enable multisample
|
||||
if (m_multisample && WGL_ARB_multisample && !m_multisampleEnabled && !is_crappy_intel_card())
|
||||
{
|
||||
success = initMultisample(preferredFormat);
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
||||
// Make sure we don't screw up the context
|
||||
if (m_hGlRc == s_firsthGLRc)
|
||||
s_firsthGLRc = NULL;
|
||||
m_drawingContextType = GHOST_kDrawingContextTypeOpenGL;
|
||||
removeDrawingContext();
|
||||
|
||||
// Create a new window
|
||||
GHOST_TWindowState new_state = getState();
|
||||
|
||||
m_nextWindow = new GHOST_WindowWin32((GHOST_SystemWin32 *)GHOST_ISystem::getSystem(),
|
||||
m_title,
|
||||
m_left,
|
||||
m_top,
|
||||
m_width,
|
||||
m_height,
|
||||
new_state,
|
||||
type,
|
||||
m_stereo,
|
||||
m_multisample,
|
||||
m_parentWindowHwnd,
|
||||
m_multisampleEnabled,
|
||||
m_msPixelFormat);
|
||||
|
||||
// Return failure so we can trash this window.
|
||||
success = GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
m_multisampleEnabled = GHOST_kSuccess;
|
||||
printf("Multisample failed to initialize\n");
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
|
||||
default:
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
switch (m_drawingContextType) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
// we shouldn't remove the drawing context if it's the first OpenGL context
|
||||
// If we do, we get corrupted drawing. See #19997
|
||||
if (m_hGlRc && m_hGlRc != s_firsthGLRc) {
|
||||
success = ::wglDeleteContext(m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
m_hGlRc = 0;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
break;
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
default:
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::lostMouseCapture()
|
||||
{
|
||||
if (m_hasMouseCaptured) {
|
||||
<<<<<<< HEAD
|
||||
m_hasGrabMouse = false;
|
||||
m_nPressedButtons = 0;
|
||||
=======
|
||||
m_hasGrabMouse = false;
|
||||
m_nPressedButtons = 0;
|
||||
>>>>>>> master
|
||||
m_hasMouseCaptured = false;
|
||||
}
|
||||
}
|
||||
@@ -1334,6 +1172,8 @@ GHOST_TSuccess GHOST_WindowWin32::endProgressBar()
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
/* Ron Fosner's code for weighting pixel formats and forcing software.
|
||||
* See http://www.opengl.org/resources/faq/technical/weight.cpp */
|
||||
|
||||
@@ -1424,3 +1264,4 @@ static int EnumPixelFormats(HDC hdc)
|
||||
}
|
||||
return iPixelFormat;
|
||||
}
|
||||
>>>>>>> master
|
||||
|
@@ -37,16 +37,16 @@
|
||||
#error WIN32 only!
|
||||
#endif // WIN32
|
||||
|
||||
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "GHOST_Window.h"
|
||||
#include "GHOST_TaskbarWin32.h"
|
||||
|
||||
#ifndef __MINGW64__
|
||||
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#include <wintab.h>
|
||||
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
|
||||
#define PACKETMODE PK_BUTTONS
|
||||
@@ -73,15 +73,16 @@ public:
|
||||
* Constructor.
|
||||
* Creates a new window and opens it.
|
||||
* To check if the window was created properly, use the getValid() method.
|
||||
* \param title The text shown in the title bar of the window.
|
||||
* \param left The coordinate of the left edge of the window.
|
||||
* \param top The coordinate of the top edge of the window.
|
||||
* \param width The width the window.
|
||||
* \param height The height the window.
|
||||
* \param state The state the window is initially opened with.
|
||||
* \param type The type of drawing context installed in this window.
|
||||
* \param stereoVisual Stereo visual for quad buffered stereo.
|
||||
* \param numOfAASamples Number of samples used for AA (zero if no AA)
|
||||
* \param title The text shown in the title bar of the window.
|
||||
* \param left The coordinate of the left edge of the window.
|
||||
* \param top The coordinate of the top edge of the window.
|
||||
* \param width The width the window.
|
||||
* \param height The height the window.
|
||||
* \param state The state the window is initially opened with.
|
||||
* \param type The type of drawing context installed in this window.
|
||||
* \param wantStereoVisual Stereo visual for quad buffered stereo.
|
||||
* \param wantNumOfAASamples Number of samples used for AA (zero if no AA)
|
||||
* \param parentWindowHwnd
|
||||
*/
|
||||
GHOST_WindowWin32(
|
||||
GHOST_SystemWin32 *system,
|
||||
@@ -92,11 +93,9 @@ public:
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
GHOST_TEmbedderWindowID parentWindowHwnd = 0,
|
||||
GHOST_TSuccess msEnabled = GHOST_kFailure,
|
||||
int msPixelFormat = 0
|
||||
bool wantStereoVisual = false,
|
||||
GHOST_TUns16 wantNumOfAASamples = 0,
|
||||
GHOST_TEmbedderWindowID parentWindowHwnd = 0
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -105,13 +104,6 @@ public:
|
||||
*/
|
||||
virtual ~GHOST_WindowWin32();
|
||||
|
||||
/**
|
||||
* Returns the window to replace this one if it's getting replaced
|
||||
* \return The window replacing this one.
|
||||
*/
|
||||
|
||||
GHOST_Window *getNextWindow();
|
||||
|
||||
/**
|
||||
* Returns indication as to whether the window is valid.
|
||||
* \return The validity of the window.
|
||||
@@ -208,29 +200,6 @@ public:
|
||||
virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return An integer.
|
||||
*/
|
||||
virtual int getSwapInterval();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Invalidates the contents of this window.
|
||||
@@ -248,13 +217,6 @@ public:
|
||||
*/
|
||||
virtual GHOST_TSuccess endProgressBar();
|
||||
|
||||
/**
|
||||
* Returns the name of the window class.
|
||||
* \return The name of the window class.
|
||||
*/
|
||||
static const wchar_t *getWindowClassName() {
|
||||
return s_windowClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a mouse click event (should be called
|
||||
@@ -296,23 +258,15 @@ public:
|
||||
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
|
||||
|
||||
/** if the window currently resizing */
|
||||
bool m_inLiveResize;
|
||||
bool m_inLiveResize; // XXX jwilkins: ugh
|
||||
|
||||
protected:
|
||||
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param type The type of rendering context installed.
|
||||
* \param type The type of rendering context create.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess removeDrawingContext();
|
||||
virtual GHOST_Context* newDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Sets the cursor visibility on the window using
|
||||
@@ -360,12 +314,7 @@ protected:
|
||||
HWND m_hWnd;
|
||||
/** Device context handle. */
|
||||
HDC m_hDC;
|
||||
/** OpenGL rendering context. */
|
||||
HGLRC m_hGlRc;
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static HGLRC s_firsthGLRc;
|
||||
/** The first created device context handle. */
|
||||
static HDC s_firstHDC;
|
||||
|
||||
/** Flag for if window has captured the mouse */
|
||||
bool m_hasMouseCaptured;
|
||||
/** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
|
||||
@@ -393,26 +342,7 @@ protected:
|
||||
LONG m_maxPressure;
|
||||
LONG m_maxAzimuth, m_maxAltitude;
|
||||
|
||||
/** Preferred number of samples */
|
||||
GHOST_TUns16 m_multisample;
|
||||
|
||||
/** Check if multisample is supported */
|
||||
GHOST_TSuccess m_multisampleEnabled;
|
||||
|
||||
/** The pixelFormat to use for multisample */
|
||||
int m_msPixelFormat;
|
||||
|
||||
/** We need to following to recreate the window */
|
||||
const STR_String& m_title;
|
||||
GHOST_TInt32 m_left;
|
||||
GHOST_TInt32 m_top;
|
||||
GHOST_TUns32 m_width;
|
||||
GHOST_TUns32 m_height;
|
||||
GHOST_TWindowState m_normal_state;
|
||||
bool m_stereo;
|
||||
|
||||
/** The GHOST_System passes this to wm if this window is being replaced */
|
||||
GHOST_Window *m_nextWindow;
|
||||
|
||||
/** Hwnd to parent window */
|
||||
GHOST_TEmbedderWindowID m_parentWindowHwnd;
|
||||
|
@@ -30,8 +30,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <GL/glxew.h>
|
||||
|
||||
#include "GHOST_WindowX11.h"
|
||||
#include "GHOST_SystemX11.h"
|
||||
#include "STR_String.h"
|
||||
@@ -41,6 +39,14 @@
|
||||
#include "GHOST_DropTargetX11.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
#include "GHOST_ContextGLX.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
#include "GHOST_ContextEGL.h"
|
||||
#endif
|
||||
|
||||
/* For standard X11 cursors */
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xatom.h>
|
||||
@@ -65,14 +71,6 @@ typedef struct {
|
||||
long input_mode;
|
||||
} MotifWmHints;
|
||||
|
||||
// Workaround for MESA bug #54080
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=54080()
|
||||
#define SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
static bool g_swap_interval_disabled = false;
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
|
||||
|
||||
@@ -157,132 +155,53 @@ static long BLENDER_ICON_48x48x32[] = {
|
||||
};
|
||||
|
||||
|
||||
GLXContext GHOST_WindowX11::s_firstContext = NULL;
|
||||
|
||||
GHOST_WindowX11::
|
||||
GHOST_WindowX11(
|
||||
GHOST_SystemX11 *system,
|
||||
Display *display,
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
const GHOST_TEmbedderWindowID parentWindow,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const bool exclusive,
|
||||
const GHOST_TUns16 numOfAASamples)
|
||||
: GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples),
|
||||
m_context(NULL),
|
||||
m_display(display),
|
||||
m_normal_state(GHOST_kWindowStateNormal),
|
||||
m_system(system),
|
||||
m_valid_setup(false),
|
||||
m_invalid_window(false),
|
||||
m_empty_cursor(None),
|
||||
m_custom_cursor(None),
|
||||
m_visible_cursor(None)
|
||||
GHOST_SystemX11 *system,
|
||||
Display *display,
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
const GHOST_TEmbedderWindowID parentWindow,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual,
|
||||
const bool exclusive,
|
||||
const GHOST_TUns16 numOfAASamples
|
||||
) :
|
||||
GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
|
||||
m_display(display),
|
||||
m_normal_state(GHOST_kWindowStateNormal),
|
||||
m_system(system),
|
||||
m_valid_setup(false),
|
||||
m_invalid_window(false),
|
||||
m_empty_cursor(None),
|
||||
m_custom_cursor(None),
|
||||
m_visible_cursor(None)
|
||||
{
|
||||
|
||||
/* Set up the minimum attributes that we require and see if
|
||||
* X can find us a visual matching those requirements. */
|
||||
|
||||
int attributes[40], i, samples;
|
||||
int natom;
|
||||
int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
|
||||
|
||||
m_visual = NULL;
|
||||
|
||||
if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
|
||||
printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
|
||||
/* exit if this is the first window */
|
||||
if (s_firstContext == NULL) {
|
||||
printf("initial window could not find the GLX extension, exit!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the display with highest samples, starting at level requested */
|
||||
for (samples = m_numOfAASamples; samples >= 0; samples--) {
|
||||
i = 0; /* Reusing attributes array, so reset counter */
|
||||
|
||||
if (m_stereoVisual)
|
||||
attributes[i++] = GLX_STEREO;
|
||||
|
||||
attributes[i++] = GLX_RGBA;
|
||||
attributes[i++] = GLX_DOUBLEBUFFER;
|
||||
attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
|
||||
#ifdef GHOST_OPENGL_ALPHA
|
||||
attributes[i++] = GLX_ALPHA_SIZE; attributes[i++] = 1;
|
||||
#endif
|
||||
/* GLX >= 1.4 required for multi-sample */
|
||||
if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
|
||||
attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
|
||||
attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
|
||||
}
|
||||
attributes[i] = None;
|
||||
|
||||
m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
|
||||
|
||||
/* Any sample level or even zero, which means oversampling disabled, is good
|
||||
* but we need a valid visual to continue */
|
||||
if (m_visual == NULL) {
|
||||
if (samples == 0) {
|
||||
/* All options exhausted, cannot continue */
|
||||
printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
|
||||
|
||||
if (s_firstContext == NULL) {
|
||||
printf("initial window could not find the GLX extension, exit!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_numOfAASamples && (m_numOfAASamples > samples)) {
|
||||
printf("%s:%d: oversampling requested %i but using %i samples\n",
|
||||
__FILE__, __LINE__, m_numOfAASamples, samples);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a bunch of attributes needed to create an X window. */
|
||||
|
||||
|
||||
/* First create a colormap for the window and visual.
|
||||
* This seems pretty much a legacy feature as we are in rgba mode anyway. */
|
||||
unsigned int xattributes_valuemask = 0;
|
||||
|
||||
XSetWindowAttributes xattributes;
|
||||
unsigned int xattributes_valuemask = (CWBorderPixel | CWColormap | CWEventMask);
|
||||
memset(&xattributes, 0, sizeof(xattributes));
|
||||
|
||||
xattributes.colormap = XCreateColormap(m_display,
|
||||
RootWindow(m_display, m_visual->screen),
|
||||
m_visual->visual,
|
||||
AllocNone
|
||||
);
|
||||
|
||||
xattributes_valuemask |= CWBorderPixel;
|
||||
xattributes.border_pixel = 0;
|
||||
|
||||
/* Specify which events we are interested in hearing. */
|
||||
|
||||
xattributes_valuemask |= CWEventMask;
|
||||
xattributes.event_mask =
|
||||
ExposureMask | StructureNotifyMask |
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | FocusChangeMask |
|
||||
PropertyChangeMask | KeymapStateMask;
|
||||
ExposureMask | StructureNotifyMask |
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | FocusChangeMask |
|
||||
PropertyChangeMask | KeymapStateMask ;
|
||||
|
||||
if (exclusive) {
|
||||
xattributes_valuemask |= CWOverrideRedirect;
|
||||
@@ -292,21 +211,20 @@ GHOST_WindowX11(
|
||||
/* create the window! */
|
||||
if (parentWindow == 0) {
|
||||
m_window = XCreateWindow(m_display,
|
||||
RootWindow(m_display, m_visual->screen),
|
||||
RootWindow(m_display, DefaultScreen(m_display)),
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
0, /* no border. */
|
||||
m_visual->depth,
|
||||
0, /* no border. */
|
||||
CopyFromParent,
|
||||
InputOutput,
|
||||
m_visual->visual,
|
||||
CopyFromParent,
|
||||
xattributes_valuemask,
|
||||
&xattributes
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
Window root_return;
|
||||
int x_return, y_return;
|
||||
unsigned int w_return, h_return, border_w_return, depth_return;
|
||||
@@ -314,28 +232,26 @@ GHOST_WindowX11(
|
||||
XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
|
||||
&w_return, &h_return, &border_w_return, &depth_return);
|
||||
|
||||
left = 0;
|
||||
top = 0;
|
||||
width = w_return;
|
||||
left = 0;
|
||||
top = 0;
|
||||
width = w_return;
|
||||
height = h_return;
|
||||
|
||||
|
||||
m_window = XCreateWindow(m_display,
|
||||
parentWindow, /* reparent against embedder */
|
||||
parentWindow, /* reparent against embedder */
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
0, /* no border. */
|
||||
m_visual->depth,
|
||||
0, /* no border. */
|
||||
CopyFromParent,
|
||||
InputOutput,
|
||||
m_visual->visual,
|
||||
CopyFromParent,
|
||||
xattributes_valuemask,
|
||||
&xattributes
|
||||
);
|
||||
|
||||
XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
|
||||
|
||||
}
|
||||
|
||||
#ifdef WITH_XDND
|
||||
@@ -460,7 +376,7 @@ GHOST_WindowX11(
|
||||
#endif
|
||||
|
||||
/* now set up the rendering context. */
|
||||
if (installDrawingContext(type) == GHOST_kSuccess) {
|
||||
if (setDrawingContextType(type) == GHOST_kSuccess) {
|
||||
m_valid_setup = true;
|
||||
GHOST_PRINT("Created window\n");
|
||||
}
|
||||
@@ -685,7 +601,7 @@ screenToClient(
|
||||
Window temp;
|
||||
|
||||
XTranslateCoordinates(m_display,
|
||||
RootWindow(m_display, m_visual->screen),
|
||||
RootWindow(m_display, DefaultScreen(m_display)),
|
||||
m_window,
|
||||
inX, inY,
|
||||
&ax, &ay,
|
||||
@@ -708,7 +624,7 @@ clientToScreen(
|
||||
XTranslateCoordinates(
|
||||
m_display,
|
||||
m_window,
|
||||
RootWindow(m_display, m_visual->screen),
|
||||
RootWindow(m_display, DefaultScreen(m_display)),
|
||||
inX, inY,
|
||||
&ax, &ay,
|
||||
&temp);
|
||||
@@ -1052,7 +968,7 @@ setOrder(
|
||||
xev.xclient.data.l[3] = 0;
|
||||
xev.xclient.data.l[4] = 0;
|
||||
|
||||
root = RootWindow(m_display, m_visual->screen),
|
||||
root = RootWindow(m_display, DefaultScreen(m_display)),
|
||||
eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
|
||||
|
||||
XSendEvent(m_display, root, False, eventmask, &xev);
|
||||
@@ -1077,34 +993,6 @@ setOrder(
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
swapBuffers()
|
||||
{
|
||||
if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
|
||||
glXSwapBuffers(m_display, m_window);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
activateDrawingContext()
|
||||
{
|
||||
if (m_context != NULL) {
|
||||
glXMakeCurrent(m_display, m_window, m_context);
|
||||
/* Disable AA by default */
|
||||
if (m_numOfAASamples > 0) {
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
invalidate()
|
||||
@@ -1172,10 +1060,6 @@ GHOST_WindowX11::
|
||||
XFreeCursor(m_display, m_custom_cursor);
|
||||
}
|
||||
|
||||
if (m_context != s_firstContext) {
|
||||
glXDestroyContext(m_display, m_context);
|
||||
}
|
||||
|
||||
if (p_owner == m_window) {
|
||||
XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
|
||||
}
|
||||
@@ -1193,91 +1077,105 @@ GHOST_WindowX11::
|
||||
delete m_dropTarget;
|
||||
#endif
|
||||
|
||||
releaseNativeHandles();
|
||||
|
||||
XDestroyWindow(m_display, m_window);
|
||||
XFree(m_visual);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param type The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
installDrawingContext(
|
||||
GHOST_TDrawingContextType type)
|
||||
GHOST_Context* GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
/* only support openGL for now. */
|
||||
GHOST_TSuccess success;
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
{
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* use our own event handlers to avoid exiting blender,
|
||||
* this would happen for eg:
|
||||
* if you open blender, unplug a tablet, then open a new window. */
|
||||
XErrorHandler old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
|
||||
XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if defined(WITH_GL_CONTEXT_DESKTOP)
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
GLX_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
|
||||
if (m_context != NULL) {
|
||||
if (!s_firstContext) {
|
||||
s_firstContext = m_context;
|
||||
}
|
||||
glXMakeCurrent(m_display, m_window, m_context);
|
||||
glClearColor(0.447, 0.447, 0.447, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
#elif defined(WITH_GL_CONTEXT_EMBEDDED)
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* Restore handler */
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
(void) XSetIOErrorHandler(old_handler_io);
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context* context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
{
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
success = GHOST_kFailure;
|
||||
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
return success;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* \return Indication as to whether removal has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
removeDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
|
||||
if (m_context != NULL) {
|
||||
glXDestroyContext(m_display, m_context);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
Cursor
|
||||
GHOST_WindowX11::
|
||||
getStandardCursor(
|
||||
@@ -1530,72 +1428,3 @@ endFullScreen() const
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
setSwapInterval(int interval) {
|
||||
if (!GLX_EXT_swap_control || !glXSwapIntervalEXT
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
|| g_swap_interval_disabled
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
glXSwapIntervalEXT(m_display, m_window, interval);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
static int QueryDrawable_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
|
||||
{
|
||||
fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
|
||||
theEvent->error_code, theEvent->request_code);
|
||||
if (!g_swap_interval_disabled) {
|
||||
fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
|
||||
g_swap_interval_disabled = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int QueryDrawable_ApplicationIOErrorHandler(Display *display)
|
||||
{
|
||||
fprintf(stderr, "Ignoring Xlib error: error IO\n");
|
||||
if (!g_swap_interval_disabled) {
|
||||
fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
|
||||
g_swap_interval_disabled = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
int
|
||||
GHOST_WindowX11::
|
||||
getSwapInterval() {
|
||||
if (GLX_EXT_swap_control) {
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
/* XXX: Current MESA driver will give GLXBadDrawable for all
|
||||
* the glXQueryDrawable requests with direct contexts.
|
||||
*
|
||||
* To prevent crashes and unexpected behaviors, we will
|
||||
* disable swap intervals extension if query fails here.
|
||||
* (because if we will override interval without having
|
||||
* old value we couldn't restore it properly).
|
||||
*/
|
||||
XErrorHandler old_handler = XSetErrorHandler(QueryDrawable_ApplicationErrorHandler);
|
||||
XIOErrorHandler old_handler_io = XSetIOErrorHandler(QueryDrawable_ApplicationIOErrorHandler);
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
unsigned int value = 0;
|
||||
glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &value);
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
/* Restore handler */
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
(void) XSetIOErrorHandler(old_handler_io);
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "GHOST_Window.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
// For tablets
|
||||
#ifdef WITH_X11_XINPUT
|
||||
# include <X11/extensions/XInput.h>
|
||||
@@ -160,13 +159,6 @@ public:
|
||||
);
|
||||
|
||||
GHOST_TSuccess
|
||||
swapBuffers(
|
||||
);
|
||||
|
||||
GHOST_TSuccess
|
||||
activateDrawingContext(
|
||||
);
|
||||
GHOST_TSuccess
|
||||
invalidate(
|
||||
);
|
||||
|
||||
@@ -235,37 +227,12 @@ public:
|
||||
|
||||
GHOST_TSuccess endFullScreen() const;
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess setSwapInterval(int interval);
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \return An integer.
|
||||
*/
|
||||
virtual int getSwapInterval();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param type The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
* \param type The type of rendering context create.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess
|
||||
installDrawingContext(
|
||||
GHOST_TDrawingContextType type
|
||||
);
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* \return Indication as to whether removal has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess
|
||||
removeDrawingContext(
|
||||
);
|
||||
virtual GHOST_Context* newDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Sets the cursor visibility on the window using
|
||||
@@ -350,17 +317,11 @@ private:
|
||||
void initXInputDevices();
|
||||
#endif
|
||||
|
||||
GLXContext m_context;
|
||||
Window m_window;
|
||||
Display *m_display;
|
||||
XVisualInfo *m_visual;
|
||||
Window m_window;
|
||||
Display *m_display;
|
||||
GHOST_TWindowState m_normal_state;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static GLXContext s_firstContext;
|
||||
|
||||
/// A pointer to the typed system class.
|
||||
|
||||
/**A pointer to the typed system class. */
|
||||
GHOST_SystemX11 *m_system;
|
||||
|
||||
bool m_valid_setup;
|
||||
|
39
intern/glew-mx/CMakeLists.txt
Normal file
39
intern/glew-mx/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2014, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jason Wilkins
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
glew-mx.h
|
||||
|
||||
intern/glew-mx.c
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_intern_glew_mx "${SRC}" "${INC}" "${INC_SYS}")
|
68
intern/glew-mx/glew-mx.h
Normal file
68
intern/glew-mx/glew-mx.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file glew-mx.h
|
||||
* \ingroup glew-mx
|
||||
* GLEW Context Management
|
||||
*/
|
||||
|
||||
#ifndef GLEW_MX_H__
|
||||
#define GLEW_MX_H__
|
||||
|
||||
#if GLEW_MX
|
||||
#define glewGetContext() _glewContext
|
||||
#endif
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#if GLEW_MX
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern GLEWContext* _glewContext;
|
||||
|
||||
void glewSetContext(GLEWContext* ctx);
|
||||
GLEWContext* glewCreateContext(void);
|
||||
void glewDestroyContext(GLEWContext* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h> // for NULL
|
||||
|
||||
#define glewSetContext(ctx)
|
||||
#define glewCreateContext() NULL
|
||||
#define glewDestroyContext(ctx)
|
||||
|
||||
#endif // GLEW_MX
|
||||
|
||||
#endif
|
64
intern/glew-mx/intern/glew-mx.c
Normal file
64
intern/glew-mx/intern/glew-mx.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Jason Wilkins
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file glew-mx.c
|
||||
* \ingroup glew-mx
|
||||
* GLEW Context Management
|
||||
*/
|
||||
|
||||
#if GLEW_MX
|
||||
#include "glew-mx.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
GLEWContext* _glewContext = NULL;
|
||||
|
||||
void glewSetContext(GLEWContext* ctx)
|
||||
{
|
||||
_glewContext = ctx;
|
||||
}
|
||||
|
||||
GLEWContext* glewCreateContext()
|
||||
{
|
||||
GLEWContext* rv = malloc(sizeof(GLEWContext));
|
||||
|
||||
if (rv != NULL)
|
||||
memset(rv, 0, sizeof(GLEWContext));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void glewDestroyContext(GLEWContext* ctx)
|
||||
{
|
||||
if (_glewContext == ctx)
|
||||
_glewContext = NULL;
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
#endif
|
@@ -66,6 +66,14 @@
|
||||
#include "../../source/blender/blenlib/BLI_sys_types.h"
|
||||
#include "../../source/blender/blenlib/BLI_compiler_attrs.h"
|
||||
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__func__)
|
||||
# define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@@ -36,6 +36,12 @@ set(SRC
|
||||
boost_locale_wrapper.h
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SRC
|
||||
osx_user_locale.mm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_HEADLESS)
|
||||
add_definitions(-DWITH_HEADLESS)
|
||||
endif()
|
||||
|
@@ -65,8 +65,7 @@ void bl_locale_set(const char *locale)
|
||||
}
|
||||
else {
|
||||
#if defined(__APPLE__) && !defined(WITH_HEADLESS) && !defined(WITH_GHOST_SDL)
|
||||
extern char GHOST_user_locale[128]; // pulled from Ghost_SystemCocoa
|
||||
std::string locale_osx = GHOST_user_locale + std::string(".UTF-8");
|
||||
std::string locale_osx = osx_user_locale() + std::string(".UTF-8");
|
||||
_locale = gen(locale_osx.c_str());
|
||||
#else
|
||||
_locale = gen("");
|
||||
|
@@ -42,7 +42,11 @@ void bl_locale_init(const char *messages_path, const char *default_domain);
|
||||
void bl_locale_set(const char *locale);
|
||||
const char *bl_locale_get(void);
|
||||
const char *bl_locale_pgettext(const char *msgctxt, const char *msgid);
|
||||
|
||||
|
||||
#if defined(__APPLE__) && !defined(WITH_HEADLESS) && !defined(WITH_GHOST_SDL)
|
||||
const char* osx_user_locale(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
22
intern/locale/osx_user_locale.mm
Normal file
22
intern/locale/osx_user_locale.mm
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "boost_locale_wrapper.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
static char* user_locale = NULL;
|
||||
|
||||
// get current locale
|
||||
const char* osx_user_locale()
|
||||
{
|
||||
::free(user_locale);
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
|
||||
NSLocale * myNSLocale = (NSLocale *) myCFLocale;
|
||||
[myNSLocale autorelease];
|
||||
NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
||||
user_locale = ::strdup([nsIdentifier UTF8String]);
|
||||
[pool drain];
|
||||
|
||||
return user_locale;
|
||||
}
|
@@ -25,6 +25,7 @@
|
||||
|
||||
set(INC
|
||||
.
|
||||
../glew-mx
|
||||
../guardedalloc
|
||||
../../source/blender/blenlib
|
||||
)
|
||||
@@ -44,9 +45,10 @@ set(SRC
|
||||
if(WITH_OPENCOLORIO)
|
||||
add_definitions(
|
||||
-DWITH_OCIO
|
||||
-DGLEW_STATIC
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${OPENCOLORIO_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
|
@@ -29,13 +29,6 @@
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
|
||||
using namespace OCIO_NAMESPACE;
|
||||
|
@@ -37,7 +37,7 @@
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include "glew-mx.h"
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
|
||||
|
@@ -26,11 +26,13 @@ set(INC
|
||||
../blenkernel
|
||||
../blenlib
|
||||
../editors/include
|
||||
../gpu
|
||||
../makesdna
|
||||
../makesrna
|
||||
../python
|
||||
../imbuf
|
||||
../../../intern/guardedalloc
|
||||
../../../intern/glew-mx
|
||||
../../../intern/locale
|
||||
)
|
||||
|
||||
@@ -58,7 +60,7 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_blenfont "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
||||
|
@@ -514,7 +514,6 @@ static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param)
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* Save the current matrix mode. */
|
||||
glGetIntegerv(GL_MATRIX_MODE, mode);
|
||||
|
@@ -38,6 +38,7 @@ set(INC
|
||||
../nodes
|
||||
../render/extern/include
|
||||
../../../intern/guardedalloc
|
||||
../../../intern/glew-mx
|
||||
../../../intern/iksolver/extern
|
||||
../../../intern/memutil
|
||||
../../../intern/mikktspace
|
||||
@@ -272,7 +273,7 @@ set(SRC
|
||||
intern/pbvh_intern.h
|
||||
)
|
||||
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_AUDASPACE)
|
||||
list(APPEND INC
|
||||
|
@@ -72,11 +72,10 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
|
||||
|
||||
#include "BLI_sys_types.h" /* for intptr_t support */
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "GPU_buffers.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_glew.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
/* very slow! enable for testing only! */
|
||||
|
@@ -34,8 +34,6 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_edgehash.h"
|
||||
@@ -62,6 +60,7 @@
|
||||
#include "GPU_buffers.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_glew.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@@ -41,8 +41,6 @@
|
||||
* is likely to be a little slow.
|
||||
*/
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_jitter.h"
|
||||
#include "BLI_bitmap.h"
|
||||
@@ -58,6 +56,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_glew.h"
|
||||
|
||||
extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
|
||||
|
||||
|
@@ -1644,7 +1644,7 @@ void BKE_pbvh_raycast_project_ray_root (PBVH *bvh, bool original, float ray_star
|
||||
}
|
||||
|
||||
|
||||
//#include <GL/glew.h>
|
||||
//#include "GPU_glew.h"
|
||||
|
||||
typedef struct {
|
||||
DMSetMaterial setMaterial;
|
||||
|
@@ -33,8 +33,6 @@
|
||||
|
||||
/* Part of the code copied from elbeem fluid library, copyright by Nils Thuerey */
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include <float.h>
|
||||
@@ -84,6 +82,8 @@
|
||||
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
#include "GPU_glew.h"
|
||||
|
||||
/* UNUSED so far, may be enabled later */
|
||||
/* #define USE_SMOKE_COLLISION_DM */
|
||||
|
||||
|
@@ -72,10 +72,9 @@
|
||||
# include "BLI_array.h"
|
||||
#endif
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_glew.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "CCGSubSurf.h"
|
||||
|
@@ -72,6 +72,16 @@ void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]);
|
||||
void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
|
||||
void mul_m3_m3m4(float R[3][3], float A[4][4], float B[3][3]);
|
||||
|
||||
|
||||
void mul_m4_m4m4_q(float m1[4][4], float m3[4][4], float m2[4][4]);
|
||||
void mul_m4_m3m4_q(float m1[4][4], float m3[4][4], float m2[3][3]);
|
||||
|
||||
void mul_serie_m3(float R[3][3],
|
||||
float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
|
||||
float M5[3][3], float M6[3][3], float M7[3][3], float M8[3][3]);
|
||||
void mul_serie_m4(float R[4][4],
|
||||
float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
|
||||
float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]);
|
||||
/* mul_m3_series */
|
||||
void _va_mul_m3_series_3(float R[3][3], float M1[3][3], float M2[3][3]) ATTR_NONNULL();
|
||||
void _va_mul_m3_series_4(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3]) ATTR_NONNULL();
|
||||
@@ -105,6 +115,8 @@ void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
|
||||
void mul_v2_m4v3(float r[2], float M[4][4], const float v[3]);
|
||||
void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
|
||||
void mul_m2v2(float M[2][2], float v[2]);
|
||||
void mul_v4_m4v3(float r[4], float M[4][4], const float v[3]);
|
||||
void mul_v3_m4v3_q(float r[3], float M[4][4], const float v[3]);
|
||||
void mul_mat3_m4_v3(float M[4][4], float r[3]);
|
||||
void mul_m4_v4(float M[4][4], float r[4]);
|
||||
void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
|
||||
@@ -190,6 +202,8 @@ void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
|
||||
void scale_m3_fl(float R[3][3], float scale);
|
||||
void scale_m4_fl(float R[4][4], float scale);
|
||||
|
||||
void scale_m4(float m[][4], float x, float y, float z);
|
||||
|
||||
float mat3_to_scale(float M[3][3]);
|
||||
float mat4_to_scale(float M[4][4]);
|
||||
|
||||
@@ -201,6 +215,7 @@ void mat4_to_size(float r[3], float M[4][4]);
|
||||
|
||||
void translate_m4(float mat[4][4], float tx, float ty, float tz);
|
||||
void rotate_m4(float mat[4][4], const char axis, const float angle);
|
||||
void rotate_m4_right(float mat[4][4], const char axis);
|
||||
void rotate_m2(float mat[2][2], const float angle);
|
||||
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
|
||||
|
||||
@@ -227,6 +242,13 @@ bool is_negative_m4(float mat[4][4]);
|
||||
bool is_zero_m3(float mat[3][3]);
|
||||
bool is_zero_m4(float mat[4][4]);
|
||||
|
||||
/******************************** Projections ********************************/
|
||||
|
||||
void mat4_ortho_set(float m[4][4], float left, float right, float bottom, float top, float nearVal, float farVal);
|
||||
void mat4_frustum_set(float m[4][4], float left, float right, float bottom, float top, float nearVal, float farVal);
|
||||
|
||||
void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3]);
|
||||
|
||||
/* SpaceTransform helper */
|
||||
typedef struct SpaceTransform {
|
||||
float local2target[4][4];
|
||||
@@ -243,6 +265,7 @@ void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float
|
||||
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
|
||||
BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
|
||||
|
||||
|
||||
/*********************************** Other ***********************************/
|
||||
|
||||
void print_m3(const char *str, float M[3][3]);
|
||||
|
@@ -266,7 +266,7 @@ void project_v3_plane(float v[3], const float n[3], const float p[3]);
|
||||
void reflect_v3_v3v3(float r[3], const float v[3], const float n[3]);
|
||||
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
|
||||
void ortho_v3_v3(float p[3], const float v[3]);
|
||||
void ortho_v2_v2(float p[2], const float v[2]);
|
||||
void ortho_v2_v2(float p[3], const float v[3]);
|
||||
void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
|
||||
void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
|
||||
void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
|
||||
|
@@ -297,15 +297,37 @@
|
||||
(v1)[2] = FTOCHAR((v2[2])); \
|
||||
(v1)[3] = FTOCHAR((v2[3])); \
|
||||
} (void)0
|
||||
#define VECCOPY(v1, v2) { \
|
||||
*(v1) = *(v2); \
|
||||
*(v1 + 1) = *(v2 + 1); \
|
||||
*(v1 + 2) = *(v2 + 2); \
|
||||
#define VEC2D(v1, x, y) { \
|
||||
*((v1) + 0) = x; \
|
||||
*((v1) + 1) = y; \
|
||||
} (void)0
|
||||
#define VEC3D(v1, x, y, z) { \
|
||||
*((v1) + 0) = x; \
|
||||
*((v1) + 1) = y; \
|
||||
*((v1) + 2) = z; \
|
||||
} (void)0
|
||||
#define VEC4D(v1, x, y, z, w) { \
|
||||
*((v1) + 0) = x; \
|
||||
*((v1) + 1) = y; \
|
||||
*((v1) + 2) = z; \
|
||||
*((v1) + 3) = w; \
|
||||
} (void)0
|
||||
#define VECCOPY2D(v1, v2) { \
|
||||
*(v1) = *(v2); \
|
||||
*(v1 + 1) = *(v2 + 1); \
|
||||
} (void)0
|
||||
#define VECCOPY3D(v1, v2) { \
|
||||
*(v1) = *(v2); \
|
||||
*(v1 + 1) = *(v2 + 1); \
|
||||
*(v1 + 2) = *(v2 + 2); \
|
||||
} (void)0
|
||||
#define VECCOPY(v1, v2) VECCOPY3D(v1, v2)
|
||||
#define VECCOPY4D(v1, v2) { \
|
||||
*(v1 + 0) = *(v2 + 0); \
|
||||
*(v1 + 1) = *(v2 + 1); \
|
||||
*(v1 + 2) = *(v2 + 2); \
|
||||
*(v1 + 3) = *(v2 + 3); \
|
||||
} (void)0
|
||||
#define VECADD(v1, v2, v3) { \
|
||||
*(v1) = *(v2) + *(v3); \
|
||||
*(v1 + 1) = *(v2 + 1) + *(v3 + 1); \
|
||||
|
@@ -186,26 +186,7 @@ void mul_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4])
|
||||
copy_m4_m4(m3, m3_);
|
||||
|
||||
/* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
|
||||
m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0] + m2[0][3] * m3[3][0];
|
||||
m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1] + m2[0][3] * m3[3][1];
|
||||
m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2] + m2[0][3] * m3[3][2];
|
||||
m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3] + m2[0][3] * m3[3][3];
|
||||
|
||||
m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0] + m2[1][3] * m3[3][0];
|
||||
m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1] + m2[1][3] * m3[3][1];
|
||||
m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2] + m2[1][3] * m3[3][2];
|
||||
m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3] + m2[1][3] * m3[3][3];
|
||||
|
||||
m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0] + m2[2][3] * m3[3][0];
|
||||
m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1] + m2[2][3] * m3[3][1];
|
||||
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2] + m2[2][3] * m3[3][2];
|
||||
m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3] + m2[2][3] * m3[3][3];
|
||||
|
||||
m1[3][0] = m2[3][0] * m3[0][0] + m2[3][1] * m3[1][0] + m2[3][2] * m3[2][0] + m2[3][3] * m3[3][0];
|
||||
m1[3][1] = m2[3][0] * m3[0][1] + m2[3][1] * m3[1][1] + m2[3][2] * m3[2][1] + m2[3][3] * m3[3][1];
|
||||
m1[3][2] = m2[3][0] * m3[0][2] + m2[3][1] * m3[1][2] + m2[3][2] * m3[2][2] + m2[3][3] * m3[3][2];
|
||||
m1[3][3] = m2[3][0] * m3[0][3] + m2[3][1] * m3[1][3] + m2[3][2] * m3[2][3] + m2[3][3] * m3[3][3];
|
||||
|
||||
mul_m4_m4m4_q(m1, m3, m2);
|
||||
}
|
||||
|
||||
void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3])
|
||||
@@ -291,6 +272,88 @@ void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4])
|
||||
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
|
||||
}
|
||||
|
||||
void mul_m4_m4m4_q(float m1[4][4], float m3[4][4], float m2[4][4])
|
||||
{
|
||||
/* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
|
||||
m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0] + m2[0][3] * m3[3][0];
|
||||
m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1] + m2[0][3] * m3[3][1];
|
||||
m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2] + m2[0][3] * m3[3][2];
|
||||
m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3] + m2[0][3] * m3[3][3];
|
||||
|
||||
m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0] + m2[1][3] * m3[3][0];
|
||||
m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1] + m2[1][3] * m3[3][1];
|
||||
m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2] + m2[1][3] * m3[3][2];
|
||||
m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3] + m2[1][3] * m3[3][3];
|
||||
|
||||
m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0] + m2[2][3] * m3[3][0];
|
||||
m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1] + m2[2][3] * m3[3][1];
|
||||
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2] + m2[2][3] * m3[3][2];
|
||||
m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3] + m2[2][3] * m3[3][3];
|
||||
|
||||
m1[3][0] = m2[3][0] * m3[0][0] + m2[3][1] * m3[1][0] + m2[3][2] * m3[2][0] + m2[3][3] * m3[3][0];
|
||||
m1[3][1] = m2[3][0] * m3[0][1] + m2[3][1] * m3[1][1] + m2[3][2] * m3[2][1] + m2[3][3] * m3[3][1];
|
||||
m1[3][2] = m2[3][0] * m3[0][2] + m2[3][1] * m3[1][2] + m2[3][2] * m3[2][2] + m2[3][3] * m3[3][2];
|
||||
m1[3][3] = m2[3][0] * m3[0][3] + m2[3][1] * m3[1][3] + m2[3][2] * m3[2][3] + m2[3][3] * m3[3][3];
|
||||
}
|
||||
|
||||
void mul_m4_m3m4_q(float m1[4][4], float m3[4][4], float m2[3][3])
|
||||
{
|
||||
/* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
|
||||
m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
|
||||
m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
|
||||
m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
|
||||
m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3];
|
||||
|
||||
m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
|
||||
m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
|
||||
m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
|
||||
m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3];
|
||||
|
||||
m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
|
||||
m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
|
||||
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
|
||||
m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3];
|
||||
|
||||
m1[3][0] = m3[3][0];
|
||||
m1[3][1] = m3[3][1];
|
||||
m1[3][2] = m3[3][2];
|
||||
m1[3][3] = m3[3][3];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mul_serie_m3(float answ[3][3],
|
||||
float m1[3][3], float m2[3][3], float m3[3][3],
|
||||
float m4[3][3], float m5[3][3], float m6[3][3],
|
||||
float m7[3][3], float m8[3][3])
|
||||
{
|
||||
float temp[3][3];
|
||||
|
||||
if (m1 == NULL || m2 == NULL) return;
|
||||
|
||||
mul_m3_m3m3(answ, m2, m1);
|
||||
if (m3) {
|
||||
mul_m3_m3m3(temp, m3, answ);
|
||||
if (m4) {
|
||||
mul_m3_m3m3(answ, m4, temp);
|
||||
if (m5) {
|
||||
mul_m3_m3m3(temp, m5, answ);
|
||||
if (m6) {
|
||||
mul_m3_m3m3(answ, m6, temp);
|
||||
if (m7) {
|
||||
mul_m3_m3m3(temp, m7, answ);
|
||||
if (m8) {
|
||||
mul_m3_m3m3(answ, m8, temp);
|
||||
}
|
||||
else copy_m3_m3(answ, temp);
|
||||
}
|
||||
}
|
||||
else copy_m3_m3(answ, temp);
|
||||
}
|
||||
}
|
||||
else copy_m3_m3(answ, temp);
|
||||
}
|
||||
}
|
||||
|
||||
/** \name Macro helpers for: mul_m3_series
|
||||
* \{ */
|
||||
@@ -493,6 +556,22 @@ void mul_m2v2(float mat[2][2], float vec[2])
|
||||
mul_v2_m2v2(vec, mat, vec);
|
||||
}
|
||||
|
||||
void mul_v4_m4v3(float out[4], float mat[][4], const float vec[3])
|
||||
{
|
||||
out[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
|
||||
out[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
|
||||
out[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
|
||||
out[3] = vec[0] * mat[0][3] + vec[1] * mat[1][3] + mat[2][3] * vec[2] + mat[3][3];
|
||||
}
|
||||
|
||||
void mul_v3_m4v3_q(float out[3], float mat[][4], const float vec[3])
|
||||
{
|
||||
out[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
|
||||
out[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
|
||||
out[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
|
||||
|
||||
}
|
||||
|
||||
/* same as mul_m4_v3() but doesnt apply translation component */
|
||||
void mul_mat3_m4_v3(float mat[4][4], float vec[3])
|
||||
{
|
||||
@@ -1478,11 +1557,19 @@ void scale_m4_fl(float m[4][4], float scale)
|
||||
m[3][0] = m[3][1] = m[3][2] = 0.0;
|
||||
}
|
||||
|
||||
void scale_m4(float m[][4], float x, float y, float z)
|
||||
{
|
||||
m[0][0]*=x; m[0][1]*=x; m[0][2]*=x; m[0][3]*=x;
|
||||
m[1][0]*=y; m[1][1]*=y; m[1][2]*=y; m[1][3]*=y;
|
||||
m[2][0]*=z; m[2][1]*=z; m[2][2]*=z; m[2][3]*=z;
|
||||
}
|
||||
|
||||
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
|
||||
{
|
||||
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
|
||||
mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
|
||||
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
|
||||
mat[3][3] += (Tx * mat[0][3] + Ty * mat[1][3] + Tz * mat[2][3]);
|
||||
}
|
||||
|
||||
void rotate_m4(float mat[4][4], const char axis, const float angle)
|
||||
@@ -1554,6 +1641,60 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
|
||||
mul_m4_m4m4(mat, mat, tmat);
|
||||
}
|
||||
|
||||
void rotate_m4_right(float mat[][4], const char axis)
|
||||
{
|
||||
#define COORD(x,y) (4*x + y)
|
||||
const static char mrotx[] = {1, 2};
|
||||
const static char mrotxn[] = {2, 1};
|
||||
|
||||
const static char mroty[] = {2, 0};
|
||||
const static char mrotyn[] = {0, 2};
|
||||
|
||||
const static char mrotz[] = {0, 1};
|
||||
const static char mrotzn[] = {1, 0};
|
||||
|
||||
#undef COORD
|
||||
|
||||
const char * rotmat;
|
||||
float tmpf;
|
||||
int i;
|
||||
|
||||
|
||||
switch(axis)
|
||||
{
|
||||
case 'X':
|
||||
rotmat = mrotx;
|
||||
break;
|
||||
case (char)-'X':
|
||||
rotmat = mrotxn;
|
||||
break;
|
||||
case 'Y':
|
||||
rotmat = mroty;
|
||||
break;
|
||||
case (char)-'Y':
|
||||
rotmat = mrotyn;
|
||||
break;
|
||||
case 'Z':
|
||||
rotmat = mrotz;
|
||||
break;
|
||||
case (char)-'Z':
|
||||
rotmat = mrotzn;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
|
||||
}
|
||||
|
||||
for(i=0; i<3; i++)
|
||||
{
|
||||
tmpf = mat[rotmat[1]][i];
|
||||
mat[rotmat[1]][i] = -1.0f*mat[rotmat[0]][i];
|
||||
mat[rotmat[0]][i] = tmpf;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
|
||||
{
|
||||
float srot[3][3], drot[3][3];
|
||||
@@ -2194,6 +2335,41 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
|
||||
mul_m4_series(Ainv, U, Wm, V);
|
||||
}
|
||||
|
||||
void mat4_ortho_set(float m[][4], float left, float right, float bottom, float top, float nearVal, float farVal)
|
||||
{
|
||||
m[0][0] = 2/(right-left); m[1][0] = 0; m[2][0] = 0; m[3][0] = -(right+left)/(right-left);
|
||||
m[0][1] = 0; m[1][1] = 2/(top-bottom); m[2][1] = 0; m[3][1] = -(top+bottom)/(top-bottom);
|
||||
m[0][2] = 0; m[1][2] = 0; m[2][2] = -2/(farVal-nearVal); m[3][2] = -(farVal+nearVal)/(farVal-nearVal);
|
||||
m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
|
||||
}
|
||||
|
||||
void mat4_frustum_set(float m[][4], float left, float right, float bottom, float top, float nearVal, float farVal)
|
||||
{
|
||||
m[0][0] = 2*nearVal/(right-left); m[1][0] = 0; m[2][0] = (right+left)/(right-left); m[3][0] = 0;
|
||||
m[0][1] = 0; m[1][1] = 2*nearVal/(top-bottom); m[2][1] = (top+bottom)/(top-bottom); m[3][1] = 0;
|
||||
m[0][2] = 0; m[1][2] = 0; m[2][2] = -(farVal+nearVal)/(farVal-nearVal); m[3][2] = -2*farVal*nearVal/(farVal-nearVal);
|
||||
m[0][3] = 0; m[1][3] = 0; m[2][3] = -1; m[3][3] = 0;
|
||||
}
|
||||
|
||||
/* Loosly based on Mesa implementation of gluLookAt */
|
||||
void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3])
|
||||
{
|
||||
float side[3];
|
||||
|
||||
normalize_v3(lookdir);
|
||||
|
||||
cross_v3_v3v3(side, lookdir, camup);
|
||||
|
||||
normalize_v3(side);
|
||||
|
||||
cross_v3_v3v3(camup, side, lookdir);
|
||||
|
||||
m[0][0] = side [0]; m[1][0] = side [1]; m[2][0] = side [2]; m[3][0] = 0;
|
||||
m[0][1] = camup [0]; m[1][1] = camup [1]; m[2][1] = camup [2]; m[3][1] = 0;
|
||||
m[0][2] = -lookdir[0]; m[1][2] = -lookdir[1]; m[2][2] = -lookdir[2]; m[3][2] = 0;
|
||||
m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
|
||||
}
|
||||
|
||||
void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
|
||||
{
|
||||
/* try regular inverse when possible, otherwise fall back to slow svd */
|
||||
|
@@ -669,7 +669,7 @@ void ortho_v3_v3(float p[3], const float v[3])
|
||||
/**
|
||||
* no brainer compared to v3, just have for consistency.
|
||||
*/
|
||||
void ortho_v2_v2(float p[2], const float v[2])
|
||||
void ortho_v2_v2(float p[3], const float v[3])
|
||||
{
|
||||
BLI_assert(p != v);
|
||||
|
||||
|
@@ -97,6 +97,19 @@ MINLINE void copy_v4_fl(float r[4], float f)
|
||||
r[3] = f;
|
||||
}
|
||||
|
||||
MINLINE void copy_v2_flfl(float r[2], float f0, float f1)
|
||||
{
|
||||
r[0] = f0;
|
||||
r[1] = f1;
|
||||
}
|
||||
|
||||
MINLINE void copy_v3_flflfl(float r[3], float f0, float f1, float f2)
|
||||
{
|
||||
r[0] = f0;
|
||||
r[1] = f1;
|
||||
r[2] = f2;
|
||||
}
|
||||
|
||||
/* short */
|
||||
MINLINE void copy_v2_v2_char(char r[2], const char a[2])
|
||||
{
|
||||
|
@@ -23,10 +23,12 @@ set(INC
|
||||
../../blenfont
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -57,4 +59,6 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_animation "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -3382,7 +3382,6 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
|
||||
selected = 0;
|
||||
|
||||
/* set blending again, as may not be set in previous step */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
/* step 1) draw backdrop ........................................... */
|
||||
|
@@ -140,7 +140,6 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
|
||||
|
||||
/* only draw this if preview range is set */
|
||||
if (PRVRANGEON) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
|
||||
|
||||
|
@@ -330,7 +330,6 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
|
||||
glScalef(1.0f / xscale, 1.0f, 1.0f);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* vertical line - dotted */
|
||||
#ifdef DURIAN_CAMERA_SWITCH
|
||||
|
@@ -28,6 +28,7 @@ set(INC
|
||||
../../windowmanager
|
||||
../../gpu
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -74,4 +75,6 @@ if(WITH_OPENNL)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_armature "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -2069,7 +2069,6 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch,
|
||||
glPushMatrix();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
switch (sketch->next_point.mode) {
|
||||
case PT_SNAP:
|
||||
|
@@ -24,10 +24,12 @@ set(INC
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../imbuf
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -50,4 +52,6 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_gpencil "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -556,7 +556,6 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy,
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
/* turn on alpha-blending */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
/* loop over layers, drawing them */
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#ifndef __BIF_GL_H__
|
||||
#define __BIF_GL_H__
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "GPU_glew.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
|
@@ -30,6 +30,7 @@ set(INC
|
||||
../../python
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -70,4 +71,6 @@ if(WITH_PYTHON)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_interface "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -1329,9 +1329,6 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
|
||||
if (multisample_enabled)
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
/* we set this only once */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* scale fonts */
|
||||
ui_fontscale(&style.paneltitle.points, block->aspect);
|
||||
ui_fontscale(&style.grouplabel.points, block->aspect);
|
||||
|
@@ -446,8 +446,6 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
|
||||
/* restore scissortest */
|
||||
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* outline */
|
||||
glColor4f(0.f, 0.f, 0.f, 0.5f);
|
||||
uiSetRoundBox(UI_CNR_ALL);
|
||||
@@ -460,14 +458,13 @@ static void histogram_draw_one(float r, float g, float b, float alpha,
|
||||
int i;
|
||||
|
||||
if (is_line) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
glLineWidth(1.5);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glColor4f(r, g, b, alpha);
|
||||
|
||||
/* curve outline */
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (i = 0; i < res; i++) {
|
||||
@@ -477,14 +474,19 @@ static void histogram_draw_one(float r, float g, float b, float alpha,
|
||||
glEnd();
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glLineWidth(1.0);
|
||||
}
|
||||
else {
|
||||
/* under the curve */
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
glColor4f(r, g, b, alpha);
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
glVertex2f(x, y);
|
||||
glVertex2f(x, y + (data[0] * h));
|
||||
@@ -496,9 +498,11 @@ static void histogram_draw_one(float r, float g, float b, float alpha,
|
||||
glEnd();
|
||||
|
||||
/* curve outline */
|
||||
|
||||
glColor4f(0.f, 0.f, 0.f, 0.25f);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (i = 0; i < res; i++) {
|
||||
@@ -532,7 +536,6 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
|
||||
h = BLI_rctf_size_y(&rect) * hist->ymax;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glColor4f(0.f, 0.f, 0.f, 0.3f);
|
||||
uiSetRoundBox(UI_CNR_ALL);
|
||||
@@ -619,8 +622,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
glColor4f(0.f, 0.f, 0.f, 0.3f);
|
||||
uiSetRoundBox(UI_CNR_ALL);
|
||||
uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
|
||||
@@ -642,7 +644,6 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
|
||||
BLF_draw_default(rect.xmin + 1, yofs - 5 + (i / 5.f) * h, 0, str, sizeof(str) - 1);
|
||||
/* in the loop because blf_draw reset it */
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
/* 3 vertical separation */
|
||||
if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
|
||||
@@ -665,15 +666,14 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
|
||||
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA)
|
||||
fdrawline(rect.xmin, yofs + h * 0.075f, rect.xmax + 1, yofs + h * 0.075f);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
if (scopes->ok && scopes->waveform_1 != NULL) {
|
||||
|
||||
/* LUMA (1 channel) */
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glColor3f(alpha, alpha, alpha);
|
||||
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glPushMatrix();
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
@@ -702,9 +702,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
|
||||
SCOPES_WAVEFRM_YCC_JPEG))
|
||||
{
|
||||
int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
@@ -743,7 +741,9 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* outline */
|
||||
draw_scope_end(&rect, scissor);
|
||||
}
|
||||
@@ -838,7 +838,6 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
|
||||
alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glColor4f(0.f, 0.f, 0.f, 0.3f);
|
||||
uiSetRoundBox(UI_CNR_ALL);
|
||||
@@ -890,6 +889,8 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glPopMatrix();
|
||||
|
||||
glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
/* outline */
|
||||
@@ -1336,7 +1337,6 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
|
||||
|
||||
/* grid, hsv uses different grid */
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4ub(0, 0, 0, 48);
|
||||
ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -1500,7 +1500,6 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
|
||||
height = BLI_rctf_size_y(&rect);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* need scissor test, preview image can draw outside of boundary */
|
||||
glGetIntegerv(GL_VIEWPORT, scissor);
|
||||
|
@@ -1129,9 +1129,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
|
||||
#endif
|
||||
if (!iimg->rect) return; /* something has gone wrong! */
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else if (di->type == ICON_TYPE_PREVIEW) {
|
||||
PreviewImage *pi = BKE_previewimg_get((ID *)icon->obj);
|
||||
|
@@ -668,9 +668,6 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
|
||||
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
|
||||
/* alpha fill */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glColor4ubv((unsigned char *)wcol->inner);
|
||||
|
||||
for (a = 0; a < wtb->totvert; a++) {
|
||||
|
@@ -25,10 +25,12 @@ set(INC
|
||||
../include
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -48,4 +50,6 @@ set(SRC
|
||||
mask_intern.h
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_mask "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -309,7 +309,6 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
|
||||
if (is_smooth) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
/* control points */
|
||||
@@ -498,7 +497,6 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
|
||||
|
||||
if (is_smooth == false && is_feather) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
mask_color_active_tint(rgb_tmp, rgb_tmp, is_active);
|
||||
@@ -549,7 +547,6 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
|
||||
if (is_smooth) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, &tot_feather_point, resol, (is_fill != false));
|
||||
@@ -826,6 +823,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
|
||||
glPopMatrix();
|
||||
|
||||
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
|
||||
glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,7 @@ set(INC
|
||||
../../render/extern/include
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@@ -86,4 +87,6 @@ if(WITH_BULLET)
|
||||
add_definitions(-DWITH_BULLET)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -992,7 +992,6 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
|
||||
int i;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* draw any snapped verts first */
|
||||
glColor4ubv(kcd->colors.point_a);
|
||||
|
@@ -33,10 +33,11 @@ set(INC
|
||||
../../render/extern/include
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
@@ -62,6 +63,8 @@ set(SRC
|
||||
object_intern.h
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_PYTHON)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
endif()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user