1
1

Compare commits

...

42 Commits

Author SHA1 Message Date
d9ffc99e66 Merge branch 'master' into soc-2014-viewport_fx
I have resolved some differences, for instance selection code which was more or less a stub, to be
the same as master. This will have to be fixed later.

Conflicts:
	CMakeLists.txt
	intern/ghost/CMakeLists.txt
	intern/ghost/intern/GHOST_SystemWin32.cpp
	intern/ghost/intern/GHOST_Window.cpp
	intern/ghost/intern/GHOST_WindowWin32.cpp
	intern/ghost/intern/GHOST_WindowX11.cpp
	source/blender/blenlib/BLI_math_matrix.h
	source/blender/blenlib/intern/math_matrix.c
	source/blender/gpu/CMakeLists.txt
	source/blender/gpu/GPU_select.h
	source/blender/gpu/intern/gpu_buffers.c
	source/blender/gpu/intern/gpu_draw.c
	source/blender/gpu/intern/gpu_extensions.c
	source/blender/gpu/intern/gpu_select.c
	source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
	source/blender/nodes/CMakeLists.txt
2014-09-08 18:15:42 +02:00
551ebaa3dd Fix compilation on linux (Ubuntu 14.04 used here). 2014-09-08 15:33:42 +02:00
50366779e6 Merge remote-tracking branch 'origin' into soc-2014-viewport_fx
Conflicts:
	source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
2014-07-10 18:18:14 -05:00
1d8739b014 need to call releaseNativeHandles in GHOST_WindowX11's destructor, as well as some additional checks in GHOST_ContextGLX's destructor 2014-07-10 17:59:56 -05:00
4dc1ec4564 fix initial window size being too large for OSX/X11 on multiple monitors (check for X11 being used instead of not APPLE and not WIN32) 2014-07-10 08:34:35 -05:00
3e454e0c5d oops, some typos made it into the GLX context commit 2014-07-10 07:29:47 -05:00
ab86fafed4 removed some accidentally added backup files 2014-07-10 07:17:46 -05:00
0ef5c183d8 Merge branch 'soc-2014-viewport_fx' of git.blender.org:blender into soc-2014-viewport_fx 2014-07-09 21:30:31 -05:00
71ea85cc61 [Revision] GHOST Context Refactor for X11 (Also can compile GHOST X11 on OSX)
This is much like the CGL context in that it is fairly preliminary and does not have all the features of EGL or WGL contexts yet.
In order to work on this on OSX, some minor changes were made to CMake to link with X11 on OSX
2014-07-09 18:19:18 -05:00
85fdb5adef some readability edits for ghost context classes
also added code to clear screen immediately after context creation, similar to how it is done for glX
2014-07-09 18:13:49 -05:00
a1d1b07eb6 removed apparent overly verbose conversion of int to bool in GHOST_C-api.cpp 2014-07-09 18:06:07 -05:00
62e83b3478 fix: xdnd module did not compile on OSX without setting the location of X11 include files 2014-07-09 18:03:14 -05:00
40b6df7851 Moved and deleted some code from GHOST Cocoa
moved locale query to the intern/locale module
deleted some odd code that did not appear to be actually used relating to command line arguments
2014-07-09 17:56:49 -05:00
302a5b56df [OpenGL Policy] BlendFuncSeparate defaults to GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO
Only set the blend func if the coefficients are different.  Return them to the defaults when done.

Note: Fairly confident that Blender and the standalone Cycles renderer are correct, but that both the embedded and standalone game engine will need more testing.

Note: Do we actually want the default to be: GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA?
2014-07-04 15:15:16 -05:00
df3313187f Merge branch 'master' of git.blender.org:blender into soc-2014-viewport_fx 2014-07-04 11:58:37 -05:00
361ab2ff2e OpenGL Extension Shims
A few things are going on with these "shims":
* OpenGL 2.0 and GLEW_ARB_shader_objects are subtly different.
* Some extensions come in ARB and OES flavors.
* GenerateMipmaps needs a workaround on ATI.
* gpu_buffer_start_update and gpu_buffer_finish_update make usage of buffer objects a bit more abstract

Any use of a shimmed function directly without the shim is caught by GPU_deprecated.h

There are also some other changes that are not related to shims that came along for the ride.
2014-07-04 11:57:20 -05:00
c39f6c49b7 Made a mistake when rewriting GPU_material_construct_end to return bool. 2014-07-04 11:40:43 -05:00
407a6dfdc9 #if 0'd out all of GPU_deprecated.h and turned on GPU_MANGLE_DEPRECATED by default.
Will add functions and symbols back as work progresses.

Since bgl.c uses OpenGL directly like source/blender/gpu, it disables GPU_MANGLE_DEPRECATED.
2014-07-04 11:38:08 -05:00
dc627428c9 Added getNumOfAASamples to GHOST_IWindow interface.
I was going to use it for something, but decided to use glGetIntegerv(GL_SAMPLES, &i) instead.
It may be the case that neither this nor stereoVisual should be cached.
2014-07-04 11:30:33 -05:00
653379b15a Fixed documentation of GHOST_GetSwapInterval to match new interface 2014-07-01 04:12:22 -05:00
1ead782e3c Merge branch 'master' of git.blender.org:blender into soc-2014-viewport_fx 2014-07-01 02:49:38 -05:00
6741f8e7a0 Accidentally committed some backup copies of some files in gpu. 2014-06-28 04:02:55 -05:00
b54017edb0 Merge branch 'master' of git.blender.org:blender into soc-2014-viewport_fx 2014-06-27 06:09:00 -05:00
7c012d906c Merge branch 'soc-2014-viewport_fx' of git.blender.org:blender into soc-2014-viewport_fx 2014-06-27 05:50:41 -05:00
d56908df51 Some changes to OSX GHOST contexts got left out of previous separation of wanted parameters and actual parameters 2014-06-27 05:48:39 -05:00
42beba3f73 (Showing My Work) Expanded GPU Module to Support Modern OpenGL
I am updating the GPU module so that it contains code needed for Blender to support a programmable shader based pipeline.

In an effort to make sure things always compile I've excluded most of the changes from 2013 that were made to gpu_codegen, gpu_draw, gpu_extensions, and gpu_material.

This new functionality is not used anywhere in Blender yet.  That will come gradually.

This is a bit rough because I wanted something in the repository before evaluations.  I wanted to break this into smaller more manageable pieces for code review, but that would take too much time.  However, this might still work for review purposes.
2014-06-27 05:20:31 -05:00
4f88d6d74c Merge branch 'master' of git.blender.org:blender into soc-2014-viewport_fx 2014-06-27 04:57:53 -05:00
4606950e81 Merge branch 'master' of git.blender.org:blender into soc-2014-viewport_fx
Conflicts:
	CMakeLists.txt
	source/creator/CMakeLists.txt
	source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
2014-06-27 03:01:42 -05:00
8ecdbe5f98 (Revision 1) New Matrix and Vector Operations for Viewport FX
Addressed concerns:
"Using const with multi-dimensional arrays gives warnings in GCC/Clang"
"This so short that I dont think its even copyrightable, (cross product and some assignments)"
"all other functions have mul_ prefix. why difference?"

I also cleaned up some whitespace.

Have not addressed concerns about the name of scale_m4 or the generality/compatibility of translate_m4.
2014-06-26 22:45:03 -05:00
d3de9c621e Revert "BLI_restrict macro to help the compiler optimize functions that do not allow pointer aliasing."
This reverts commit 9e402f8866.
2014-06-26 21:43:49 -05:00
728bb4d239 Fix for MSVC where __func__ is not defined unless you accidentally include BLI_compiler_compat.h 2014-06-25 16:13:52 -05:00
9e402f8866 BLI_restrict macro to help the compiler optimize functions that do not allow pointer aliasing. 2014-06-25 16:11:46 -05:00
25bb89896c New Matrix and Vector Operations for Viewport FX
New functions required for emulation an OpenGL style matrix stack on the GPU
New functions that replace functionality provided by GLU
Some fixes to make various matrix and vector functions const correct
More efficient '_q' matrix functions that assume no pointer aliasing
A set of macros for initializing vector arrays (VEC2D, VEC3D, VEC4D)
2 and 4 dimensional versions of VECCOPY macro
Typo fix, ortho_v2_v2 formal parameter implied a 3 element array, instead of the proper 2
2014-06-25 16:10:39 -05:00
7fd107b320 Using 0 as an error sentinel for the swap interval is not strictly correct.
0 is a valid value for a swap interval and different users of getSwapInterval may want to substitute different values if the swap interval cannot be read.

This commit changes the prototype to: GHOST_TSuccess getSwapInterval(int& intervalOut)

Users of the function should either check the return value or set intervalOut to a default value before calling getSwapInterval.
2014-06-25 10:55:02 -05:00
ebe89356b5 GHOST_ContextCGL
Initial pass at a re-factored OpenGL context for Cocoa.
This does not yet implement the same checks and warnings that the WGL and EGL contexts have.
2014-06-25 10:15:35 -05:00
5eb9a088fd Update of GHOST_ContextNone so that functions recently added to the interface have dummy implementations that are no-ops but still "succeed" at doing nothing (the defaults in GHOST_Context "fail" to do nothing) 2014-06-25 09:17:59 -05:00
1f565b3217 Separation of desired stereo and multisample parameters from actual values along with some other fixes to GHOST
stereoVisual and numOfAASamples now stored in GHOST_Context
parameters for GHOST_Window renamed to wantStereoVisual and wantNumOfAASamples to reflect that context creation will try to satisfy the request, but not fail if it cannot.
The parameters in GHOST_Context hold the actual values that were initialized
added isValid to base GHOST_Window
added updateDrawingContext to GHOST_Context and GHOST_Window (However, it is only needed by OSX)
fixed typo: WGLEW_WGL_EXT_swap_control -> WGLEW_EXT_swap_control
2014-06-25 09:13:19 -05:00
3ae2dc47e7 The GLU library in BLENDER_GL_LIBRARIES was accidentally being replaced. Solution is to use list(APPEND) instead of set(). 2014-06-25 08:59:35 -05:00
94999949d8 cleanup related to EGL contexts
added EGL 1.5 entry points to glew-es
glew-es was assuming that EGL and ES always go together, but you can use EGL to initialize non-ES contexts
moved swap interval implementation to GHOST_Context classes
added EGLDisplay parameter to EGLEWInit in order to work around ARM Mali bug (but seems sensible compared to other EGL functions)
more checks before calling eglBindAPI, no need if there is no EGL display
2014-06-13 18:28:19 -05:00
a8dee3a614 GHOST Refactor for EGL Contexts
Documentation to appear here:
http://wiki.blender.org/index.php/User:Jwilkins/VFX/GHOST_Refactor_for_EGL

Missing from this commit is support for systems other than Windows.
This also only builds with CMake.
2014-06-11 20:26:22 -05:00
6da8fa60f5 More fixes for CMake, MSVC 2013, Windows 8
The hard-coded path for OpenEXR library should include the -2_1 suffix.

Added /SAFESEH:NO flag to standalone Cycles application so it can link.

The standalone Cycles application needs both debug and optimized versions of the OpenEXR libraries.
2014-06-09 12:06:28 -05:00
e01449fa4b Fixes and workarounds for build problems: Windows 8.1, CMake 2.8.12.2, MSVC 2013
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.

Setting JPEG_NAME seems to be required by any version of MSVC, not just 9,
so changed check from MSVC09 to just MSVC

The proper Boost static libraries are not found unless the following variables are set:
set(Boost_USE_STATIC_RUNTIME ON) # prefix lib
set(Boost_USE_MULTITHREADED  ON) # suffix -mt
set(Boost_USE_STATIC_LIBS    ON) # suffix -s

Note: The debug versions of the opencollada libraries are missing from windows_v12,
but this cannot be worked around (except to disable opencollada for debug builds)
because the value of _ITERATOR_DEBUG_LEVEL is different between opencollada and the
rest of Blender, so cannot just use the release versions with a debug build.
The fix would be to add the _d versions to the library directory.

Set /SAFESEH:NO to fix linker error related to libjpeg
(not sure why libjpeg is not compatible with this flag)
Also quiets warning about ignoring  /EDITANDCONTINUE due to having /SAFESEH enabled

Some typos in buildinfo.cmake fixed.

In buildinfo.cmake, trying to determine if a branch is modified when it
has no upstream branch kills the build, so added ERROR_QUIET where upstream
check was done.
2014-06-07 03:13:05 -05:00
284 changed files with 73091 additions and 3130 deletions

View File

@@ -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)

View 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()

View File

@@ -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.

View File

@@ -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
View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

22405
extern/glew-es/src/glew.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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}")

View File

@@ -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)

View File

@@ -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()

View File

@@ -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}")

View File

@@ -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()

View File

@@ -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})

View File

@@ -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)

View File

@@ -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);

View File

@@ -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})

View File

@@ -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})

View File

@@ -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__ */

View File

@@ -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);

View File

@@ -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}")

View File

@@ -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.

View File

@@ -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.

View File

@@ -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;

View 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());
}

View 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__

View 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_

View 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;
}

View 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;
}

View 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_

View 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;
}
}

View 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_

View 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;
}

View 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__

View 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;
}

View 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_

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -34,7 +34,6 @@
#define __GHOST_SYSTEMX11_H__
#include <X11/Xlib.h>
#include <GL/glx.h>
#include "GHOST_System.h"
#include "../GHOST_Types.h"

View File

@@ -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)

View File

@@ -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;
};

View File

@@ -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__

View File

@@ -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()
{

View File

@@ -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;
}

View File

@@ -174,7 +174,7 @@ protected:
GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
GHOST_TSuccess setSwapInterval(int interval);
int getSwapInterval();
GHOST_TSuccess getSwapInterval(int& intervalOut);
};

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View 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
View 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

View 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

View File

@@ -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

View File

@@ -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()

View File

@@ -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("");

View File

@@ -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

View 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;
}

View File

@@ -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}

View File

@@ -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;

View File

@@ -37,7 +37,7 @@
#include <sstream>
#include <string.h>
#include <GL/glew.h>
#include "glew-mx.h"
#include <OpenColorIO/OpenColorIO.h>

View File

@@ -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}")

View File

@@ -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);

View File

@@ -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

View File

@@ -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! */

View File

@@ -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>

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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"

View File

@@ -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]);

View File

@@ -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);

View File

@@ -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); \

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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])
{

View File

@@ -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}")

View File

@@ -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 ........................................... */

View File

@@ -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);

View File

@@ -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

View File

@@ -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}")

View File

@@ -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:

View File

@@ -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}")

View File

@@ -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 */

View File

@@ -33,7 +33,7 @@
#ifndef __BIF_GL_H__
#define __BIF_GL_H__
#include "GL/glew.h"
#include "GPU_glew.h"
#ifdef __APPLE__

View File

@@ -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}")

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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++) {

View File

@@ -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}")

View File

@@ -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);
}

View File

@@ -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}")

View File

@@ -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);

View File

@@ -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