Commit 51545ba0 authored by hybrid's avatar hybrid

Add geometry shaders for OpenGL. Implementation is largely influenced by ideas...

Add geometry shaders for OpenGL. Implementation is largely influenced by ideas from devsh. Right now the input and output types are fixed to EPT_TRIANGLES, the maximal output vertices are only limited by the driver, and some geometry shader extensions are wrongly used. Will be fixed in the near future.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2926 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 2ad8effc
......@@ -15,6 +15,9 @@ enum E_VERTEX_SHADER_TYPE
EVST_VS_2_0,
EVST_VS_2_a,
EVST_VS_3_0,
EVST_VS_4_0,
EVST_VS_4_1,
EVST_VS_5_0,
//! This is not a type, but a value indicating how much types there are.
EVST_COUNT
......@@ -26,6 +29,9 @@ const c8* const VERTEX_SHADER_TYPE_NAMES[] = {
"vs_2_0",
"vs_2_a",
"vs_3_0",
"vs_4_0",
"vs_4_1",
"vs_5_0",
0 };
//! Compile target enumeration for the addHighLevelShaderMaterial() method.
......@@ -39,6 +45,9 @@ enum E_PIXEL_SHADER_TYPE
EPST_PS_2_a,
EPST_PS_2_b,
EPST_PS_3_0,
EPST_PS_4_0,
EPST_PS_4_1,
EPST_PS_5_0,
//! This is not a type, but a value indicating how much types there are.
EPST_COUNT
......@@ -54,6 +63,23 @@ const c8* const PIXEL_SHADER_TYPE_NAMES[] = {
"ps_2_a",
"ps_2_b",
"ps_3_0",
"ps_4_0",
"ps_4_1",
"ps_5_0",
0 };
//! Enum for supported geometry shader types
enum E_GEOMETRY_SHADER_TYPE
{
EGST_GS_4_0 = 0,
//! This is not a type, but a value indicating how much types there are.
EGST_COUNT
};
//! String names for supported geometry shader types
const c8* const GEOMETRY_SHADER_TYPE_NAMES[] = {
"gs_4_0",
0 };
......
......@@ -37,17 +37,25 @@ public:
shader program. This can be 0 if no vertex program shall be used.
\param vertexShaderEntryPointName: Name of the entry function of the
vertexShaderProgram
\param vsCompileTarget: Vertex shader version where the high level
shader shall be compiled to.
\param vsCompileTarget: Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgram: String containing the source of the pixel
shader program. This can be 0 if no pixel shader shall be used.
\param pixelShaderEntryPointName: Entry name of the function of the
pixelShaderEntryPointName
\param psCompileTarget: Pixel shader version where the high level
shader shall be compiled to.
\param psCompileTarget: Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgram: String containing the source of the
geometry shader program. This can be 0 if no geometry shader shall be
used.
\param geometryShaderEntryPointName: Entry name of the function of the
geometryShaderEntryPointName
\param gsCompileTarget: Geometry shader version the high level shader
shall be compiled to.
\param callback: Pointer to an implementation of
IShaderConstantSetCallBack in which you can set the needed vertex and
pixel shader program constants. Set this to 0 if you don't need this.
IShaderConstantSetCallBack in which you can set the needed vertex,
pixel, and geometry shader program constants. Set this to 0 if you
don't need this.
\param baseMaterial: Base material which renderstates will be used to
shade the material.
\param userData: a user data int. This int can be set to any value and
......@@ -55,12 +63,11 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\return Returns the number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an
error occured, e.g. if a vertex or pixel shader program could not be
compiled or a compile target is not reachable. The error strings are
then printed to the error log and can be catched with a custom event
receiver. */
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an error
occured, e.g. if a shader program could not be compiled or a compile
target is not reachable. The error strings are then printed to the
error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
......@@ -68,33 +75,59 @@ public:
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0 ) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0 )
{
return addHighLevelShaderMaterial(
vertexShaderProgram, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgram,
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
callback, baseMaterial, userData);
}
//! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
/** \param vertexShaderProgram: Text file containing the source of the
* vertex shader program.
Set to 0 if no shader shall be created.
\param vertexShaderEntryPointName: Name of the entry function of the
vertexShaderProgram
\param vsCompileTarget: Vertex shader version where the high level
shader shall be compiled to.
\param pixelShaderProgram: Text file containing the source of the pixel
shader program. Set to 0 if no shader shall be created.
/** \param vertexShaderProgramFileName: Text file containing the source
of the vertex shader program. Set to empty string if no vertex shader
shall be created.
\param vertexShaderEntryPointName: Name of the entry function of the
vertexShaderProgram
\param vsCompileTarget: Vertex shader version where the high level
shader shall be compiled to.
\param pixelShaderProgram: String containing the source of the pixel
shader program. This can be 0 if no pixel shader shall be used.
\param vsCompileTarget: Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgramFileName: Text file containing the source of
the pixel shader program. Set to empty string if no pixel shader shall
be created.
\param pixelShaderEntryPointName: Entry name of the function of the
pixelShaderEntryPointName
\param psCompileTarget: Pixel shader version where the high level
shader shall be compiled to.
\param psCompileTarget: Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgramFileName: String containing the source of
the geometry shader program. Set to empty string if no geometry shader
shall be created.
\param geometryShaderEntryPointName: Entry name of the function of the
geometryShaderEntryPointName
\param gsCompileTarget: Geometry shader version the high level shader
shall be compiled to.
\param callback: Pointer to an implementation of
IShaderConstantSetCallBack in which you can set the needed vertex and
pixel shader program constants. Set this to 0 if you don't need this.
IShaderConstantSetCallBack in which you can set the needed vertex,
pixel, and geometry shader program constants. Set this to 0 if you
don't need this.
\param baseMaterial: Base material which renderstates will be used to
shade the material.
\param userData: a user data int. This int can be set to any value and
......@@ -102,12 +135,11 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\return Returns the number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an
error occured, e.g. if a vertex or pixel shader program could not be
compiled or a compile target is not reachable. The error strings are
then printed to the error log and can be catched with a custom event
receiver. */
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an error
occured, e.g. if a shader program could not be compiled or a compile
target is not reachable. The error strings are then printed to the
error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles(
const io::path& vertexShaderProgramFileName,
const c8* vertexShaderEntryPointName = "main",
......@@ -115,27 +147,54 @@ public:
const io::path& pixelShaderProgramFileName = "",
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const io::path& geometryShaderProgramFileName="",
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
const io::path& vertexShaderProgramFileName,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const io::path& pixelShaderProgramFileName = "",
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgramFileName, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgramFileName,
pixelShaderEntryPointName, psCompileTarget,
"", "main", EGST_GS_4_0,
callback, baseMaterial, userData);
}
//! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
/** \param vertexShaderProgram: Text file handle containing the source
* of the vertex shader program.
Set to 0 if no shader shall be created.
of the vertex shader program. Set to 0 if no vertex shader shall be
created.
\param vertexShaderEntryPointName: Name of the entry function of the
vertexShaderProgram
\param vsCompileTarget: Vertex shader version where the high level
shader shall be compiled to.
\param pixelShaderProgram: Text file containing the source of the pixel
shader program. Set to
\param vsCompileTarget: Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgram: Text file handle containing the source of
the pixel shader program. Set to 0 if no shader shall be created.
the pixel shader program. Set to 0 if no pixel shader shall be created.
\param pixelShaderEntryPointName: Entry name of the function of the
pixelShaderEntryPointName
\param psCompileTarget: Pixel shader version where the high level
shader shall be compiled to.
\param psCompileTarget: Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgram: Text file handle containing the source of
the geometry shader program. Set to 0 if no geometry shader shall be
created.
\param geometryShaderEntryPointName: Entry name of the function of the
geometryShaderEntryPointName
\param gsCompileTarget: Geometry shader version the high level shader
shall be compiled to.
\param callback: Pointer to an implementation of
IShaderConstantSetCallBack in which you can set the needed vertex and
pixel shader program constants. Set this to 0 if you don't need this.
......@@ -146,12 +205,11 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\return Returns the number of the material type which can be set in
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an
error occured, e.g. if a vertex or pixel shader program could not be
compiled or a compile target is not reachable. The error strings are
then printed to the error log and can be catched with a custom event
receiver. */
error occured, e.g. if a shader program could not be compiled or a
compile target is not reachable. The error strings are then printed to
the error log and can be catched with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
......@@ -159,10 +217,33 @@ public:
io::IReadFile* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
io::IReadFile* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
io::IReadFile* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgram, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgram,
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
callback, baseMaterial, userData);
}
//! Adds a new ASM shader material renderer to the VideoDriver
/** Note that it is a good idea to call IVideoDriver::queryFeature() in
advance to check if the IVideoDriver supports the vertex and/or pixel
......
......@@ -1785,8 +1785,7 @@ IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices()
}
//! Adds a new material renderer to the VideoDriver, based on a high level shading
//! language. Currently only HLSL in D3D9 is supported.
//! Adds a new material renderer to the VideoDriver, based on a high level shading language.
s32 CNullDriver::addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName,
......@@ -1794,6 +1793,9 @@ s32 CNullDriver::addHighLevelShaderMaterial(
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
......@@ -1806,46 +1808,57 @@ s32 CNullDriver::addHighLevelShaderMaterial(
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files.
s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
const io::path& vertexShaderProgram,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const io::path& pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
const io::path& vertexShaderProgramFileName,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const io::path& pixelShaderProgramFileName,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const io::path& geometryShaderProgramFileName,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
{
io::IReadFile* vsfile = 0;
io::IReadFile* psfile = 0;
io::IReadFile* gsfile = 0;
if (vertexShaderProgram.size() )
if (vertexShaderProgramFileName.size() )
{
vsfile = FileSystem->createAndOpenFile(vertexShaderProgram);
vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName);
if (!vsfile)
{
os::Printer::log("Could not open vertex shader program file",
vertexShaderProgram, ELL_WARNING);
return -1;
vertexShaderProgramFileName, ELL_WARNING);
}
}
if (pixelShaderProgram.size() )
if (pixelShaderProgramFileName.size() )
{
psfile = FileSystem->createAndOpenFile(pixelShaderProgram);
psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName);
if (!psfile)
{
os::Printer::log("Could not open pixel shader program file",
pixelShaderProgram, ELL_WARNING);
if (vsfile)
vsfile->drop();
return -1;
pixelShaderProgramFileName, ELL_WARNING);
}
}
if (geometryShaderProgramFileName.size() )
{
gsfile = FileSystem->createAndOpenFile(geometryShaderProgramFileName);
if (!gsfile)
{
os::Printer::log("Could not open geometry shader program file",
geometryShaderProgramFileName, ELL_WARNING);
}
}
s32 result = addHighLevelShaderMaterialFromFiles(
vsfile, vertexShaderEntryPointName, vsCompileTarget,
psfile, pixelShaderEntryPointName, psCompileTarget,
gsfile, geometryShaderEntryPointName, gsCompileTarget,
callback, baseMaterial, userData);
if (psfile)
......@@ -1854,6 +1867,9 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
if (vsfile)
vsfile->drop();
if (gsfile)
gsfile->drop();
return result;
}
......@@ -1861,18 +1877,22 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files.
s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
io::IReadFile* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
io::IReadFile* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
io::IReadFile* geometryShaderProgram,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
{
c8* vs = 0;
c8* ps = 0;
c8* gs = 0;
if (vertexShaderProgram)
{
......@@ -1899,13 +1919,30 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
}
}
if (geometryShaderProgram)
{
const long size = geometryShaderProgram->getSize();
if (size)
{
// if both handles are the same we must reset the file
if ((geometryShaderProgram==vertexShaderProgram) ||
(geometryShaderProgram==pixelShaderProgram))
geometryShaderProgram->seek(0);
gs = new c8[size+1];
geometryShaderProgram->read(gs, size);
gs[size] = 0;
}
}
s32 result = this->addHighLevelShaderMaterial(
vs, vertexShaderEntryPointName, vsCompileTarget,
ps, pixelShaderEntryPointName, psCompileTarget,
gs, geometryShaderEntryPointName, gsCompileTarget,
callback, baseMaterial, userData);
delete [] vs;
delete [] ps;
delete [] gs;
return result;
}
......
......@@ -478,6 +478,9 @@ namespace video
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
......@@ -491,6 +494,9 @@ namespace video
const io::path& pixelShaderProgramFile = "",
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const io::path& geometryShaderProgramFileName="",
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
......@@ -504,6 +510,9 @@ namespace video
io::IReadFile* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
io::IReadFile* geometryShaderProgram= 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
......
......@@ -3235,6 +3235,9 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
......@@ -3242,14 +3245,16 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
s32 nr = -1;
COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer(
this, nr, vertexShaderProgram, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
this, nr,
vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
callback,getMaterialRenderer(baseMaterial), userData);
r->drop();
return nr;
}
//! Returns a pointer to the IVideoDriver interface. (Implementation for
//! IMaterialRendererServices)
IVideoDriver* COpenGLDriver::getVideoDriver()
......
......@@ -261,10 +261,19 @@ namespace video
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData);
//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry.
virtual s32 addHighLevelShaderMaterial(const c8* vertexShaderProgram, const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget, const c8* pixelShaderProgram, const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget, IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial,
s32 userData);
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0);
//! Returns a pointer to the IVideoDriver interface. (Implementation for
//! IMaterialRendererServices)
......
......@@ -19,9 +19,11 @@ namespace video
COpenGLExtensionHandler::COpenGLExtensionHandler() :
StencilBuffer(false), MultiTextureExtension(false),
TextureCompressionExtension(false),
MaxTextureUnits(1), MaxLights(1), MaxAnisotropy(1), MaxUserClipPlanes(0),
MaxAuxBuffers(0), MaxIndices(65535), MaxTextureSize(1), MaxTextureLODBias(0.f),
MaxMultipleRenderTargets(1), Version(0), ShaderLanguageVersion(0)
MaxTextureUnits(1), MaxLights(1), MaxAnisotropy(1),
MaxUserClipPlanes(0), MaxAuxBuffers(0),
MaxMultipleRenderTargets(1), MaxIndices(65535),
MaxTextureSize(1), MaxGeometryVerticesOut(0),
MaxTextureLODBias(0.f), Version(0), ShaderLanguageVersion(0)
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0),
pGlGenProgramsARB(0), pGlBindProgramARB(0), pGlProgramStringARB(0),
......@@ -48,7 +50,8 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
pGlIsBufferARB(0), pGlGetBufferParameterivARB(0), pGlGetBufferPointervARB(0),
pGlProvokingVertexARB(0), pGlProvokingVertexEXT(0),
pGlColorMaskIndexedEXT(0), pGlEnableIndexedEXT(0), pGlDisableIndexedEXT(0),
pGlBlendFuncIndexedAMD(0), pGlBlendFunciARB(0)
pGlBlendFuncIndexedAMD(0), pGlBlendFunciARB(0),
pGlProgramParameteriARB(0), pGlProgramParameteriEXT(0)
#endif // _IRR_OPENGL_USE_EXTPOINTER_
{
for (u32 i=0; i<IRR_OpenGL_Feature_Count; ++i)
......@@ -195,6 +198,8 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
pGlDisableIndexedEXT= (PFNGLDISABLEINDEXEDEXTPROC) wglGetProcAddress("glDisableIndexedEXT");
pGlBlendFuncIndexedAMD= (PFNGLBLENDFUNCINDEXEDAMDPROC) wglGetProcAddress("glBlendFuncIndexedAMD");
pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC) wglGetProcAddress("glBlendFunciARB");
pGlProgramParameteriARB= (PFNGLPROGRAMPARAMETERIARBPROC) wglGetProcAddress("glProgramParameteriARB");
pGlProgramParameteriEXT= (PFNGLPROGRAMPARAMETERIEXTPROC) wglGetProcAddress("glProgramParameteriEXT");
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined (_IRR_COMPILE_WITH_SDL_DEVICE_)
......@@ -421,6 +426,10 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glBlendFuncIndexedAMD"));
pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glBlendFunciARB"));
pGlProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glProgramParameteriARB"));
pGlProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)
IRR_OGL_LOAD_EXTENSION(reinterpret_cast<const GLubyte*>("glProgramParameteriEXT"));
#endif // _IRR_OPENGL_USE_EXTPOINTER_
#endif // _IRR_WINDOWS_API_
......@@ -452,6 +461,13 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
#endif
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &num);
MaxTextureSize=static_cast<u32>(num);
#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4)
if (queryFeature(EVDF_GEOMETRY_SHADER))
{
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &num);
MaxGeometryVerticesOut=static_cast<u32>(num);
}
#endif
#ifdef GL_EXT_texture_lod_bias
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxTextureLODBias);
......
......@@ -812,14 +812,16 @@ class COpenGLExtensionHandler
u8 MaxUserClipPlanes;
//! Number of auxiliary buffers
u8 MaxAuxBuffers;
//! Number of rendertargets available as MRTs
u8 MaxMultipleRenderTargets;
//! Optimal number of indices per meshbuffer
u32 MaxIndices;
//! Maximal texture dimension
u32 MaxTextureSize;
//! Maximal vertices handled by geometry shaders
u32 MaxGeometryVerticesOut;
//! Maximal LOD Bias
f32 MaxTextureLODBias;
//! Number of rendertargets available as MRTs
u8 MaxMultipleRenderTargets;
//! Minimal and maximal supported thickness for lines without smoothing
GLfloat DimAliasedLine[2];
//! Minimal and maximal supported thickness for points without smoothing
......@@ -904,6 +906,7 @@ class COpenGLExtensionHandler
void extGlEnableIndexed(GLenum target, GLuint index);
void extGlDisableIndexed(GLenum target, GLuint index);
void extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst);
void extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value);
protected:
......@@ -979,6 +982,8 @@ class COpenGLExtensionHandler
PFNGLDISABLEINDEXEDEXTPROC pGlDisableIndexedEXT;
PFNGLBLENDFUNCINDEXEDAMDPROC pGlBlendFuncIndexedAMD;
PFNGLBLENDFUNCIPROC pGlBlendFunciARB;
PFNGLPROGRAMPARAMETERIARBPROC pGlProgramParameteriARB;
PFNGLPROGRAMPARAMETERIEXTPROC pGlProgramParameteriEXT;
#endif
};
......@@ -1746,6 +1751,28 @@ inline void COpenGLExtensionHandler::extGlBlendFuncIndexed(GLuint buf, GLenum sr
}
inline void COpenGLExtensionHandler::extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value)
{
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
if (queryFeature(EVDF_GEOMETRY_SHADER))
{
if (pGlProgramParameteriARB)
pGlProgramParameteriARB(program, pname, value);
else if (pGlProgramParameteriEXT)
pGlProgramParameteriEXT(program, pname, value);
}
#elif defined(GL_ARB_geometry_shader4)
glProgramParameteriARB(program, pname, value);
#elif defined(GL_EXT_geometry_shader4)
glProgramParameteriEXT(program, pname, value);
#elif defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4)
glProgramParameteriNV(program, pname, value);
#else
os::Printer::log("glProgramParameteri not supported", ELL_ERROR);
#endif
}
}
}
......
......@@ -35,6 +35,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
IShaderConstantSetCallBack* callback,
video::IMaterialRenderer* baseMaterial,
s32 userData)
......@@ -58,7 +61,7 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
if (!Driver->queryFeature(EVDF_ARB_GLSL))
return;
init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram);
init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, geometryShaderProgram);
}
......@@ -96,9 +99,11 @@ COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer()
BaseMaterial->drop();
}
void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram)
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
const c8* geometryShaderProgram)
{
outMaterialTypeNr = -1;
......@@ -110,12 +115,17 @@ void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,
if (!createShader(GL_VERTEX_SHADER_ARB, vertexShaderProgram))
return;
if (pixelShaderProgram)
if (!createShader(GL_FRAGMENT_SHADER_ARB, pixelShaderProgram))
return;
#endif
#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4)
if (geometryShaderProgram && Driver->queryFeature(EVDF_GEOMETRY_SHADER))
if (!createShader(GL_GEOMETRY_SHADER_EXT, geometryShaderProgram))
return;
#endif
if (!linkProgram())
return;
......@@ -128,7 +138,7 @@ bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service,
E_VERTEX_TYPE vtxtype)
{
// call callback to set shader constants
if (CallBack && (Program))
if (CallBack && Program)
CallBack->OnSetConstants(this, UserData);
return true;
......@@ -212,6 +222,15 @@ bool COpenGLSLMaterialRenderer::createShader(GLenum shaderType, const char* shad
Driver->extGlAttachObject(Program, shaderHandle);
#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4)
if (shaderType==GL_GEOMETRY_SHADER_EXT && Driver->queryFeature(EVDF_GEOMETRY_SHADER))
{
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLES);
Driver->extGlProgramParameteri(Program, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut);
}
#endif
return true;
}
......
......@@ -54,15 +54,18 @@ public:
COpenGLSLMaterialRenderer(
COpenGLDriver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
s32 userData);
const c8* vertexShaderProgram = 0,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
IShaderConstantSetCallBack* callback = 0,
IMaterialRenderer* baseMaterial = 0,
s32 userData = 0);
//! Destructor
virtual ~COpenGLSLMaterialRenderer();
......@@ -96,7 +99,8 @@ protected:
void init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram);
const c8* pixelShaderProgram,
const c8* geometryShaderProgram);
bool createProgram();
bool createShader(GLenum shaderType, const char* shader);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment