diff options
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/opengl/OpenGLHelper.cxx | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx new file mode 100644 index 000000000000..75eefe7c1f3f --- /dev/null +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <vcl/opengl/OpenGLHelper.hxx> + +#include <osl/file.hxx> +#include <rtl/bootstrap.hxx> +#include <config_folders.h> + +#include <vector> + +namespace { + +OUString getShaderFolder() +{ + OUString aUrl("$BRAND_BASE_DIR/" LIBO_ETC_FOLDER); + rtl::Bootstrap::expandMacros(aUrl); + + return aUrl + "/opengl/"; +} + +OUString maShaderFolder = getShaderFolder(); + +OString loadShader(const OUString& rFilename) +{ + OUString aFileURL = maShaderFolder + rFilename +".glsl"; + osl::File aFile(aFileURL); + if(aFile.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None) + { + sal_uInt64 nSize = 0; + aFile.getSize(nSize); + char* content = new char[nSize+1]; + sal_uInt64 nBytesRead = 0; + aFile.read(content, nSize, nBytesRead); + if(nSize != nBytesRead) + assert(false); + + content[nSize] = 0; + return OString(content); + } + else + { + SAL_WARN("vcl.opengl", "could not load the file: " << aFileURL); + } + + return OString(); +} + +} + +GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName) +{ + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + OString aVertexShaderSource = loadShader(rVertexShaderName); + char const * VertexSourcePointer = aVertexShaderSource.getStr(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + if ( !Result ) + { + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ) + { + std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + VertexShaderErrorMessage.push_back('\0'); + SAL_WARN("vcl.opengl", "vertex shader compile failed : " << &VertexShaderErrorMessage[0]); + } + else + SAL_WARN("vcl.opengl", "vertex shader compile failed without error log"); + + return 0; + } + + // Compile Fragment Shader + OString aFragmentShaderSource = loadShader(rFragmentShaderName); + char const * FragmentSourcePointer = aFragmentShaderSource.getStr(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + if ( !Result ) + { + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ) + { + std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + FragmentShaderErrorMessage.push_back('\0'); + SAL_WARN("vcl.opengl", "fragment shader compile failed : " << &FragmentShaderErrorMessage[0]); + } + else + SAL_WARN("vcl.opengl", "fragment shader compile failed without error log"); + + + return 0; + } + + // Link the program + GLint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if ( !Result ) + { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ) + { + std::vector<char> ProgramErrorMessage(InfoLogLength+1); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + ProgramErrorMessage.push_back('\0'); + SAL_WARN("vcl.opengl", "Shader Program failed : " << &ProgramErrorMessage[0]); + } + else + SAL_WARN("vcl.opengl", "shader program link failed without error log"); + + return 0; + } + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |