mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0028912: Visualization, TKOpenGl - multi-texture support
Graphic3d_AspectFillArea3d now stores array of textures. Graphic3d_TextureParams stores texture unit for mapping texture. OpenGl_Context::BindTextures() - context now manages the set of active textures. Related code has been removed from OpenGl_Workspace. OpenGl_Sampler has been extended to hold texture parameters structure. OpenGl_Texture now holds OpenGl_Sampler instance as class field. OpenGl_Texture inherits new class OpenGl_NamedResource and holds texture identifier used for sharing resource in OpenGl_Context. OpenGl_RaytraceGeometry now creates bindless textures taking Sampler object directly from OpenGl_Texture. OpenGl_Context::BindTextures() automatically recreates immutable Sampler Object on texture parameters change. Declared new structure OpenGl_ArbSamplerObject for platform-neutral usage of related functionality. Related functions are now loaded within OpenGL ES 3.0+. Declarations.glsl - occActiveSampler has been renamed to occSampler0 with aliases occSamplerBaseColor (main) and occActiveSampler (for compatibility). Additional texture samplers should be declared explicitly within specific GLSL program as occSampler1, occSampler2, etc. AIS_Shape and AIS_ColoredShape now computes Shaded presentation with UV coordinates if texture mapping is enabled in Drawer. vshaderprog now accepts Shader source code as parameter.
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
#include <Graphic3d_AspectLine3d.hxx>
|
||||
#include <Graphic3d_CStructure.hxx>
|
||||
#include <Graphic3d_Texture2Dmanual.hxx>
|
||||
#include <Graphic3d_GraphicDriver.hxx>
|
||||
#include <Image_AlienPixMap.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <Prs3d_Drawer.hxx>
|
||||
@@ -3420,13 +3421,13 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
|
||||
|
||||
Handle(AIS_Shape) aTexturedIO;
|
||||
Handle(Graphic3d_TextureMap) aTextureOld;
|
||||
Handle(Graphic3d_Texture2Dmanual) aTextureNew;
|
||||
Handle(Graphic3d_TextureSet) aTextureSetOld;
|
||||
NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
|
||||
bool toSetGenRepeat = false;
|
||||
bool toSetGenScale = false;
|
||||
bool toSetGenOrigin = false;
|
||||
bool toSetImage = false;
|
||||
bool toSetNewImage = false;
|
||||
bool toComputeUV = false;
|
||||
|
||||
const TCollection_AsciiString aCommandName (theArgVec[0]);
|
||||
bool toSetDefaults = aCommandName == "vtexdefault";
|
||||
@@ -3456,7 +3457,7 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
|
||||
if (aTexturedIO->Attributes()->HasOwnShadingAspect())
|
||||
{
|
||||
aTextureOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap();
|
||||
aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
|
||||
}
|
||||
}
|
||||
else if (aNameCase == "-scale"
|
||||
@@ -3665,22 +3666,51 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
{
|
||||
toSetDefaults = true;
|
||||
}
|
||||
else if (aTextureNew.IsNull()
|
||||
&& aCommandName == "vtexture")
|
||||
else if (aCommandName == "vtexture"
|
||||
&& (aTextureVecNew.IsEmpty()
|
||||
|| aNameCase.StartsWith ("-tex")))
|
||||
{
|
||||
toSetImage = true;
|
||||
toSetNewImage = true;
|
||||
if (aName.IsIntegerValue())
|
||||
Standard_Integer aTexIndex = 0;
|
||||
TCollection_AsciiString aTexName = aName;
|
||||
if (aNameCase.StartsWith ("-tex"))
|
||||
{
|
||||
const Standard_Integer aValue = aName.IntegerValue();
|
||||
if (anArgIter + 1 >= theArgsNb
|
||||
|| aNameCase.Length() < 5)
|
||||
{
|
||||
std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
|
||||
if (!aTexIndexStr.IsIntegerValue())
|
||||
{
|
||||
std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
aTexIndex = aTexIndexStr.IntegerValue();
|
||||
aTexName = theArgVec[anArgIter + 1];
|
||||
++anArgIter;
|
||||
}
|
||||
if (aTexIndex >= Graphic3d_TextureUnit_NB
|
||||
|| aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
|
||||
{
|
||||
std::cout << "Error: too many textures specified\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
toSetImage = true;
|
||||
if (aTexName.IsIntegerValue())
|
||||
{
|
||||
const Standard_Integer aValue = aTexName.IntegerValue();
|
||||
if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
|
||||
{
|
||||
std::cout << "Syntax error: texture with ID " << aValue << " is undefined!\n";
|
||||
return 1;
|
||||
}
|
||||
aTextureNew = new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue));
|
||||
aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
|
||||
}
|
||||
else if (aNameCase == "?")
|
||||
else if (aTexName == "?")
|
||||
{
|
||||
const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
|
||||
|
||||
@@ -3695,19 +3725,49 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
theDi.Eval (aCmnd.ToCString());
|
||||
return 0;
|
||||
}
|
||||
else if (aNameCase != "off")
|
||||
else if (aTexName != "off")
|
||||
{
|
||||
if (!OSD_File (aName).Exists())
|
||||
if (!OSD_File (aTexName).Exists())
|
||||
{
|
||||
std::cout << "Syntax error: non-existing image file has been specified '" << aName << "'.\n";
|
||||
std::cout << "Syntax error: non-existing image file has been specified '" << aTexName << "'.\n";
|
||||
return 1;
|
||||
}
|
||||
aTextureNew = new Graphic3d_Texture2Dmanual (aName);
|
||||
aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
|
||||
}
|
||||
|
||||
if (!aTextureNew.IsNull())
|
||||
else
|
||||
{
|
||||
if (!aTextureOld.IsNull())
|
||||
aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
|
||||
}
|
||||
aTextureVecNew.ChangeValue (aTexIndex)->GetParams()->SetTextureUnit ((Graphic3d_TextureUnit )aTexIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (toSetImage)
|
||||
{
|
||||
// check if new image set is equal to already set one
|
||||
Standard_Integer aNbChanged = 0;
|
||||
Handle(Graphic3d_TextureSet) aTextureSetNew;
|
||||
if (!aTextureVecNew.IsEmpty())
|
||||
{
|
||||
aNbChanged = aTextureVecNew.Size();
|
||||
aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
|
||||
for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
|
||||
{
|
||||
Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
|
||||
Handle(Graphic3d_TextureRoot) aTextureOld;
|
||||
if (!aTextureSetOld.IsNull()
|
||||
&& aTexIter < aTextureSetOld->Size())
|
||||
{
|
||||
aTextureOld = aTextureSetOld->Value (aTexIter);
|
||||
}
|
||||
|
||||
if (!aTextureOld.IsNull()
|
||||
&& !aTextureNew.IsNull())
|
||||
{
|
||||
*aTextureNew->GetParams() = *aTextureOld->GetParams();
|
||||
if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
|
||||
@@ -3719,39 +3779,31 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
&& aFilePathOld == aFilePathNew
|
||||
&& (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
|
||||
{
|
||||
toSetNewImage = false;
|
||||
--aNbChanged;
|
||||
aTextureNew = anOldManualTex;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aTexturedIO->SetToUpdate (AIS_Shaded);
|
||||
}
|
||||
aTextureSetNew->SetValue (aTexIter, aTextureNew);
|
||||
}
|
||||
|
||||
if (!aTexturedIO->Attributes()->HasOwnShadingAspect())
|
||||
{
|
||||
aTexturedIO->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
*aTexturedIO->Attributes()->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
|
||||
}
|
||||
|
||||
if (!aTextureNew.IsNull())
|
||||
{
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
|
||||
}
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (aTextureNew);
|
||||
aTextureOld.Nullify();
|
||||
}
|
||||
else
|
||||
if (aNbChanged == 0
|
||||
&& ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
|
||||
|| (aTextureSetOld->Size() == aTextureSetNew->Size())))
|
||||
{
|
||||
std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
|
||||
return 1;
|
||||
aTextureSetNew = aTextureSetOld;
|
||||
}
|
||||
|
||||
if (!aTexturedIO->Attributes()->HasOwnShadingAspect())
|
||||
{
|
||||
aTexturedIO->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
*aTexturedIO->Attributes()->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
|
||||
}
|
||||
|
||||
toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
|
||||
aTextureSetOld.Nullify();
|
||||
}
|
||||
|
||||
if (toSetDefaults)
|
||||
@@ -3790,12 +3842,12 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
if (aCommandName == "vtexture"
|
||||
&& theArgsNb == 2)
|
||||
{
|
||||
if (!aTextureOld.IsNull())
|
||||
if (!aTextureSetOld.IsNull())
|
||||
{
|
||||
toSetNewImage = true;
|
||||
//toComputeUV = true; // we can keep UV vertex attributes
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (Handle(Graphic3d_TextureMap)());
|
||||
aTextureOld.Nullify();
|
||||
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
|
||||
aTextureSetOld.Nullify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3851,7 +3903,7 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
|
||||
toSetGenScale = true;
|
||||
}
|
||||
|
||||
if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toSetNewImage)
|
||||
if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
|
||||
{
|
||||
aTexturedIO->SetToUpdate (AIS_Shaded);
|
||||
if (toSetImage)
|
||||
@@ -6267,6 +6319,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
|
||||
|
||||
theCommands.Add ("vtexture",
|
||||
"vtexture [-noupdate|-update] name [ImageFile|IdOfTexture|off]"
|
||||
"\n\t\t: [-tex0 Image0] [-tex1 Image1] [...]"
|
||||
"\n\t\t: [-origin {u v|off}] [-scale {u v|off}] [-repeat {u v|off}]"
|
||||
"\n\t\t: [-trsfTrans du dv] [-trsfScale su sv] [-trsfAngle Angle]"
|
||||
"\n\t\t: [-modulate {on|off}]"
|
||||
|
@@ -594,28 +594,40 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
|
||||
{
|
||||
if (theArgNb < 3)
|
||||
{
|
||||
std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
|
||||
std::cout << "Syntax error: lack of arguments\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
|
||||
const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
|
||||
if (!aSrcVert.IsEmpty()
|
||||
&& !OSD_File (aSrcVert).Exists())
|
||||
if (aSrcVert.IsEmpty() || aSrcFrag.IsEmpty())
|
||||
{
|
||||
std::cerr << "Non-existing vertex shader source\n";
|
||||
std::cout << "Syntax error: lack of arguments\n";
|
||||
return 1;
|
||||
}
|
||||
if (!aSrcFrag.IsEmpty()
|
||||
&& !OSD_File (aSrcFrag).Exists())
|
||||
|
||||
const bool isVertFile = OSD_File (aSrcVert).Exists();
|
||||
const bool isFragFile = OSD_File (aSrcFrag).Exists();
|
||||
if (!isVertFile
|
||||
&& aSrcVert.Search ("gl_Position") == -1)
|
||||
{
|
||||
std::cerr << "Non-existing fragment shader source\n";
|
||||
std::cerr << "Error: non-existing or invalid vertex shader source\n";
|
||||
return 1;
|
||||
}
|
||||
if (!isFragFile
|
||||
&& aSrcFrag.Search ("occFragColor") == -1)
|
||||
{
|
||||
std::cerr << "Error: non-existing or invalid fragment shader source\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
aProgram = new Graphic3d_ShaderProgram();
|
||||
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
aProgram->AttachShader (isVertFile
|
||||
? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)
|
||||
: Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgram->AttachShader (isFragFile
|
||||
? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)
|
||||
: Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
anArgsNb = theArgNb - 2;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user