void * getNativeDisplay(GLFWwindow * window)
 {
     void * nativeDisplay = nullptr;
     ON_LINUX([&]
     {
         nativeDisplay = (void*)glfwGetX11Display();
     });
     return nativeDisplay;
 }
예제 #2
0
void init_cl(const char ** sources, int count) {
    int err = CL_SUCCESS;

    // get the platform id for this system
    cl_platform_id platform;
    err = clGetPlatformIDs(1, &platform, NULL);
    cl_check_err(err, "clGetPlatformIDs(...)");

    // connect to the compute device
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
    cl_check_err(err, "clGetDeviceIDs(...)");

    // set the platform specific context properties for OpenGL + OpenCL sharing
#ifdef __APPLE__
    cl_context_properties ctx_prop[] = {
        CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
        (cl_context_properties)CGLGetShareGroup(CGLGetCurrentContext()),
        0};

#elif defined __linux__
    cl_context_properties ctx_prop[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties)glfwGetGLXContext(window),
        CL_GLX_DISPLAY_KHR, (cl_context_properties)glfwGetX11Display(),
        CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
        0};
#elif defined __MINGW32__
    cl_context_properties ctx_prop[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
        CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
        CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
        0};
#endif

    // create the working context
    context = clCreateContext(ctx_prop, 1, &device_id, NULL, NULL, &err);
    cl_check_err(err, "clCreateContext(...)");

    // next up is the command queue
    command_queue = clCreateCommandQueue(context, device_id, 0, &err);
    cl_check_err(err, "clCreateCommandQueue(...)");

    // create a single source buffer for the program from the input files
    size_t length = 0;
    for (int i = 0; i < count; i++) {
        length += file_length(sources[i]);
    }

    char * buffer = (char *)malloc(length);
    buffer[0] = '\0';
    for (int i = 0; i < count; i++) {
        char * tmp = read_file(sources[i]);
        strcat(buffer, tmp);
        free(tmp);
    }

    // create the compute program from 'kernels.cl'
    program = clCreateProgramWithSource(context, 1, (const char **)&buffer, NULL, &err);
    cl_check_err(err, "clCreateProgramWithSource(...)");
    free(buffer); // program already read, we don't need the buffer anymore

    // compile the program for our device
    err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
    cl_check_err(err, "clBuildProgram(...)");

    // create the computer kernel in the program we wish to run
    kernel = clCreateKernel(program, "ray_tracer", &err);
    cl_check_err(err, "clCreateKernel(...)");
}
예제 #3
0
파일: main.c 프로젝트: Oblomov/mandelbrot
// OpenCL functions
int InitialiseCLEnvironment(cl_platform_id **platform, cl_device_id ***device_id, cl_program *program, renderStruct *render)
{
	// error flag
	cl_int err;
	char infostring[1024];
	char deviceInfo[1024];

	// need to ensure platform supports OpenGL OpenCL interop before querying devices
	// to avoid segfault when calling clGetGLContextInfoKHR
	int *platformSupportsInterop;

	//get kernel from file
	FILE* kernelFile = fopen(kernelFileName, "rb");
	fseek(kernelFile, 0, SEEK_END);
	long fileLength = ftell(kernelFile);
	rewind(kernelFile);
	char *kernelSource = malloc(fileLength*sizeof(char));
	long read = fread(kernelSource, sizeof(char), fileLength, kernelFile);
	if (fileLength != read) printf("Error reading kernel file, line %d\n", __LINE__);
	fclose(kernelFile);

	//get platform and device information
	cl_uint numPlatforms;
	err = clGetPlatformIDs(0, NULL, &numPlatforms);
	*platform = malloc(numPlatforms * sizeof(cl_platform_id));
	*device_id = malloc(numPlatforms * sizeof(cl_device_id*));
	platformSupportsInterop = malloc(numPlatforms * sizeof(*platformSupportsInterop));
	err |= clGetPlatformIDs(numPlatforms, *platform, NULL);
	CheckOpenCLError(err, __LINE__);
	cl_uint *numDevices;
	numDevices = malloc(numPlatforms * sizeof(cl_uint));

	for (cl_uint i = 0; i < numPlatforms; i++) {
		clGetPlatformInfo((*platform)[i], CL_PLATFORM_VENDOR, sizeof(infostring), infostring, NULL);
		printf("\n---OpenCL: Platform Vendor %d: %s\n", i, infostring);

		err = clGetDeviceIDs((*platform)[i], CL_DEVICE_TYPE_ALL, 0, NULL, &(numDevices[i]));
		CheckOpenCLError(err, __LINE__);
		(*device_id)[i] = malloc(numDevices[i] * sizeof(cl_device_id));
		platformSupportsInterop[i] = 0;
		err = clGetDeviceIDs((*platform)[i], CL_DEVICE_TYPE_ALL, numDevices[i], (*device_id)[i], NULL);
		CheckOpenCLError(err, __LINE__);
		for (cl_uint j = 0; j < numDevices[i]; j++) {
			char deviceName[200];
			clGetDeviceInfo((*device_id)[i][j], CL_DEVICE_NAME, sizeof(deviceName), deviceName, NULL);
			printf("---OpenCL:    Device found %d. %s\n", j, deviceName);
			clGetDeviceInfo((*device_id)[i][j], CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL);
			if (strstr(deviceInfo, "cl_khr_gl_sharing") != NULL) {
				printf("---OpenCL:        cl_khr_gl_sharing supported!\n");
				platformSupportsInterop[i] = 1;
			}
			else {
				printf("---OpenCL:        cl_khr_gl_sharing NOT supported!\n");
				platformSupportsInterop[i] |= 0;
			}
			if (strstr(deviceInfo, "cl_khr_fp64") != NULL) {
				printf("---OpenCL:        cl_khr_fp64 supported!\n");
			}
			else {
				printf("---OpenCL:        cl_khr_fp64 NOT supported!\n");
			}
		}
	}
	printf("\n");


	////////////////////////////////
	// This part is different to how we usually do things. Need to get context and device from existing
	// OpenGL context. Loop through all platforms looking for the device:
	cl_device_id device = NULL;
	int deviceFound = 0;
	cl_uint checkPlatform = 0;

#ifdef TRYINTEROP
	while (!deviceFound) {
		if (platformSupportsInterop[checkPlatform]) {
			printf("---OpenCL: Looking for OpenGL Context device on platform %d ... ", checkPlatform);
			clGetGLContextInfoKHR_fn pclGetGLContextInfoKHR;
			PTR_FUNC_PTR pclGetGLContextInfoKHR = clGetExtensionFunctionAddressForPlatform((*platform)[checkPlatform], "clGetGLContextInfoKHR");
			cl_context_properties properties[] = {
				CL_GL_CONTEXT_KHR, (cl_context_properties) glfwGetGLXContext(render->window),
				CL_GLX_DISPLAY_KHR, (cl_context_properties) glfwGetX11Display(),
				CL_CONTEXT_PLATFORM, (cl_context_properties) (*platform)[checkPlatform],
				0};
			err = pclGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &device, NULL);
			if (err != CL_SUCCESS) {
				printf("Not Found.\n");
				checkPlatform++;
				if (checkPlatform > numPlatforms-1) {
					printf("---OpenCL: Error! Could not find OpenGL sharing device.\n");
					deviceFound = 1;
					render->glclInterop = 0;
				}
			}
			else {
				printf("Found!\n");
				deviceFound = 1;
				render->glclInterop = 1;
			}
		}
		else {
			checkPlatform++;
		}
	}

	if (render->glclInterop) {
		// Check the device we've found supports double precision
		clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL);
		if (strstr(deviceInfo, "cl_khr_fp64") == NULL) {
			printf("---OpenCL: Interop device doesn't support double precision! We cannot use it.\n");
		}
		else {
			cl_context_properties properties[] = {
				CL_GL_CONTEXT_KHR, (cl_context_properties) glfwGetGLXContext(render->window),
				CL_GLX_DISPLAY_KHR, (cl_context_properties) glfwGetX11Display(),
				CL_CONTEXT_PLATFORM, (cl_context_properties) (*platform)[checkPlatform],
				0};
			render->contextCL = clCreateContext(properties, 1, &device, NULL, 0, &err);
			CheckOpenCLError(err, __LINE__);
		}
	}
#endif

	// if render->glclInterop is 0, either we are not trying to use it, we couldn't find an interop
	// device, or we found an interop device but it doesn't support double precision.
	// In these cases, have the user choose a platform and device manually.
	if (!(render->glclInterop)) {
		printf("Choose a platform and device.\n");
		checkPlatform = numPlatforms;
		while (checkPlatform >= numPlatforms) {
			printf("Platform: ");
			scanf("%u", &checkPlatform);
			if (checkPlatform >= numPlatforms) {
				printf("Invalid Platform choice.\n");
			}
		}

		cl_uint chooseDevice = numDevices[checkPlatform];
		while (chooseDevice >= numDevices[checkPlatform]) {
			printf("Device: ");
			scanf("%u", &chooseDevice);
			if (chooseDevice >= numDevices[checkPlatform]) {
				printf("Invalid Device choice.\n");
			} else {
				// Check the device we've chosen supports double precision
				clGetDeviceInfo((*device_id)[checkPlatform][chooseDevice], CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL);
				if (strstr(deviceInfo, "cl_khr_fp64") == NULL) {
					printf("---OpenCL: Interop device doesn't support double precision! We cannot use it.\n");
					chooseDevice = numDevices[checkPlatform];
				}
			}
		}

		// Create non-interop context
		render->contextCL = clCreateContext(NULL, 1, &((*device_id)[checkPlatform][chooseDevice]), NULL, NULL, &err);
		device = (*device_id)[checkPlatform][chooseDevice];
	}
	////////////////////////////////

	// device is now fixed. Query its max global memory allocation size and store it, used in
	// HighResolutionRender routine, to determine into how many tiles we need to split the
	// computation.
	clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(render->deviceMaxAlloc), &(render->deviceMaxAlloc), NULL);
	printf("---OpenCL: Selected device has CL_DEVICE_MAX_MEM_ALLOC_SIZE: %lfMB\n",
	       render->deviceMaxAlloc/1024.0/1024.0);

	// create a command queue
	render->queue = clCreateCommandQueue(render->contextCL, device, 0, &err);
	CheckOpenCLError(err, __LINE__);


	//create the program with the source above
//	printf("Creating CL Program...\n");
	*program = clCreateProgramWithSource(render->contextCL, 1, (const char**)&kernelSource, NULL, &err);
	if (err != CL_SUCCESS) {
		printf("Error in clCreateProgramWithSource: %d, line %d.\n", err, __LINE__);
		return EXIT_FAILURE;
	}

	//build program executable
	err = clBuildProgram(*program, 0, NULL, "-I. -I src/", NULL, NULL);
	if (err != CL_SUCCESS) {
		printf("Error in clBuildProgram: %d, line %d.\n", err, __LINE__);
		char buffer[5000];
		clGetProgramBuildInfo(*program, device, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, NULL);
		printf("%s\n", buffer);
		return EXIT_FAILURE;
	}

	// dump ptx
	size_t binSize;
	clGetProgramInfo(*program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binSize, NULL);
	unsigned char *bin = malloc(binSize);
	clGetProgramInfo(*program, CL_PROGRAM_BINARIES, sizeof(unsigned char *), &bin, NULL);
	FILE *fp = fopen("openclPTX.ptx", "wb");
	fwrite(bin, sizeof(char), binSize, fp);
	fclose(fp);
	free(bin);

	free(numDevices);
	free(kernelSource);
	printf("\n");
	return EXIT_SUCCESS;
}
예제 #4
0
int main(int argc, char** argv)
{
    LOG_INFO("RiftRay version %s", pRiftRayVersion);
#if defined(_WIN32)
    LOG_INFO("Windows build.");
#elif defined(_LINUX)
    LOG_INFO("Linux build.");
#elif defined(_MACOS)
    LOG_INFO("MacOS build.");
#endif

    bool useOpenGLCoreContext = false;

    g_renderMode.outputType = RenderingMode::OVR_SDK;

#ifdef USE_CORE_CONTEXT
    useOpenGLCoreContext = true;
#endif

#ifdef _LINUX
    // Linux driver seems to be lagging a bit
    useOpenGLCoreContext = false;
#endif

    LOG_INFO("Using GLFW3 backend.");
    LOG_INFO("Compiled against GLFW %i.%i.%i",
        GLFW_VERSION_MAJOR,
        GLFW_VERSION_MINOR,
        GLFW_VERSION_REVISION);
    int major, minor, revision;
    glfwGetVersion(&major, &minor, &revision);
    LOG_INFO("Running against GLFW %i.%i.%i", major, minor, revision);
    LOG_INFO("glfwGetVersionString: %s", glfwGetVersionString());

    // Command line options
    for (int i=0; i<argc; ++i)
    {
        const std::string a = argv[i];
        LOG_INFO("argv[%d]: %s", i, a.c_str());
        if (!a.compare("-sdk"))
        {
            g_renderMode.outputType = RenderingMode::OVR_SDK;
        }
        else if (!a.compare("-client"))
        {
            g_renderMode.outputType = RenderingMode::OVR_Client;
        }
        else if (!a.compare("-core"))
        {
            useOpenGLCoreContext = true;
        }
        else if (!a.compare("-compat"))
        {
            useOpenGLCoreContext = false;
        }
    }

    LoadConfigFile();

    g_app.initHMD();

    GLFWwindow* l_Window = NULL;
    glfwSetErrorCallback(ErrorCallback);
    if (!glfwInit())
    {
        exit(EXIT_FAILURE);
    }

#ifdef __APPLE__
    // Set the working directory to the Resources dir of the .app bundle
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
    char path[PATH_MAX];
    CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX);
    CFRelease(resourcesURL);
    strcat( path, "/shaders" );
    struct stat sb;
    if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode))
        chdir(path);
#endif

#ifndef _LINUX
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
#  if defined(_MACOS)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#  else
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
#  endif
#endif //ndef _LINUX
    if (useOpenGLCoreContext)
    {
        LOG_INFO("Using OpenGL core context.");
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    }
    else
    {
#ifndef _LINUX
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
#endif
    }

    glfwWindowHint(GLFW_SAMPLES, 0);
#ifdef _DEBUG
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
#endif

    std::string windowTitle = "RiftRay-v" + std::string(pRiftRayVersion);
#ifdef USE_OCULUSSDK
    const ovrSizei sz = g_app.getHmdResolution();
    const ovrVector2i pos = g_app.getHmdWindowPos();

    if (g_app.UsingDebugHmd() == true)
    {
        // Create a normal, decorated application window
        LOG_INFO("Using Debug HMD mode.");
        windowTitle += "-GLFW-DebugHMD";

        l_Window = glfwCreateWindow(sz.w, sz.h, windowTitle.c_str(), NULL, NULL);
        g_app.m_dashScene.m_bDraw = false;
        g_renderMode.outputType = RenderingMode::Mono_Buffered;
    }
    else if (g_app.UsingDirectMode())
    {
        LOG_INFO("Using Direct to Rift mode.");
        windowTitle += "-GLFW-Direct";

        l_Window = glfwCreateWindow(sz.w, sz.h, windowTitle.c_str(), NULL, NULL);

#if defined(_WIN32)
        g_app.AttachToWindow((void*)glfwGetWin32Window(l_Window));
#endif
    }
    else
    {
        LOG_INFO("Using Extended desktop mode.");
        windowTitle += "-GLFW-Extended";

        glfwWindowHint(GLFW_DECORATED, 0);
        l_Window = glfwCreateWindow(sz.w, sz.h, windowTitle.c_str(), NULL, NULL);
        glfwWindowHint(GLFW_DECORATED, 1);
        glfwSetWindowPos(l_Window, pos.x, pos.y);
    }

    resize(l_Window, sz.w, sz.h); // inform AppSkeleton of window size

#else
    const glm::vec2 sz(800, 600);
    // Create a normal, decorated application window
    LOG_INFO("Using No VR SDK.");
    windowTitle += "-GLFW-NoVRSDK";
    g_renderMode.outputType = RenderingMode::Mono_Buffered;

    l_Window = glfwCreateWindow(sz.x, sz.y, windowTitle.c_str(), NULL, NULL);
    resize(l_Window, sz.x, sz.y); // inform AppSkeleton of window size
#endif //USE_OSVR|USE_OCULUSSDK

    if (!l_Window)
    {
        LOG_INFO("Glfw failed to create a window. Exiting.");
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

#ifdef USE_OCULUSSDK
    // Required for SDK rendering (to do the buffer swap on its own)
#  if defined(_WIN32)
    g_app.setWindow(glfwGetWin32Window(l_Window));
#  elif defined(__linux__)
    g_app.setWindow(glfwGetX11Display());
#  endif
#endif

    glfwMakeContextCurrent(l_Window);
    glfwSetWindowSizeCallback(l_Window, resize);
    glfwSetMouseButtonCallback(l_Window, mouseDown);
    glfwSetCursorPosCallback(l_Window, mouseMove);
    glfwSetScrollCallback(l_Window, mouseWheel);
    glfwSetKeyCallback(l_Window, keyboard);

    memset(m_keyStates, 0, GLFW_KEY_LAST*sizeof(int));

    FindPreferredJoystick();

    // Log system monitor information
    const GLFWmonitor* pPrimary = glfwGetPrimaryMonitor();
    int monitorCount = 0;
    GLFWmonitor** ppMonitors = glfwGetMonitors(&monitorCount);
    for (int i=0; i<monitorCount; ++i)
    {
        GLFWmonitor* pCur = ppMonitors[i];
        const GLFWvidmode* mode = glfwGetVideoMode(pCur);
        if (mode != NULL)
        {
            LOG_INFO("Monitor #%d: %dx%d @ %dHz %s",
                i,
                mode->width,
                mode->height,
                mode->refreshRate,
                pCur==pPrimary ? "Primary":"");
        }
    }

    printGLContextInfo(l_Window);
    glfwMakeContextCurrent(l_Window);
    g_pHMDWindow = l_Window;


    // Don't forget to initialize Glew, turn glewExperimental on to
    // avoid problems fetching function pointers...
    glewExperimental = GL_TRUE;
    const GLenum l_Result = glewInit();
    if (l_Result != GLEW_OK)
    {
        LOG_INFO("glewInit() error.");
        exit(EXIT_FAILURE);
    }

#ifdef _DEBUG
    // Debug callback initialization
    // Must be done *after* glew initialization.
    glDebugMessageCallback(myCallback, NULL);
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
    glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
        GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Start debugging");
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
#endif

#ifdef USE_ANTTWEAKBAR
    LOG_INFO("Using AntTweakbar.");
    TwInit(useOpenGLCoreContext ? TW_OPENGL_CORE : TW_OPENGL, NULL);
    InitializeBar();
#endif

    LOG_INFO("Calling initGL...");
    g_app.initGL();
    LOG_INFO("Calling initVR...");
    g_app.initVR();
    LOG_INFO("initVR complete.");

    SetVsync(1); // default to vsync on

    StartShaderLoad();

    while (!glfwWindowShouldClose(l_Window))
    {
        const bool tapped = g_app.CheckForTapOnHmd();
        if (tapped && (g_receivedFirstTap == false))
        {
            g_app.RecenterPose();
            g_receivedFirstTap = true;
        }

        glfwPollEvents();
        joystick();
        timestep();
        g_fps.OnFrame();
        if (g_dynamicallyScaleFBO)
        {
            DynamicallyScaleFBO();
        }

#ifdef USE_ANTTWEAKBAR
        TwRefreshBar(g_pTweakbar);
        TwRefreshBar(g_pShaderTweakbar);
#endif

        displayToHMD();

#ifndef _LINUX
        // Indicate FPS in window title
        // This is absolute death for performance in Ubuntu Linux 12.04
        {
            std::ostringstream oss;
            oss << windowTitle
                << " "
                << static_cast<int>(g_fps.GetFPS())
                << " fps";
            glfwSetWindowTitle(l_Window, oss.str().c_str());
            if (g_AuxWindow != NULL)
                glfwSetWindowTitle(g_AuxWindow, oss.str().c_str());
        }
#endif
        const float dumpInterval = 1.f;
        if (g_logDumpTimer.seconds() > dumpInterval)
        {
            LOG_INFO("Frame rate: %d fps", static_cast<int>(g_fps.GetFPS()));
            g_logDumpTimer.reset();
        }

        // Optionally display to auxiliary mono view
        if (g_AuxWindow != NULL)
        {
            glfwMakeContextCurrent(g_AuxWindow);
            glClearColor(0.f, 0.f, 0.f, 0.f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            ///@note VAOs *cannot* be shared between contexts.
            ///@note GLFW windows are inextricably tied to their own unique context.
            /// For these two reasons, calling draw a third time for the auxiliary window
            /// is not possible. Furthermore, it is not strictly desirable for the extra
            /// rendering cost.
            /// Instead, we share the render target texture from the stereo render and present
            /// just the left eye to the aux window.
            if (g_drawToAuxWindow)
            {
                presentSharedFboTexture();
            }

#ifdef USE_ANTTWEAKBAR
            TwDraw(); ///@todo Should this go first? Will it write to a depth buffer?
#endif

            glfwSwapBuffers(g_AuxWindow);

            if (glfwWindowShouldClose(g_AuxWindow))
            {
                destroyAuxiliaryWindow(g_AuxWindow);
            }

            // Set context to Rift window when done
            glfwMakeContextCurrent(l_Window);
        }
    }

    g_app.exitVR();
    glfwDestroyWindow(l_Window);
    glfwTerminate();

    exit(EXIT_SUCCESS);
}
예제 #5
0
int main(int argc, char** argv){
  cl_int err;


  // START OPENGL INIT

  Magick::InitializeMagick(argv[0]);
  // start GL context and O/S window using the GLFW helper library
  if (!glfwInit ()) {
    fprintf (stderr, "ERROR: could not start GLFW3\n");
    return 1;
  }
  // Demand OpenGL 4.1
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

  #ifdef __APPLE__
  // Use Core profile to obtain a context for the latest OpenGL spec.
  // Otherwise we're stuck at 2.1
  std::cout<<"Apple FTW\n";
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  #endif




  window = glfwCreateWindow (WIDTH, HEIGHT, "Hello Triangle", NULL, NULL);
  if (!window) {
    fprintf (stderr, "ERROR: could not open window with GLFW3\n");
    glfwTerminate();
    return 1;
  }
  glfwSetWindowSize( window, WIDTH/2 , HEIGHT/2);

  //glfwWindowHint(GLFW_SAMPLES, 4);
  //glEnable( GL_MULTISAMPLE );

  glfwMakeContextCurrent (window);
  checkGLErr( "glfwMakeContextCurrent" );
  // start GLEW extension handler
  glewExperimental = GL_TRUE;
  glewInit();
  glGetError();
  //checkGLErr( "GLEW init" );



  // END OPENGL INIT..

  // START OPENCL..
  std::vector<cl::Platform> platformList;
  cl::Platform::get(&platformList);

  checkErr(platformList.size()!=0 ? CL_SUCCESS : -1, "cl::Platform::get");

  std::cerr << "Platform number is: " << platformList.size() << std::endl;
  std::string platformVendor;

  platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
  std::cerr << "Platform is by: " << platformVendor << "\n";

  #ifdef __APPLE__
  CGLContextObj kCGLContext = CGLGetCurrentContext();
  CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
  cl_context_properties cprops[6] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(),CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE , (cl_context_properties) kCGLShareGroup, 0, 0};
  cl::Context context( CL_DEVICE_TYPE_CPU, cprops, NULL, NULL, &err);
  #endif

  #ifdef __linux__
    cl_platform_id platform;
    err = clGetPlatformIDs(1, &platform, NULL);
    cl_context_properties props[] =
    {
    	CL_GL_CONTEXT_KHR, (cl_context_properties)glfwGetGLXContext( window ),
    	CL_GLX_DISPLAY_KHR, (cl_context_properties)glfwGetX11Display(),
    	CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
    	0
    };
    cl::Context context( CL_DEVICE_TYPE_CPU, props, NULL, NULL, &err);
  //cl::Context context = clCreateContextFromType(props, CL_DEVICE_TYPE_CPU, NULL, NULL, &err);
  #endif


  checkErr(err, "Context::Context()");

  std::cout<<"Created context."<< std::endl;

  // Create shared texture.
  pCLTarget = new RenderTarget( WIDTH, HEIGHT, GL_RGBA , GL_RGBA, GL_FLOAT, 0, false );
  checkGLErr( "RenderTarget::RenderTarget" );
  pAccumulator = new RenderTarget( WIDTH, HEIGHT, GL_RGBA, GL_RGBA, GL_FLOAT, 0, false );
  checkGLErr( "RenderTarget::RenderTarget" );

  const int inSizeS = 3;
  const int inSizeP = 0;
  const int inSizeT = 12;
  const int inSurf = 5;

  /*
  float* outH = new float[inSize];
  cl::Buffer outCL( context, CL_MEM_WRITE_ONLY, inSize * sizeof( float ) );
  */
  Sphere* spheres = new Sphere[inSizeS];
  std::cout<<"Sphere: "<< spheres[0].radius << "\n";
  spheres[1].uSurf = 0;
  spheres[1].center = glm::vec4( 0.0f, -2.0f, 0.0f, 0.0f );
  spheres[1].radius = 1.0f;
  /*spheres[1].uSurf = 0;
  spheres[1].center = glm::vec4( +1.0f, 0.0f, +1.0f, 0.0f);
  spheres[1].radius = 1.0f;*/

  spheres[0].uSurf = 2;
  spheres[0].center = glm::vec4( 0.0f, +1.50f, 0.0f, 0.0f);
  spheres[0].radius = 0.2f;

  /*spheres[2].uSurf = 0;
  spheres[2].center = glm::vec4( +0.0f, 0.0f, -0.0f, 0.0f);
  spheres[2].radius = 1.0f;*/

  spheres[2].uSurf = 0;
  spheres[2].center = glm::vec4( -2.0f, -2.0f, -2.0f, 0.0f);
  spheres[2].radius = 1.0f;

  /*spheres[4].uSurf = 0;
  spheres[4].center = glm::vec4( -1.0f, -0.0f, +1.0f, 0.0f);
  spheres[4].radius = 1.0f;*/
  Plane* planes = new Plane[inSizeP];
  int planeSize = 3.0f;
  //std::cout<<"Sphere: "<< planes[0].radius << "\n";
  /*planes[0].normal = glm::vec4( 0.0f, 1.0f, 0.0f, 0.0f );
  planes[0].point = glm::vec4( 0.0f, -planeSize, 0.0f, 0.0f );
  planes[0].uSurf = 1;
  
  planes[1].normal = glm::vec4( 0.0f, -1.0f, 0.0f, 0.0f );
  planes[1].point = glm::vec4( 0.0f, planeSize, 0.0f, 0.0f );
  planes[1].uSurf = 1;
  
  planes[2].normal = glm::vec4( 1.0f, 0.0f, 0.0f, 0.0f );
  planes[2].point = glm::vec4( -planeSize, 0.0f, 0.0f, 0.0f );
  planes[2].uSurf = 1;
  
  planes[3].normal = glm::vec4( -1.0f, 0.0f, 0.0f, 0.0f );
  planes[3].point = glm::vec4( planeSize, 0.0f, 0.0f, 0.0f );
  planes[3].uSurf = 1;
  
  planes[4].normal = glm::vec4( 0.0f, 0.0f, +1.0f, +0.0f );
  planes[4].point = glm::vec4( 0.0f, 0.0f, -planeSize, 0.0f );
  planes[4].uSurf = 1;
  
  planes[5].normal = glm::vec4( 0.0f, 0.0f, -1.0f, 0.0f );
  planes[5].point = glm::vec4( 0.0f, 0.0f, +planeSize, 0.0f );
  planes[5].uSurf = 1;*/
  
  

  Triangle* triangles = new Triangle[inSizeT];
  //std::cout<<"Sphere: "<< spheres[0].radius << "\n";
  float boxSize = 3.0f;
  triangles[0].uSurf = 1;
  triangles[0].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f);
  triangles[0].p1 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f);
  triangles[0].p2 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f);
  
  triangles[1].uSurf = 1;
  triangles[1].p0 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f);
  triangles[1].p2 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f);
  triangles[1].p1 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f);
  
  triangles[2].uSurf = 1;
  triangles[2].p0 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f);
  triangles[2].p2 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f);
  triangles[2].p1 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f);
  
  triangles[3].uSurf = 1;
  triangles[3].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f);
  triangles[3].p1 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f);
  triangles[3].p2 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f);
  

  triangles[4].uSurf = 1;
  triangles[4].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f);
  triangles[4].p2 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f);
  triangles[4].p1 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f);
  
  triangles[5].uSurf = 1;
  triangles[5].p0 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f);
  triangles[5].p1 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f);
  triangles[5].p2 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f);
  
  triangles[6].uSurf = 1;
  triangles[6].p0 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f);
  triangles[6].p1 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f);
  triangles[6].p2 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f);
  
  triangles[7].uSurf = 1;
  triangles[7].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f);
  triangles[7].p2 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f);
  triangles[7].p1 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f);
  
  triangles[8].uSurf = 3;
  triangles[8].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f);
  triangles[8].p1 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f);
  triangles[8].p2 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f);
  
  triangles[9].uSurf = 3;
  triangles[9].p0 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f);
  triangles[9].p2 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f);
  triangles[9].p1 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f);
  
  triangles[10].uSurf = 4;
  triangles[10].p0 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f);
  triangles[10].p2 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f);
  triangles[10].p1 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f);
  
  triangles[11].uSurf = 4;
  triangles[11].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f);
  triangles[11].p1 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f);
  triangles[11].p2 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f);
  
  /*triangles[12].uSurf = 1;
  triangles[12].p0 = glm::vec4( -boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f);
  triangles[12].p1 = glm::vec4( boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f);
  triangles[12].p2 = glm::vec4( -boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f);
  
  triangles[13].uSurf = 1;
  triangles[13].p0 = glm::vec4( boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f);
  triangles[13].p2 = glm::vec4( boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f);
  triangles[13].p1 = glm::vec4( -boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f);*/
  
  
  

  GeometryDescriptor* geometry = new GeometryDescriptor( inSizeS, inSizeP, inSizeT );

  Surface* pSurf = new Surface[inSurf];
  pSurf[0].vColor = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f );
  
  pSurf[1].vColor = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f );
  
  pSurf[2].vColor = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f );
  float lPower = 5.0f;
  pSurf[2].vEmissive = glm::vec4( lPower, lPower, lPower, lPower );
  
  pSurf[3].vColor = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f );
  
  pSurf[4].vColor = glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f );

  cl::Buffer clSpheres( context, CL_MEM_READ_ONLY, inSizeS * sizeof( Sphere ));
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clPlanes( context, CL_MEM_READ_ONLY, inSizeP * sizeof( Plane ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clTriangles( context, CL_MEM_READ_ONLY, inSizeT * sizeof( Triangle ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clCamera( context, CL_MEM_READ_ONLY, 1 * sizeof( CLCamera ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clGeom( context, CL_MEM_READ_ONLY, 1 * sizeof( GeometryDescriptor ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clImgDesc( context, CL_MEM_READ_ONLY, 1 * sizeof( ImageDescriptor ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clSeed( context, CL_MEM_READ_WRITE, WIDTH * HEIGHT * 4 * sizeof( uint ) );
  checkErr(err, "Buffer::Buffer()");

  cl::Buffer clSurf( context, CL_MEM_READ_WRITE, inSurf * sizeof( Surface ) );
  checkErr(err, "Buffer::Buffer()");

  cl::ImageGL imgGL( context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, pCLTarget->getColorTexture()->glGetInternalTexture(), &err );
  checkErr(err, "ImageGL::ImageGL()");

  cl::ImageGL accGL( context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, pAccumulator->getColorTexture()->glGetInternalTexture(), &err );
  checkErr(err, "ImageGL::ImageGL()");

  std::cout<<"Created buffers."<< std::endl;

  srand( time( NULL ) );
  uint *pSeeds = new uint[WIDTH * HEIGHT * 4];
  for( int i = 0; i < WIDTH * HEIGHT * 4; i++ ){
    pSeeds[i] = rand();
  }

  std::vector<cl::Device> devices;
  devices = context.getInfo<CL_CONTEXT_DEVICES>();
  checkErr(devices.size() > 0 ? CL_SUCCESS : -1, "devices.size() > 0");

  std::cout<<"Num available devices: "<< devices.size()<< std::endl;

  std::ifstream file("src/kernel/kernel0.cl");
  checkErr(file.is_open() ? CL_SUCCESS:-1, "src/kernel/kernel0.cl");
  std::string prog( std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));

  cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length()+1));

  std::cout<<"Source obtained."<< std::endl;
  
  cl::Program program(context, source);
  err = program.build(devices,"-cl-opt-disable");
  std::cout<<"Source obtained."<< std::endl;

  std::string buildLog;
  program.getBuildInfo( devices[0], CL_PROGRAM_BUILD_LOG, &buildLog );
  std::cout<<"Build log:" << buildLog<< std::endl;
  checkErr(err, "Program::build()");
  std::cout<<"Built program"<< std::endl;

  cl::Kernel kernel(program, "bi_directional_path_trace", &err);
  checkErr(err, "Kernel::Kernel()");

  err = kernel.setArg(0, clCamera);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(1, imgGL);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(2, accGL);
  checkErr(err, "Kernel::setArg()");

  err = kernel.setArg(3, clSpheres);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(4, clPlanes);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(5, clTriangles);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(6, clGeom);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(7, clImgDesc);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(8, clSeed);
  checkErr(err, "Kernel::setArg()");
  err = kernel.setArg(9, clSurf);
  checkErr(err, "Kernel::setArg()");

  std::cout<<"Built Kernel"<< std::endl;

  pCamera = new ModelCamera( window );
  pCamera->setSpeedX( 0.03f );
  pCamera->setSpeedY( 0.03f );

  pCamera->setRadius( 8.0f );
  pCamera->setOrientation( glm::vec3( 0.0f, -1.0f, 0.0f ) );
  pCamera->reset( glm::vec3( 1.0f, 0.1f, -0.1f ) );


  cl::CommandQueue queue(context, devices[0], 0, &err);
  checkErr(err, "CommandQueue::CommandQueue()");
  CLCamera* cam = pCamera->getCLCamera();

  std::cout<<cam->vPos.x<<","<<cam->vPos.y<<","<<cam->vPos.z<<std::endl;

  std::cout<<cam->vLookAt.x<<","<<cam->vLookAt.y<<","<<cam->vLookAt.z<<std::endl;

  std::cout<<cam->vUp.x<<","<<cam->vUp.y<<","<<cam->vUp.z<<std::endl;

  std::cout<< sizeof( Plane )<< std::endl;
  queue.enqueueWriteBuffer( clCamera, CL_TRUE, 0, 1 * sizeof(CLCamera), (const void*)cam );
  queue.enqueueWriteBuffer( clSpheres, CL_TRUE, 0, inSizeS * sizeof(Sphere), (const void*)spheres);
  queue.enqueueWriteBuffer( clPlanes, CL_TRUE, 0, inSizeP * sizeof(Plane), (const void*)planes);
  queue.enqueueWriteBuffer( clTriangles, CL_TRUE, 0, inSizeT * sizeof(Triangle), (const void*)triangles);
  queue.enqueueWriteBuffer( clGeom, CL_TRUE, 0, 1 * sizeof(GeometryDescriptor), (const void*)geometry);
  queue.enqueueWriteBuffer( clSeed, CL_TRUE, 0, WIDTH * HEIGHT * 4 * sizeof(uint), (const void*)pSeeds);
  queue.enqueueWriteBuffer( clSurf, CL_TRUE, 0, inSurf * sizeof(Surface), (const void*)pSurf);

  vSharedUnits = new std::vector<cl::Memory>();
  vSharedUnits->push_back( imgGL );
  vSharedUnits->push_back( accGL );

  //Initialise counter.
  imgDesc.numSamples = 0;
  imgDesc.sampleRate = SAMPLES;
  cLast = clock();
  while( !glfwWindowShouldClose( window ) ){
    //usleep( 1000000 );
    mainLoop( queue, context, kernel, clImgDesc, clCamera );
  }

  /* Previous Program. Remove these if you think they are not required.
  float *fout = new float[inSize];
  err = queue.enqueueReadBuffer( clSpheres, CL_TRUE, 0, inSize * sizeof(Sphere), fout);
  */
  checkErr(err, "ComamndQueue::enqueueReadBuffer()");

  std::cout<<"Kernel finished executing."<< std::endl;

  delete vSharedUnits;
  return EXIT_SUCCESS;
}
예제 #6
0
OculusManager& OculusManager::getOculusManager()
{

	static OculusManager* oculusManager = NULL;

	if (oculusManager == NULL)
	{
		oculusManager = new OculusManager();
		if (!ovr_Initialize()) {
			fprintf(stderr, "Failed to initialize the Oculus SDK");
		}

		//= *OculusManager::getHmd();

		g_Hmd = ovrHmd_Create(0);
		if (!g_Hmd)
		{
			printf("No Oculus Rift device attached, using virtual version...\n");
			g_Hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
		}
		printf("initialized HMD: %s - %s\n", g_Hmd->Manufacturer, g_Hmd->ProductName);

		if (!glfwInit()) exit(EXIT_FAILURE);

		if (l_MultiSampling) glfwWindowHint(GLFW_SAMPLES, 4); else glfwWindowHint(GLFW_SAMPLES, 0);

		bool l_DirectMode = ((g_Hmd->HmdCaps & ovrHmdCap_ExtendDesktop) == 0);

		GLFWmonitor* l_Monitor;
		ovrSizei l_ClientSize;
		if (l_DirectMode)
		{
			printf("Running in \"Direct\" mode...\n");
			l_Monitor = NULL;

			l_ClientSize.w = g_Hmd->Resolution.w / 2; // Something reasonable, smaller, but maintain aspect ratio...
			l_ClientSize.h = g_Hmd->Resolution.h / 2; // Something reasonable, smaller, but maintain aspect ratio...
		}
		else // Extended Desktop mode...
		{
			printf("Running in \"Extended Desktop\" mode...\n");
			int l_Count;
			GLFWmonitor** l_Monitors = glfwGetMonitors(&l_Count);
			switch (l_Count)
			{
			case 0:
				printf("No monitors found, exiting...\n");
				exit(EXIT_FAILURE);
				break;
			case 1:
				printf("Two monitors expected, found only one, using primary...\n");
				l_Monitor = glfwGetPrimaryMonitor();
				break;
			case 2:
				printf("Two monitors found, using second monitor...\n");
				l_Monitor = l_Monitors[1];
				break;
			default:
				printf("More than two monitors found, using second monitor...\n");
				l_Monitor = l_Monitors[1];
			}

			l_ClientSize.w = g_Hmd->Resolution.w; // 1920 for DK2...
			l_ClientSize.h = g_Hmd->Resolution.h; // 1080 for DK2...
		}

		l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", l_Monitor, NULL);

		if (!l_Window)
		{
			glfwTerminate();
			exit(EXIT_FAILURE);
		}

#if defined(_WIN32)
		if (l_DirectMode)
		{
			ovrBool l_AttachResult = ovrHmd_AttachToWindow(g_Hmd, glfwGetWin32Window(l_Window), NULL, NULL);
			if (!l_AttachResult)
			{
				printf("Could not attach to window...");
				exit(EXIT_FAILURE);
			}
		}
#endif

		glfwMakeContextCurrent(l_Window);

		glewExperimental = GL_TRUE;
		GLenum l_GlewResult = glewInit();
		if (l_GlewResult != GLEW_OK)
		{
			printf("glewInit() error.\n");
			exit(EXIT_FAILURE);
		}

		int l_Major = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MAJOR);
		int l_Minor = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MINOR);
		int l_Profile = glfwGetWindowAttrib(l_Window, GLFW_OPENGL_PROFILE);
		printf("OpenGL: %d.%d ", l_Major, l_Minor);
		if (l_Major >= 3) // Profiles introduced in OpenGL 3.0...
		{
			if (l_Profile == GLFW_OPENGL_COMPAT_PROFILE) printf("GLFW_OPENGL_COMPAT_PROFILE\n"); else printf("GLFW_OPENGL_CORE_PROFILE\n");
		}
		printf("Vendor: %s\n", (char*)glGetString(GL_VENDOR));
		printf("Renderer: %s\n", (char*)glGetString(GL_RENDERER));

		ovrSizei l_EyeTextureSizes[2];

		l_EyeTextureSizes[ovrEye_Left] = ovrHmd_GetFovTextureSize(g_Hmd, ovrEye_Left, g_Hmd->MaxEyeFov[ovrEye_Left], 1.0f);
		l_EyeTextureSizes[ovrEye_Right] = ovrHmd_GetFovTextureSize(g_Hmd, ovrEye_Right, g_Hmd->MaxEyeFov[ovrEye_Right], 1.0f);

		// Combine for one texture for both eyes...
		g_RenderTargetSize.w = l_EyeTextureSizes[ovrEye_Left].w + l_EyeTextureSizes[ovrEye_Right].w;
		g_RenderTargetSize.h = (l_EyeTextureSizes[ovrEye_Left].h > l_EyeTextureSizes[ovrEye_Right].h ? l_EyeTextureSizes[ovrEye_Left].h : l_EyeTextureSizes[ovrEye_Right].h);

		// Create the FBO being a single one for both eyes (this is open for debate)...
		glGenFramebuffers(1, &l_FBOId);
		glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);

		// The texture we're going to render to...
		glGenTextures(1, &l_TextureId);
		// "Bind" the newly created texture : all future texture functions will modify this texture...
		glBindTexture(GL_TEXTURE_2D, l_TextureId);
		// Give an empty image to OpenGL (the last "0")
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_RenderTargetSize.w, g_RenderTargetSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
		// Linear filtering...
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

		// Create Depth Buffer...
		glGenRenderbuffers(1, &l_DepthBufferId);
		glBindRenderbuffer(GL_RENDERBUFFER, l_DepthBufferId);
		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, g_RenderTargetSize.w, g_RenderTargetSize.h);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, l_DepthBufferId);

		// Set the texture as our colour attachment #0...
		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, l_TextureId, 0);

		// Set the list of draw buffers...
		GLenum l_GLDrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
		glDrawBuffers(1, l_GLDrawBuffers); // "1" is the size of DrawBuffers

		// Check if everything is OK...
		GLenum l_Check = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
		if (l_Check != GL_FRAMEBUFFER_COMPLETE)
		{
			printf("There is a problem with the FBO.\n");
			exit(EXIT_FAILURE);
		}

		// Unbind...
		glBindRenderbuffer(GL_RENDERBUFFER, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);

		// Setup textures for each eye...

		// Left eye...
		g_EyeTextures[ovrEye_Left].Header.API = ovrRenderAPI_OpenGL;
		g_EyeTextures[ovrEye_Left].Header.TextureSize = g_RenderTargetSize;
		g_EyeTextures[ovrEye_Left].Header.RenderViewport.Pos.x = 0;
		g_EyeTextures[ovrEye_Left].Header.RenderViewport.Pos.y = 0;
		g_EyeTextures[ovrEye_Left].Header.RenderViewport.Size = l_EyeTextureSizes[ovrEye_Left];
		((ovrGLTexture&)(g_EyeTextures[ovrEye_Left])).OGL.TexId = l_TextureId;

		// Right eye (mostly the same as left but with the viewport on the right side of the texture)...
		g_EyeTextures[ovrEye_Right] = g_EyeTextures[ovrEye_Left];
		g_EyeTextures[ovrEye_Right].Header.RenderViewport.Pos.x = (g_RenderTargetSize.w + 1) / 2;
		g_EyeTextures[ovrEye_Right].Header.RenderViewport.Pos.y = 0;

		// Oculus Rift eye configurations...
		g_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
		g_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
		g_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
		g_Cfg.OGL.Header.Multisample = (l_MultiSampling ? 1 : 0);
#if defined(_WIN32)
		g_Cfg.OGL.Window = glfwGetWin32Window(l_Window);
		g_Cfg.OGL.DC = GetDC(g_Cfg.OGL.Window);
#elif defined(__linux__)
		l_Cfg.OGL.Win = glfwGetX11Window(l_Window);
		l_Cfg.OGL.Disp = glfwGetX11Display();
#endif

		// Enable capabilities...
		// ovrHmd_SetEnabledCaps(g_Hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);

		ovrBool l_ConfigureResult = ovrHmd_ConfigureRendering(g_Hmd, &g_Cfg.Config, g_DistortionCaps, g_Hmd->MaxEyeFov, g_EyeRenderDesc);
		glUseProgram(0); // Avoid OpenGL state leak in ovrHmd_ConfigureRendering...
		if (!l_ConfigureResult)
		{
			printf("Configure failed.\n");
			exit(EXIT_FAILURE);
		}

		// Start the sensor which provides the Rift’s pose and motion...
		uint32_t l_SupportedSensorCaps = ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position;
		uint32_t l_RequiredTrackingCaps = 0;
		ovrBool l_TrackingResult = ovrHmd_ConfigureTracking(g_Hmd, l_SupportedSensorCaps, l_RequiredTrackingCaps);
		if (!l_TrackingResult)
		{
			printf("Could not start tracking...");
			exit(EXIT_FAILURE);
		}

		// Projection matrici for each eye will not change at runtime, we can set them here...
		g_ProjectionMatrici[ovrEye_Left] = ovrMatrix4f_Projection(g_EyeRenderDesc[ovrEye_Left].Fov, 0.3f, 100.0f, true);
		g_ProjectionMatrici[ovrEye_Right] = ovrMatrix4f_Projection(g_EyeRenderDesc[ovrEye_Right].Fov, 0.3f, 100.0f, true);

		// IPD offset values will not change at runtime, we can set them here...
		g_EyeOffsets[ovrEye_Left] = g_EyeRenderDesc[ovrEye_Left].HmdToEyeViewOffset;
		g_EyeOffsets[ovrEye_Right] = g_EyeRenderDesc[ovrEye_Right].HmdToEyeViewOffset;

		ovrHmd_RecenterPose(g_Hmd);


		return *oculusManager;
	}
}