Browse Source

Adding X11 and X11 support. SDL will probably bite the dust

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
23b7a55273

+ 5 - 84
CMakeLists.txt

@@ -33,37 +33,15 @@ ENDMACRO()
 #
 SET(ARCH 64 CACHE STRING "The architecture")
 
-SET(CMAKE_CXX_FLAGS -m${ARCH})
-SET(CMAKE_EXE_LINKER_FLAGS -m${ARCH})
+SET(CMAKE_CXX_FLAGS "-m${ARCH} ")
+SET(CMAKE_C_FLAGS "-m${ARCH} ")
+SET(CMAKE_EXE_LINKER_FLAGS "-m${ARCH} ")
 
 #
 # Install
 #
 SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/" CACHE PATH "The subdirectory to the header prefix")
 SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Library install path")
-
-#
-# SVN
-#
-FIND_PACKAGE(Subversion 1.6 REQUIRED)
-
-IF(Subversion_FOUND)
-	Subversion_WC_INFO(${CMAKE_CURRENT_SOURCE_DIR} ER)
-	ADD_DEFINITIONS("-DANKI_REVISION=${ER_WC_REVISION}")
-	SET(ANKI_REVISION ${ER_WC_REVISION})
-ELSE()
-	ADD_DEFINITIONS("-DANKI_REVISION=???")
-	SET(ANKI_REVISION unkown)
-ENDIF()
-
-# 
-# Version
-#
-SET(ANKI_VERSION 0.1)
-
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/include/anki/Version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/anki/Version.h)
-
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/anki/Version.h DESTINATION ${INCLUDE_INSTALL_DIR}/anki)
 	
 #
 # Doxygen
@@ -107,15 +85,6 @@ SET(FREETYPE_LIBRARY_DIR "/usr/lib"
 
 ANKI_ADD_LIB(${FREETYPE_INCLUDE_DIR} ${FREETYPE_LIBRARY_DIR} ${FREETYPE_INCLUDE_DIR}/freetype/freetype.h)
 
-#
-# Python
-#
-SET(PYTHON_VER 2.7 CACHE STRING "The python version")
-SET(PYTHON_INCLUDE_DIR "/usr/include/python${PYTHON_VER}" CACHE PATH "The directory that contains the Python.h")
-SET(PYTHON_LIBRARY_DIR "/usr/lib" CACHE PATH "The directory that contains the libpython${PYTHON_VER}.so")
-
-ANKI_ADD_LIB(${PYTHON_INCLUDE_DIR} ${PYTHON_LIBRARY_DIR} ${PYTHON_INCLUDE_DIR}/Python.h)
-
 #
 # Bullet (Because FIND_PACKAGE(Bullet) sucks)
 #
@@ -127,67 +96,19 @@ SET(BULLET_LIBRARY_DIR "${ANKI_PROJ_SOURCE_DIR}/extern/lib${ARCH}" CACHE PATH
 ANKI_ADD_LIB(${BULLET_INCLUDE_DIR}/bullet ${BULLET_LIBRARY_DIR} 
 	${BULLET_INCLUDE_DIR}/bullet/btBulletCollisionCommon.h)
 
-# Extern dir
-#
-ADD_SUBDIRECTORY(extern)
-
-INCLUDE_DIRECTORIES(extern/GLEW/include extern/tinyxml2/include extern/lua)
-INCLUDE_DIRECTORIES(extern/include)
-LINK_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/extern/lib64")
-
 #
-# Defines & flags
+# Add subdirs
 #
-ADD_DEFINITIONS(-DANKI_MATH_INTEL_SIMD
-	-Dthread_local=__thread -pedantic-errors -pedantic -ansi -Wall 
-	-W -Wwrite-strings -Wno-unused -Werror -Wno-long-long -msse4 -std=c++0x)
-
-# Add a few compiler specific stuff 
-IF(${CMAKE_CXX_COMPILER} MATCHES ".*clang\\+\\+$")	
-	INCLUDE_DIRECTORIES("/opt/libcxx/include/c++/v1")
-	LINK_DIRECTORIES("/opt/libcxx/lib")
-ELSE()
-	# Dont use it. It produces warnings with -std=c++0x
-	#ADD_DEFINITIONS("-fsingle-precision-constant")
-ENDIF()
-
-IF(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
-	ADD_DEFINITIONS("-DANKI_PLATFORM_LINUX")
-ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
-	ADD_DEFINITIONS("-DANKI_PLATFORM_WINDOWS")
-ENDIF()
-
-IF(CMAKE_BUILD_TYPE STREQUAL Debug)
-	# Removed because they do not work with boost::regexpr and who knows what
-	# else
-	#ADD_DEFINITIONS("-D_GLIBCXX_DEBUG -D_GLIBXX_DEBUG_PEDANTIC")
-ELSE()
-	ADD_DEFINITIONS("-DBOOST_DISABLE_ASSERTS -mtune=core2 -ffast-math")
-ENDIF()
-
-INCLUDE_DIRECTORIES(${ANKI_PROJ_SOURCE_DIR})
-
-#
-# libanki
-#
-INCLUDE_DIRECTORIES(include)
+ADD_SUBDIRECTORY(extern)
 ADD_SUBDIRECTORY(src)
 
-#
-# Unit tests
-#
 OPTION(BUILD_TESTS "Build Unit Tests" OFF)
-
 IF(BUILD_TESTS)
 	ENABLE_TESTING()
 	ADD_SUBDIRECTORY(tests)
 ENDIF()
 
-#
-# testapp
-#
 OPTION(BUILD_TESTAPP "Build Test Application" ON)
-
 IF(BUILD_TESTAPP)
 	ADD_SUBDIRECTORY(testapp)
 ENDIF()

+ 2 - 3
include/anki/Version.h.cmake

@@ -1,9 +1,8 @@
 #ifndef ANKI_VERSION_H
 #define ANKI_VERSION_H
 
-
-#define ANKI_VERSION ${ANKI_VERSION}
+#define ANKI_VERSION_MINOR ${ANKI_VERSION_MINOR}
+#define ANKI_VERSION_MAJOR ${ANKI_VERSION_MAJOR}
 #define ANKI_REVISION ${ANKI_REVISION}
 
-
 #endif

+ 60 - 0
include/anki/core/NativeWindow.h

@@ -0,0 +1,60 @@
+#ifndef ANKI_CORE_NATIVE_WINDOW_H
+#define ANKI_CORE_NATIVE_WINDOW_H
+
+#include "anki/util/StdTypes.h"
+#include "anki/util/Array.h"
+#include <string>
+#include <memory>
+
+namespace anki {
+
+struct NativeWindowImpl;
+
+/// Window initializer
+struct NativeWindowInitializer
+{
+	Array<U32, 4> rgbaBits = {{8, 8, 8, 8}};
+	U32 depthBits = 24;
+	U32 stencilBits = 8;
+	U32 samplesCount = 0;
+	static const Bool doubleBuffer = true;
+
+	U32 minorVersion = 0;
+	U32 majorVersion = 0;
+	Bool useGles = false; ///< Use OpenGL ES
+
+	U32 width = 640;
+	U32 height = 768;
+	std::string title = "Untitled";
+};
+
+/// Native window with GL context
+class NativeWindow
+{
+public:
+	NativeWindow()
+	{}
+	~NativeWindow();
+
+	/// @name Public interface
+	/// Don't implement them in .h files
+	/// @{
+	void create(NativeWindowInitializer& initializer);
+	void destroy();
+	/// @}
+
+private:
+	U32 width;
+	U32 height;
+
+	std::unique_ptr<NativeWindowImpl> impl;
+
+	Bool isCreated() const
+	{
+		return impl.get() != nullptr;
+	}
+};
+
+} // end namespace anki
+
+#endif

+ 41 - 0
include/anki/core/NativeWindowGlxX11.h

@@ -0,0 +1,41 @@
+#ifndef ANKI_CORE_NATIVE_WINDOW_GLX_X11_H
+#define ANKI_CORE_NATIVE_WINDOW_GLX_X11_H
+
+#include "anki/core/NativeWindow.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+namespace anki {
+
+/// Native window implementation for GLX & X11
+struct NativeWindowImpl
+{
+	Display* xDisplay = nullptr;
+	Window xWindow = 0;
+	Colormap xColormap; ///< Its is actualy an unsigned int
+	GLXContext glxContext = nullptr; ///< Its actualy a pointer
+	GLXFBConfig* glxConfig = nullptr;
+
+	~NativeWindowImpl()
+	{
+		destroy();
+	}
+
+	void create(NativeWindowInitializer& init);
+	void destroy();
+
+private:
+	void createInternal(NativeWindowInitializer& init);
+
+	void createDisplay();
+	void createConfig(NativeWindowInitializer& init);
+	void createNativeWindow(NativeWindowInitializer& init);
+	void createContext(NativeWindowInitializer& init);
+};
+
+} // end namespace anki
+
+#endif

+ 5 - 1
include/anki/gl/ShaderProgram.h

@@ -171,7 +171,11 @@ private:
 	/// sense for uniforms that are arrays. For uniforms that are not arrays, 
 	/// but are declared in a named uniform block, an array stride of zero is 
 	/// returned"
-	GLint arrayStride;
+	GLint arrayStride = -1;
+
+	/// Identifying the stride between columns of a column-major matrix or rows 
+	/// of a row-major matrix
+	GLint matrixStride = -1;
 
 	/// Standard set uniform checks
 	/// - Check if initialized

+ 72 - 0
src/CMakeLists.txt

@@ -1,3 +1,75 @@
+#
+# Revision
+#
+FIND_PACKAGE(Subversion 1.6 REQUIRED)
+
+IF(Subversion_FOUND)
+	Subversion_WC_INFO(${CMAKE_CURRENT_SOURCE_DIR} ER)
+	ADD_DEFINITIONS("-DANKI_REVISION=${ER_WC_REVISION}")
+	SET(ANKI_REVISION ${ER_WC_REVISION})
+ELSE()
+	ADD_DEFINITIONS("-DANKI_REVISION=-1")
+	SET(ANKI_REVISION "-1")
+ENDIF()
+
+# 
+# Version
+#
+SET(ANKI_VERSION_MINOR 0)
+SET(ANKI_VERSION_MAJOR 1)
+ADD_DEFINITIONS("-DANKI_VERSION_MINOR=${ANKI_VERSION_MINOR}")
+ADD_DEFINITIONS("-DANKI_VERSION_MAJOR=${ANKI_VERSION_MAJOR}")
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../include/anki/Version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/anki/Version.h)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/anki/Version.h DESTINATION ${INCLUDE_INSTALL_DIR}/anki)
+
+#
+# Defines
+#
+ADD_DEFINITIONS("-DANKI_MATH_INTEL_SIMD")
+ADD_DEFINITIONS("-Dthread_local=__thread")
+
+IF(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
+	ADD_DEFINITIONS("-DANKI_PLATFORM_LINUX")
+ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
+	ADD_DEFINITIONS("-DANKI_PLATFORM_WINDOWS")
+ENDIF()
+
+# Add a few compiler specific stuff 
+IF(${CMAKE_CXX_COMPILER} MATCHES ".*clang\\+\\+$")	
+	INCLUDE_DIRECTORIES("/opt/libcxx/include/c++/v1")
+	LINK_DIRECTORIES("/opt/libcxx/lib")
+ELSE()
+	# Dont use it. It produces warnings with -std=c++0x
+	#ADD_DEFINITIONS("-fsingle-precision-constant")
+ENDIF()
+
+#
+# Extern directories
+#
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/GLEW/include ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinyxml2/include ${CMAKE_CURRENT_SOURCE_DIR}/../extern/lua)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/include)
+LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/lib64)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+
+#
+# Compiler flags
+#
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors -pedantic -ansi -Wall -W -Wwrite-strings -Wno-unused -Werror -Wno-long-long -msse4 -std=c++11 ")
+
+IF(CMAKE_BUILD_TYPE STREQUAL Debug)
+	# Removed because they do not work with boost::regexpr and who knows what
+	# else
+	#ADD_DEFINITIONS("-D_GLIBCXX_DEBUG -D_GLIBXX_DEBUG_PEDANTIC")
+ELSE()
+	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=core2 -ffast-math ")
+ENDIF()
+
+#
+# Add anki sub libraries
+#
 SET(ANKI_SUB_DIRS script renderer scene ui event input physics resource core misc gl collision math util)
 
 SET(ANKI_LIBS "")

+ 0 - 0
src/core/NativeWindowEglX11.cpp


+ 267 - 0
src/core/NativeWindowGlxX11.cpp

@@ -0,0 +1,267 @@
+#include "anki/core/NativeWindowGlxX11.h"
+#include "anki/util/Exception.h"
+
+namespace anki {
+
+//==============================================================================
+// NativeWindowImpl                                                            =
+//==============================================================================
+
+typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, 
+	GLXFBConfig, GLXContext, Bool, const int*);
+
+//==============================================================================
+void NativeWindowImpl::createDisplay()
+{
+	ANKI_ASSERT(xDisplay == nullptr);
+	xDisplay = XOpenDisplay(0);
+	if(!xDisplay)
+	{
+		throw ANKI_EXCEPTION("XOpenDisplay() failed");
+	}
+}
+
+//==============================================================================
+void NativeWindowImpl::createConfig(NativeWindowInitializer& init)
+{
+	Array<int, 256> attribs;
+	U at = 0;
+
+	attribs[at++] = GLX_X_RENDERABLE;
+	attribs[at++] = True;
+
+	attribs[at++] = GLX_DRAWABLE_TYPE;
+	attribs[at++] = GLX_WINDOW_BIT;
+
+	attribs[at++] = GLX_RENDER_TYPE;
+	attribs[at++] = GLX_RGBA_BIT;
+
+	attribs[at++] = GLX_X_VISUAL_TYPE;
+	attribs[at++] = GLX_TRUE_COLOR;
+
+	attribs[at++] = GLX_RED_SIZE;
+	attribs[at++] = init.rgbaBits[0];
+
+	attribs[at++] = GLX_GREEN_SIZE;
+	attribs[at++] = init.rgbaBits[1];
+
+	attribs[at++] = GLX_GREEN_SIZE;
+	attribs[at++] = init.rgbaBits[2];
+
+	attribs[at++] = GLX_ALPHA_SIZE;
+	attribs[at++] = init.rgbaBits[3];
+
+	attribs[at++] = GLX_DEPTH_SIZE;
+	attribs[at++] = init.depthBits;
+
+	attribs[at++] = GLX_STENCIL_SIZE;
+	attribs[at++] = init.stencilBits;
+
+	attribs[at++] = GLX_DOUBLEBUFFER;
+	attribs[at++] = init.doubleBuffer;
+
+	if(init.samplesCount)
+	{
+		attribs[at++] = GLX_SAMPLE_BUFFERS;
+		attribs[at++] = 1;
+
+		attribs[at++] = GLX_SAMPLES;
+		attribs[at++] = init.samplesCount;
+	}
+
+	attribs[at++] = None;
+
+	int fbcount;
+	glxConfig = glXChooseFBConfig(xDisplay, DefaultScreen(xDisplay), 
+		&attribs[0], &fbcount);
+
+	if(!glxConfig)
+	{
+		throw ANKI_EXCEPTION("glXChooseFBConfig() failed");
+	}
+}
+
+//==============================================================================
+void NativeWindowImpl::createNativeWindow(NativeWindowInitializer& init)
+{
+	XVisualInfo* vi;
+	XSetWindowAttributes swa;
+	Window root;
+
+	vi = glXGetVisualFromFBConfig(xDisplay, glxConfig[0]);
+
+	if(!vi)
+	{
+		throw ANKI_EXCEPTION("XGetVisualInfo() failed");
+	}
+
+	root = RootWindow(xDisplay, vi->screen);
+
+	/* creating colormap */
+	swa.colormap = xColormap = XCreateColormap(xDisplay, root, 
+		vi->visual, AllocNone);
+	swa.background_pixmap = None ;
+	swa.border_pixel      = 0;
+	swa.event_mask        = StructureNotifyMask;
+ 
+	xWindow = XCreateWindow(
+		xDisplay, root, 
+		0, 0, init.width, init.height, 0, 
+		vi->depth, InputOutput, vi->visual, 
+		CWBorderPixel | CWColormap | CWEventMask, 
+		&swa);
+
+	XFree(vi);
+
+	if(!xWindow)
+	{
+		throw ANKI_EXCEPTION("XCreateWindow() failed");
+	}
+
+	XStoreName(xDisplay, xWindow, init.title.c_str());
+	XMapWindow(xDisplay, xWindow);
+}
+
+//==============================================================================
+void NativeWindowImpl::createContext(NativeWindowInitializer& init)
+{
+	int ctxAttribs[] = {
+		GLX_CONTEXT_MAJOR_VERSION_ARB, (int)init.majorVersion,
+		GLX_CONTEXT_MINOR_VERSION_ARB, (int)init.minorVersion,
+		None};
+
+	glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+
+	glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
+		glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
+
+	if(!glXCreateContextAttribsARB)
+	{
+		throw ANKI_EXCEPTION("Cannot get addres of proc "
+			"glXCreateContextAttribsARB");
+	}
+	
+	glxContext = glXCreateContextAttribsARB(xDisplay, *glxConfig, 0,
+		True, ctxAttribs);
+
+	XSync(xDisplay, False);
+
+	if(!glxContext)
+	{
+		throw ANKI_EXCEPTION("glXCreateContextAttribsARB() failed");
+	}
+
+	if(!glXMakeCurrent(xDisplay, xWindow, glxContext))
+	{
+		throw ANKI_EXCEPTION("glXMakeCurrent() failed");
+	}
+}
+
+//==============================================================================
+void NativeWindowImpl::createInternal(NativeWindowInitializer& init)
+{
+	if(init.useGles)
+	{
+		throw ANKI_EXCEPTION("GLX and GLES is not supported. "
+			"Use other backend");
+	}
+
+	// Display
+	createDisplay();
+
+	// GLX init
+	int major, minor;
+	if(!glXQueryVersion(xDisplay, &major, &minor))
+	{
+		throw ANKI_EXCEPTION("glXQueryVersion() failed");
+	}
+
+	if(((major == 1) && (minor < 3)) || (major < 1))
+	{
+		throw ANKI_EXCEPTION("Old GLX version");
+	}
+
+	// Config
+	createConfig(init);
+
+	// Window
+	createNativeWindow(init);
+
+	// Context
+	createContext(init);
+
+	// GLEW
+	glewExperimental = GL_TRUE;
+	if(glewInit() != GLEW_OK)
+	{
+		throw ANKI_EXCEPTION("GL initialization failed");
+	}
+	glGetError();
+}
+
+//==============================================================================
+void NativeWindowImpl::create(NativeWindowInitializer& init)
+{
+	try
+	{
+		createInternal(init);
+	}
+	catch(const std::exception& e)
+	{
+		destroy();
+		throw ANKI_EXCEPTION("Window creation failed") << e;
+	}
+}
+
+//==============================================================================
+void NativeWindowImpl::destroy()
+{
+	if(glxContext)
+	{
+		ANKI_ASSERT(xDisplay);
+		glXMakeCurrent(xDisplay, 0, 0);
+		glXDestroyContext(xDisplay, glxContext);
+		glxContext = nullptr;
+	}
+
+	if(xWindow)
+	{
+		ANKI_ASSERT(xDisplay);
+		XDestroyWindow(xDisplay, xWindow);
+		xWindow = 0;
+	}
+
+	if(xColormap)
+	{
+		ANKI_ASSERT(xDisplay);
+		XFreeColormap(xDisplay, xColormap);
+	}
+
+	if(xDisplay)
+	{
+		XCloseDisplay(xDisplay);
+		xDisplay = nullptr;
+	}
+}
+
+//==============================================================================
+// NativeWindow                                                                =
+//==============================================================================
+
+//==============================================================================
+NativeWindow::~NativeWindow()
+{}
+
+//==============================================================================
+void NativeWindow::create(NativeWindowInitializer& initializer)
+{
+	impl.reset(new NativeWindowImpl);
+}
+
+//==============================================================================
+void NativeWindow::destroy()
+{
+	impl.reset(nullptr);
+}
+
+} // end namespace anki

+ 24 - 0
src/gl/ShaderProgram.cpp

@@ -523,6 +523,30 @@ void ShaderProgram::initUniformBlocks()
 			&offset);
 		ANKI_ASSERT(offset != -1); // If -1 then it should break before
 		uni.offset = offset;
+
+		/* Array stride */
+		GLint arrStride;
+		glGetActiveUniformsiv(glId, 1, &(uni.index),  GL_UNIFORM_ARRAY_STRIDE, 
+			&arrStride);
+		ANKI_ASSERT(arrStride != -1); // If -1 then it should break before
+		uni.arrayStride = arrStride;
+
+		/* Matrix stride */
+		GLint matStride;
+		glGetActiveUniformsiv(glId, 1, &(uni.index),  GL_UNIFORM_MATRIX_STRIDE, 
+			&matStride);
+		ANKI_ASSERT(matStride != -1); // If -1 then it should break before
+		uni.matrixStride = matStride;
+
+		/* Matrix layout check */
+		GLint isRowMajor;
+		glGetActiveUniformsiv(glId, 1, &(uni.index),  GL_UNIFORM_IS_ROW_MAJOR, 
+			&isRowMajor);
+		if(isRowMajor)
+		{
+			ANKI_LOGW("The engine is designed to work with column major "
+				"matrices: " << uni.name);
+		}
 	}
 }
 

+ 10 - 0
testapp/CMakeLists.txt

@@ -1,3 +1,13 @@
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors -pedantic -ansi -Wall -W -Wwrite-strings -Wno-unused -Werror -Wno-long-long -msse4 -std=c++11 ")
+
+ADD_DEFINITIONS("-Dthread_local=__thread")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/GLEW/include ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinyxml2/include ${CMAKE_CURRENT_SOURCE_DIR}/../extern/lua)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/include)
+LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../extern/lib64)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+
 ADD_EXECUTABLE(testapp Main.cpp)
 
 TARGET_LINK_LIBRARIES(testapp anki)