Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
32c25444
Commit
32c25444
authored
Jan 27, 2010
by
Sebastian Eichelbaum
Browse files
[CHANGE] - removed old shader class and replaced by new one
parent
4e394aca
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
229 additions
and
559 deletions
+229
-559
src/graphicsEngine/WShader.cpp
src/graphicsEngine/WShader.cpp
+147
-91
src/graphicsEngine/WShader.h
src/graphicsEngine/WShader.h
+73
-53
src/graphicsEngine/WShader2.cpp
src/graphicsEngine/WShader2.cpp
+0
-237
src/graphicsEngine/WShader2.h
src/graphicsEngine/WShader2.h
+0
-169
src/modules/directVolumeRendering/WMDirectVolumeRendering.cpp
...modules/directVolumeRendering/WMDirectVolumeRendering.cpp
+1
-1
src/modules/marchingCubes/WMMarchingCubes.cpp
src/modules/marchingCubes/WMMarchingCubes.cpp
+2
-2
src/modules/marchingCubes/WMMarchingCubes.h
src/modules/marchingCubes/WMMarchingCubes.h
+2
-2
src/modules/navSlices/WMNavSlices.cpp
src/modules/navSlices/WMNavSlices.cpp
+2
-2
src/modules/navSlices/WMNavSlices.h
src/modules/navSlices/WMNavSlices.h
+2
-2
No files found.
src/graphicsEngine/WShader.cpp
View file @
32c25444
...
...
@@ -22,147 +22,204 @@
//
//---------------------------------------------------------------------------
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/regex.hpp>
#include "WShader.h"
#include <osg/StateSet>
#include <osg/Node>
#include "WGraphicsEngine.h"
#include "../common/WLogger.h"
WShader
::
WShader
()
#include "WShader.h"
WShader
::
WShader
(
std
::
string
name
)
:
osg
::
Program
(),
m_shaderPath
(
WGraphicsEngine
::
getGraphicsEngine
()
->
getShaderPath
()
),
m_name
(
name
),
m_reload
(
true
)
{
// create shader
m_vertexShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
VERTEX
)
);
m_fragmentShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
FRAGMENT
)
);
m_geometryShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
GEOMETRY
)
);
// add them
addShader
(
m_vertexShader
);
addShader
(
m_fragmentShader
);
addShader
(
m_geometryShader
);
}
WShader
::
WShader
(
std
::
string
fileName
,
std
::
string
shaderPath
)
:
m_shaderPath
(
shaderPath
)
WShader
::~
WShader
()
{
m_VertexObject
=
readShaderFromFile
(
fileName
+
".vs"
,
osg
::
Shader
::
VERTEX
);
m_FragmentObject
=
readShaderFromFile
(
fileName
+
".fs"
,
osg
::
Shader
::
FRAGMENT
);
m_ProgramObject
=
new
osg
::
Program
;
// cleanup
}
if
(
m_FragmentObject
)
{
m_ProgramObject
->
addShader
(
m_FragmentObject
);
}
void
WShader
::
apply
(
osg
::
ref_ptr
<
osg
::
Node
>
node
)
{
// set the shader attribute
osg
::
StateSet
*
rootState
=
node
->
getOrCreateStateSet
();
rootState
->
setAttributeAndModes
(
this
,
osg
::
StateAttribute
::
ON
);
if
(
m_VertexObject
)
{
m_ProgramObject
->
addShader
(
m_VertexObject
);
}
// add a custom callback which actually sets and updated the shader.
node
->
addUpdateCallback
(
osg
::
ref_ptr
<
SafeUpdaterCallback
>
(
new
SafeUpdaterCallback
(
this
)
)
);
}
WShader
::~
WShader
()
void
WShader
::
reload
()
{
m_reload
=
true
;
}
WShader
::
SafeUpdaterCallback
::
SafeUpdaterCallback
(
WShader
*
shader
)
:
m_shader
(
shader
)
{
}
osg
::
Shader
*
WShader
::
readShaderFromFile
(
std
::
string
fileName
,
osg
::
Shader
::
Type
type
)
void
WShader
::
SafeUpdaterCallback
::
operator
()(
osg
::
Node
*
node
,
osg
::
NodeVisitor
*
nv
)
{
std
::
string
fileText
=
readTextFile
(
fileName
);
// is it needed to do something here?
if
(
m_shader
->
m_reload
)
{
try
{
// remove the shaders
m_shader
->
removeShader
(
m_shader
->
m_vertexShader
);
m_shader
->
removeShader
(
m_shader
->
m_fragmentShader
);
m_shader
->
removeShader
(
m_shader
->
m_geometryShader
);
// reload the sources and set the shader
// vertex shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading vertex shader
\"
"
+
m_shader
->
m_name
+
".vs
\"
"
,
"WShader"
,
LL_DEBUG
);
std
::
string
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".vs"
);
if
(
source
!=
""
)
{
m_shader
->
m_vertexShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_vertexShader
);
}
// fragment shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading fragment shader
\"
"
+
m_shader
->
m_name
+
".fs
\"
"
,
"WShader"
,
LL_DEBUG
);
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".fs"
);
if
(
source
!=
""
)
{
m_shader
->
m_fragmentShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_fragmentShader
);
}
// Geometry Shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading geometry shader
\"
"
+
m_shader
->
m_name
+
".gs
\"
"
,
"WShader"
,
LL_DEBUG
);
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".gs"
,
true
);
if
(
source
!=
""
)
{
m_shader
->
m_geometryShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_geometryShader
);
}
}
catch
(
const
std
::
exception
&
e
)
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Problem loading shader."
,
"WShader"
,
LL_ERROR
);
// std::cout << "\n=====OW==SHADER============\n"
// << fileText
// << "\n=====OW==SHADER=END========\n"
// << std::endl;
// clean up the mess
m_shader
->
removeShader
(
m_shader
->
m_vertexShader
);
m_shader
->
removeShader
(
m_shader
->
m_fragmentShader
);
m_shader
->
removeShader
(
m_shader
->
m_geometryShader
);
}
osg
::
Shader
*
shader
=
new
osg
::
Shader
(
type
,
fileText
);
// everything done now.
m_shader
->
m_reload
=
false
;
}
return
shader
;
// forward the call
traverse
(
node
,
nv
);
}
std
::
string
WShader
::
readTextFile
(
std
::
string
fileName
)
std
::
string
WShader
::
processShader
(
const
std
::
string
filename
,
bool
optional
,
int
level
)
{
std
::
string
fileText
;
namespace
fs
=
boost
::
filesystem
;
std
::
stringstream
output
;
// processed output
std
::
ifstream
ifs
(
(
(
fs
::
path
(
m_shaderPath
)
/
fileName
).
file_string
()
).
c_str
()
)
;
//
std::ifstream ifs( ( m_shaderPath + fileName ).c_str() );
std
::
string
line
;
if
(
level
==
0
)
{
// for the shader (not the included one, for which level != 0)
std
::
map
<
std
::
string
,
float
>::
const_iterator
mi
=
m_defines
.
begin
();
// apply defines
std
::
map
<
std
::
string
,
float
>::
const_iterator
mi
=
m_defines
.
begin
();
while
(
mi
!=
m_defines
.
end
()
)
{
output
<<
"#define "
<<
mi
->
first
<<
" "
<<
boost
::
lexical_cast
<
std
::
string
,
float
>
(
mi
->
second
)
<<
std
::
endl
;
}
}
while
(
mi
!=
m_defines
.
end
()
)
// we encountered an endless loop
if
(
level
>
32
)
{
fileText
+=
"#define "
;
fileText
+=
mi
->
first
;
fileText
+=
" "
;
fileText
+=
boost
::
lexical_cast
<
std
::
string
,
float
>
(
mi
->
second
);
fileText
+=
'\n'
;
// reached a certain level. This normally denotes a inclusion cycle.
// We do not throw an exception here to avoid OSG to crash.
WLogger
::
getLogger
()
->
addLogMessage
(
"Inclusion depth is too large. Maybe there is a inclusion cycle in the shader code."
,
"WShader ("
+
filename
+
")"
,
LL_ERROR
);
// just return unprocessed source
return
""
;
}
while
(
getline
(
ifs
,
line
)
)
// this is the proper regular expression for includes. This also excludes commented includes
static
const
boost
::
regex
re
(
"^[ ]*#[ ]*include[ ]+[
\"
<](.*)[
\"
>].*"
);
// the input stream
std
::
string
fn
=
(
boost
::
filesystem
::
path
(
m_shaderPath
)
/
filename
).
file_string
();
std
::
ifstream
input
(
fn
.
c_str
()
);
if
(
!
input
.
is_open
()
)
{
if
(
isIncludeLine
(
line
)
)
if
(
optional
)
{
fileText
+=
readTextFile
(
getIncludeFileName
(
line
)
);
return
""
;
}
// file does not exists. Do not throw an exception to avoid OSG crash
if
(
level
==
0
)
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Can't open shader file
\"
"
+
fn
+
"
\"
."
,
"WShader ("
+
filename
+
")"
,
LL_ERROR
);
}
else
{
fileText
+=
line
;
fileText
+=
'\n'
;
WLogger
::
getLogger
()
->
addLogMessage
(
"Can't open shader file for inclusion
\"
"
+
fn
+
"
\"
."
,
"WShader ("
+
filename
+
")"
,
LL_ERROR
);
}
}
return
fileText
;
}
bool
WShader
::
isIncludeLine
(
std
::
string
line
)
{
if
(
line
[
0
]
==
'/'
&&
line
[
1
]
==
'/'
)
{
return
false
;
// we encountered a comment
return
""
;
}
if
(
boost
::
find_first
(
line
,
"#include"
)
)
{
return
true
;
}
return
false
;
}
// go through each line and process includes
std
::
string
line
;
// the current line
boost
::
smatch
matches
;
// the list of matches
std
::
string
WShader
::
getIncludeFileName
(
std
::
string
line
)
{
std
::
string
fileName
;
int
count
=
0
;
for
(
size_t
i
=
0
;
i
<
line
.
length
()
;
++
i
)
while
(
std
::
getline
(
input
,
line
)
)
{
if
(
line
[
i
]
==
'\"'
)
if
(
boost
::
regex_search
(
line
,
matches
,
re
)
)
{
++
count
;
output
<<
processShader
(
matches
[
1
],
false
,
level
+
1
);
}
else
{
output
<<
line
;
}
}
if
(
count
<
2
)
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Missing quotes around file name in include statement of shader."
,
"WShader"
,
LL_ERROR
);
// TODO(schurade): here we could throw an exception
return
0
;
}
typedef
boost
::
tokenizer
<
boost
::
char_separator
<
char
>
>
tokenizer
;
boost
::
char_separator
<
char
>
sep
(
"
\"
"
);
tokenizer
tok
(
line
,
sep
);
tokenizer
::
iterator
it
=
tok
.
begin
();
++
it
;
return
*
it
;
}
output
<<
std
::
endl
;
}
input
.
close
();
osg
::
Program
*
WShader
::
getProgramObject
()
{
return
m_ProgramObject
;
return
output
.
str
();
}
void
WShader
::
setDefine
(
std
::
string
key
,
float
value
)
...
...
@@ -173,7 +230,6 @@ void WShader::setDefine( std::string key, float value )
}
}
void
WShader
::
eraseDefine
(
std
::
string
key
)
{
m_defines
.
erase
(
key
);
...
...
src/graphicsEngine/WShader.h
View file @
32c25444
...
...
@@ -25,46 +25,45 @@
#ifndef WSHADER_H
#define WSHADER_H
#include <string>
#include <map>
#include <string>
#include <
osg/Geometry
>
#include <
boost/filesystem.hpp
>
#include <boost/shared_ptr.hpp>
#include <osg/Shader>
#include <osg/Program>
/**
* Class the encapsulates the loading and compiling of shader objects
* \ingroup ge
* Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
*/
class
WShader
class
WShader
:
public
osg
::
Program
{
public:
/**
* default constructor
*/
WShader
();
/**
* constructor
with initialization
*
Default
constructor
. Loads the specified shader programs.
*
* \param fileName the file name
* \param shaderPath path to the directory where all shader file are stored
* \param name the name of the shader. It gets searched in the shader path.
*/
WShader
(
std
::
string
fileName
,
std
::
string
shaderPath
);
explicit
WShader
(
std
::
string
name
);
/**
*
d
estructor
*
D
estructor
.
*/
virtual
~
WShader
();
/**
* Returns the OSG program object
* Apply this shader to the specified node. Use this method to ensure, that reload events can be handled properly during the
* update cycle.
*
* \return the program object
* \param node the node where the program should be registered to.
*/
virtual
void
apply
(
osg
::
ref_ptr
<
osg
::
Node
>
node
);
/**
* Initiate a reload of the shader during the next update cycle.
*/
osg
::
Program
*
getProgramObject
();
virtual
void
reload
();
/**
* Sets a define which is include into the shader source code.
...
...
@@ -82,68 +81,89 @@ public:
*/
void
eraseDefine
(
std
::
string
key
);
private:
protected:
/**
* Helper routine to load a shader program from a text file
* This method searches and processes all includes in the shader source. The filenames in the include statement are assumed to
* be relative to this shader's path.
*
* \return An osg shader
* \param filename the filename of the shader to process.
* \param optional denotes whether a "file not found" is critical or not
* \param level the inclusion level. This is used to avoid cycles.
*
* \param fileName the file name
* \param type The type of the shader, eg. Vertex or fragment shader
* \return the processed source.
*/
osg
::
Shader
*
readShaderFromFile
(
std
::
string
file
N
ame
,
osg
::
Shader
::
Type
type
);
std
::
string
processShader
(
const
std
::
string
file
n
ame
,
bool
optional
=
false
,
int
level
=
0
);
/**
* Helper routine to load a text file into a string
*
* \return String
*
* \param fileName The file name
* String that stores the location of all shader files
*/
std
::
string
readTextFile
(
std
::
string
fileName
)
;
std
::
string
m_shaderPath
;
/**
* Helper routine to test if a line contains an include statement
*
* \return true if line contains an include statement
*
* \param line a string with the line
* The name of the shader. It is used to construct the actual filename to load.
*/
bool
isIncludeLine
(
std
::
string
line
)
;
std
::
string
m_name
;
/**
* Parses a line with an include statement and returns the file name
*
* \return string with the file name
*
* \param line a string with the line
* Flag denoting whether a shader should be reloaded.
*/
std
::
string
getIncludeFileName
(
std
::
string
line
);
bool
m_reload
;
/**
*
String that stores the location
of all s
hader
fi
l
es
*
a map
of all s
et de
fi
n
es
*/
std
::
string
m_shaderPath
;
std
::
map
<
std
::
string
,
float
>
m_defines
;
/**
* the vertex shader object
*/
osg
::
Shader
*
m_
V
ertex
Object
;
osg
::
ref_ptr
<
osg
::
Shader
>
m_
v
ertex
Shader
;
/**
* the fragment shader object
*/
osg
::
Shader
*
m_
F
ragment
Object
;
osg
::
ref_ptr
<
osg
::
Shader
>
m_
f
ragment
Shader
;
/**
* the
shader program
* the
geometry shader object
*/
osg
::
Program
*
m_ProgramObject
;
osg
::
ref_ptr
<
osg
::
Shader
>
m_geometryShader
;
/**
* a map of all set defines
* Update callback which handles the shader reloading.
* This ensures thread safe modification of the osg node.
*/
std
::
map
<
std
::
string
,
float
>
m_defines
;
class
SafeUpdaterCallback
:
public
osg
::
NodeCallback
{
public:
/**
* Constructor. Creates a new callback.
*
* \param shader the shader which needs to be updated.
*/
explicit
SafeUpdaterCallback
(
WShader
*
shader
);
/**
* Callback method called by the NodeVisitor when visiting a node.
* This inserts and removes enqueued nodes from this group node instance.
*
* \param node the node calling this update
* \param nv The node visitor which performs the traversal. Should be an
* update visitor.
*/
virtual
void
operator
()(
osg
::
Node
*
node
,
osg
::
NodeVisitor
*
nv
);
protected:
/**
* The shader belonging to the node currently getting updated.
*/
WShader
*
m_shader
;
};
private:
};
#endif // WSHADER_H
src/graphicsEngine/WShader2.cpp
deleted
100644 → 0
View file @
4e394aca
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <map>
#include <string>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/regex.hpp>
#include <osg/StateSet>
#include <osg/Node>
#include "WGraphicsEngine.h"
#include "../common/WLogger.h"
#include "WShader2.h"
WShader2
::
WShader2
(
std
::
string
name
)
:
osg
::
Program
(),
m_shaderPath
(
WGraphicsEngine
::
getGraphicsEngine
()
->
getShaderPath
()
),
m_name
(
name
),
m_reload
(
true
)
{
// create shader
m_vertexShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
VERTEX
)
);
m_fragmentShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
FRAGMENT
)
);
m_geometryShader
=
osg
::
ref_ptr
<
osg
::
Shader
>
(
new
osg
::
Shader
(
osg
::
Shader
::
GEOMETRY
)
);
// add them
addShader
(
m_vertexShader
);
addShader
(
m_fragmentShader
);
addShader
(
m_geometryShader
);
}
WShader2
::~
WShader2
()
{
// cleanup
}
void
WShader2
::
apply
(
osg
::
ref_ptr
<
osg
::
Node
>
node
)
{
// set the shader attribute
osg
::
StateSet
*
rootState
=
node
->
getOrCreateStateSet
();
rootState
->
setAttributeAndModes
(
this
,
osg
::
StateAttribute
::
ON
);
// add a custom callback which actually sets and updated the shader.
node
->
addUpdateCallback
(
osg
::
ref_ptr
<
SafeUpdaterCallback
>
(
new
SafeUpdaterCallback
(
this
)
)
);
}
void
WShader2
::
reload
()
{
m_reload
=
true
;
}
WShader2
::
SafeUpdaterCallback
::
SafeUpdaterCallback
(
WShader2
*
shader
)
:
m_shader
(
shader
)
{
}
void
WShader2
::
SafeUpdaterCallback
::
operator
()(
osg
::
Node
*
node
,
osg
::
NodeVisitor
*
nv
)
{
// is it needed to do something here?
if
(
m_shader
->
m_reload
)
{
try
{
// remove the shaders
m_shader
->
removeShader
(
m_shader
->
m_vertexShader
);
m_shader
->
removeShader
(
m_shader
->
m_fragmentShader
);
m_shader
->
removeShader
(
m_shader
->
m_geometryShader
);
// reload the sources and set the shader
// vertex shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading vertex shader
\"
"
+
m_shader
->
m_name
+
".vs
\"
"
,
"WShader"
,
LL_DEBUG
);
std
::
string
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".vs"
);
if
(
source
!=
""
)
{
m_shader
->
m_vertexShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_vertexShader
);
}
// fragment shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading fragment shader
\"
"
+
m_shader
->
m_name
+
".fs
\"
"
,
"WShader"
,
LL_DEBUG
);
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".fs"
);
if
(
source
!=
""
)
{
m_shader
->
m_fragmentShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_fragmentShader
);
}
// Geometry Shader
WLogger
::
getLogger
()
->
addLogMessage
(
"Reloading geometry shader
\"
"
+
m_shader
->
m_name
+
".gs
\"
"
,
"WShader"
,
LL_DEBUG
);
source
=
m_shader
->
processShader
(
m_shader
->
m_name
+
".gs"
,
true
);
if
(
source
!=
""
)
{
m_shader
->
m_geometryShader
->
setShaderSource
(
source
);
m_shader
->
addShader
(
m_shader
->
m_geometryShader
);