/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// // GLES2Module.cpp : Defines the initialization routines for the DLL. #include "OdaCommon.h" #include "RxDispatchImpl.h" #include "RxDynamicModule.h" #include "DynamicLinker.h" #include "Gs/GsBaseVectorizeDevice.h" // for OdSmartPtr #include "Gs/GsViewImpl.h" // for OdSmartPtr #include "../vec/TrVecBaseModule.h" #include "TrVecLocalRenditionGsClient.h" #include "TrRndRenderModule.h" #include "gl2/GLES2Include.h" #if defined(TD_USE_QT_LIB) // Qt-based cross-platform device implementation #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) #include #else #include #endif #include #include #include #include #include #endif #if QT_VERSION < QT_VERSION_CHECK(6,0,0) #include #endif #endif #if defined(__linux__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif #if defined(_TOOLKIT_IN_DLL_) && defined(_MSC_VER) extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID ) { switch ( dwReason ) { case DLL_PROCESS_ATTACH: // remove this if you need per-thread initialization DisableThreadLibraryCalls( (HMODULE)hInstance ); break; } return TRUE; } #define OD_GLES2_WIN_RESOURCES #endif //_TOOLKIT_IN_DLL_ #ifdef OD_GLES2_WIN_RESOURCES #include "win/ExGsGLES2RSTestDialog.h" #endif // OD_GLES2_WIN_RESOURCES // Base device for platform-dependent screen and bitmap devices class OdGLES2PlatformBaseDevice : public OdTrVectorizerModuleHost { protected: enum PropsFlags { kEnableDynamicVBO = (1 << 0), kEnableStaticVBO = (1 << 1), kPurgeVBOArrays = (1 << 2), kCmbShaderStrategy = (1 << 3), kEnableLwdPointOpt = (1 << 4), kEnableLwdLineOpt = (1 << 5), kEnableLwdCache = (1 << 6), kLwdCachePriorGS = (1 << 7), kLwdGeometryShader = (1 << 8), kLtpGeometryShader = (1 << 9), kColorModifyShader = (1 << 10), kLwdDepthOffset = (1 << 11), kEnableShadows = (1 << 12), kEnableVSMShadows = (1 << 13), kPointShadowCubeMap = (1 << 14), kPointShadowGS = (1 << 15), kShadowsSmoothness = (1 << 16), kEnableSSAO = (1 << 17), kEnableFXAA = (1 << 18), kEnableAA2d = (1 << 19), kDepthBufferMerge = (1 << 20), kDepthBufMergeDbg = (1 << 21), kSSAODynamicRadius = (1 << 22), kEnableSMAA = (1 << 23), kEnableTextAA = (1 << 24), kEnableTextAAClearType = (1 << 25), kEnableBatching = (1 << 26), kPartialBatching = (1 << 27), // Last flag for inheritors kLastPropFlag = kPartialBatching }; protected: mutable OdTrRndLocalRenditionClientPtr m_pRenditionClient; OdUInt32 m_nCheckVersion; OdUInt32 m_nPropFlags; OdUInt32 m_nStaticVBOLimit; OdUInt32 m_nLwdCacheLimit; OdUInt32 m_nBlendingMode; float m_vsmShadowsAmount; OdUInt32 m_nShadowMapSoftness; OdUInt32 m_nShadowMapSize; float m_aaLevel, m_aaLevelExt, m_aaHltLevel; float m_ssaoFocus, m_ssaoPower; OdUInt32 m_ssaoLoops, m_ssaoBlurRadius; OdUInt32 m_aaQuality; OdUInt32 m_nGPUSelectionLevel;//See GPUSelection::Level OdUInt32 m_nTextAATextureSize; OdUInt32 m_nTextAANumSamples; OdUInt32 m_nTextAAAdditionalThickness; float m_batchingFragmentation; OdUInt32 m_batchingSizeLimitOverride; OdUInt8 m_interactivityOptions = 0; float m_FXAALineWidth; float m_anisotropy; public: // TrGL2-specific properties ODRX_DECLARE_PROPERTY_TRV(VBOLevel) ODRX_DECLARE_PROPERTY_TRV(StaticVBOLimit) ODRX_DECLARE_PROPERTY_TRV(CombinedShadersStrategy) ODRX_DECLARE_PROPERTY_TRV(LineweightOptimization) ODRX_DECLARE_PROPERTY_TRV(LineweightCacheLimit) ODRX_DECLARE_PROPERTY_TRV(GeometryShaderUsage) ODRX_DECLARE_PROPERTY_TRV(UseColorModifiersShader) ODRX_DECLARE_PROPERTY_TRV(LineweightDepthOffset) ODRX_DECLARE_PROPERTY_TRV(ShadowsRenderMode) ODRX_DECLARE_PROPERTY_TRV(VsmShadowsAmount) ODRX_DECLARE_PROPERTY_TRV(ShadowMapSoftnessOverride) ODRX_DECLARE_PROPERTY_TRV(ShadowMapSizeOverride) ODRX_DECLARE_PROPERTY_TRV(BlendingMode) ODRX_DECLARE_PROPERTY_TRV(DepthBufferMergeMode) ODRX_DECLARE_PROPERTY_TRV(AntiAliasLevel) ODRX_DECLARE_PROPERTY_TRV(AntiAliasLevelExt) ODRX_DECLARE_PROPERTY_TRV(AntiAliasHltLevelExt) ODRX_DECLARE_PROPERTY_TRV(SSAOEnable) ODRX_DECLARE_PROPERTY_TRV(SSAOLoops) ODRX_DECLARE_PROPERTY_TRV(SSAOFocus) ODRX_DECLARE_PROPERTY_TRV(SSAOPower) ODRX_DECLARE_PROPERTY_TRV(SSAOBlurRadius) ODRX_DECLARE_PROPERTY_TRV(SSAODynamicRadius) ODRX_DECLARE_PROPERTY_TRV(FXAAEnable) ODRX_DECLARE_PROPERTY_TRV(AAQuality) ODRX_DECLARE_PROPERTY_TRV(AA2dEnable) ODRX_DECLARE_PROPERTY_TRV(GPUSelectionEnable) ODRX_DECLARE_PROPERTY_TRV(GPUSelectionLevel) ODRX_DECLARE_PROPERTY_TRV(SMAAEnable) ODRX_DECLARE_PROPERTY_TRV(TextAAEnable) ODRX_DECLARE_PROPERTY_TRV(TextAAClearTypeEnable) ODRX_DECLARE_PROPERTY_TRV(TextAATextureSize) ODRX_DECLARE_PROPERTY_TRV(TextAANumSamples) ODRX_DECLARE_PROPERTY_TRV(TextAAAdditionalThickness) ODRX_DECLARE_PROPERTY_TRV(UseBatching) ODRX_DECLARE_PROPERTY_TRV(BatchingMaxFragmentation) ODRX_DECLARE_PROPERTY_TRV(BatchingVBOLimitOverride) ODRX_DECLARE_PROPERTY_TRV(FXAALineWidth) ODRX_DECLARE_PROPERTY_TRV(Anisotropy) // Module-specific properties ODRX_DECLARE_PROPERTY_TRV(RenderSettings) ODRX_DECLARE_PROPERTY_TRV(SaveContextData) ODRX_DECLARE_PROPERTY_TRV(CheckRendererVersion) ODRX_DECLARE_PROPERTY_TRV(RendererDriverInfo) //Interactivity ODRX_DECLARE_PROPERTY_TRV(InteractivityOptions) OdGLES2PlatformBaseDevice() : m_nCheckVersion(0) , m_nPropFlags(kEnableStaticVBO | kEnableLwdPointOpt | kEnableLwdCache | kLwdGeometryShader | kLtpGeometryShader | kColorModifyShader | kLwdDepthOffset | kEnableShadows | kEnableVSMShadows | kPointShadowCubeMap | kPointShadowGS | kShadowsSmoothness | kSSAODynamicRadius /* | kEnableBatching | kPartialBatching*/) , m_nStaticVBOLimit(256) // Allocate only for large vertex arrays , m_nLwdCacheLimit(16) , m_nBlendingMode(OdTrVisRenderClient::kBlendingSinglePassOIT) , m_vsmShadowsAmount(0.25f) , m_nShadowMapSoftness(3) , m_nShadowMapSize(0) , m_aaLevel(2.0f) // @@@tmp: m_aaLevel must be 0.0f by default? , m_aaLevelExt(0.25f) , m_aaHltLevel(0.075f) , m_ssaoFocus(1.0f) , m_ssaoPower(2.0f) , m_ssaoLoops(32) , m_ssaoBlurRadius(6) , m_aaQuality(4) , m_nGPUSelectionLevel(0) , m_nTextAATextureSize(64) , m_nTextAANumSamples(16) , m_nTextAAAdditionalThickness(0) , m_batchingFragmentation(0.5f) , m_batchingSizeLimitOverride(0) , m_FXAALineWidth(0.0f) , m_anisotropy(0.0f) { } void setRenditionClient(OdTrRndLocalRenditionClient *pRenditionClient) { m_pRenditionClient = pRenditionClient; } OdTrVecLocalRenditionGsClient *renditionClient() const { return static_cast(m_pRenditionClient.get()); } OdTrVisRenditionPtr createRendition() override { return renditionClient()->renderModule()->createRendition(m_pRenditionClient); } OdTrRndLocalRenditionHostPtr renditionHost() const { return renditionClient()->renderModule()->createRenditionHost(reinterpret_cast(renderClient()->getProperty(OD_T("Rendition"))->getIntPtr())); } virtual void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen = false, bool bMobile = false, bool bDynamicVBO = false) { if (bMobile) { if (!bDynamicVBO) pRenderClient->setProperty(OD_T("ShareableDevice"), OdRxVariantValue(false)); pRenderClient->setProperty(OD_T("LightSourcesLimit"), OdRxVariantValue(OdInt32(4))); } else pRenderClient->setProperty(OD_T("CombinedShadersStrategy"), OdRxVariantValue(true)); pRenderClient->setProperty(OD_T("UseOverlays"), OdRxVariantValue(!bOffScreen)); if (bDynamicVBO) { pRenderClient->setProperty(OD_T("VBOLevel"), OdRxVariantValue(OdUInt32(3))); pRenderClient->setProperty(OD_T("StaticVBOLimit"), OdRxVariantValue(OdUInt32(0))); pRenderClient->setProperty(OD_T("LineweightCacheLimit"), OdRxVariantValue(OdUInt32(0))); } } void configureForPlatform(OdTrVisRenderClient *pRenderClient, DeviceSetupType devType) override { configureForPlatform(pRenderClient, devType == kDtOffScreen); } void setVBOLevel(OdUInt32 nLevel) { SETBIT(m_nPropFlags, kEnableDynamicVBO, GETBIT(nLevel, 1)); SETBIT(m_nPropFlags, kEnableStaticVBO, GETBIT(nLevel, 2)); SETBIT(m_nPropFlags, kPurgeVBOArrays, GETBIT(nLevel, 4)); } OdUInt32 VBOLevel() const { return (GETBIT(m_nPropFlags, kEnableDynamicVBO) ? 1 : 0) | (GETBIT(m_nPropFlags, kEnableStaticVBO) ? 2 : 0) | (GETBIT(m_nPropFlags, kPurgeVBOArrays) ? 4 : 0); } void setStaticVBOLimit(OdUInt32 nLimit) { m_nStaticVBOLimit = nLimit; } OdUInt32 staticVBOLimit() const { return m_nStaticVBOLimit; } void setCombinedShadersStrategy(bool bSet) { SETBIT(m_nPropFlags, kCmbShaderStrategy, bSet); } bool isCombinedShadersStrategyEnabled() const { return GETBIT(m_nPropFlags, kCmbShaderStrategy); } void setLineweightOptimizationLevel(OdUInt32 nLevel) { SETBIT(m_nPropFlags, kEnableLwdPointOpt, GETBIT(nLevel, 1)); SETBIT(m_nPropFlags, kEnableLwdLineOpt , GETBIT(nLevel, 2)); SETBIT(m_nPropFlags, kEnableLwdCache , GETBIT(nLevel, 4)); SETBIT(m_nPropFlags, kLwdCachePriorGS , GETBIT(nLevel, 8)); } OdUInt32 lineweightOptimizationLevel() const { return (GETBIT(m_nPropFlags, kEnableLwdPointOpt) ? 1 : 0) | (GETBIT(m_nPropFlags, kEnableLwdLineOpt) ? 2 : 0) | (GETBIT(m_nPropFlags, kEnableLwdCache) ? 4 : 0) | (GETBIT(m_nPropFlags, kLwdCachePriorGS) ? 8 : 0); } void setLineweightCacheLimit(OdUInt32 nLimit) { m_nLwdCacheLimit = nLimit; } OdUInt32 lineweightCacheLimit() const { return m_nLwdCacheLimit; } void setGeometryShaderUsageLevel(OdUInt32 nLevel) { SETBIT(m_nPropFlags, kLwdGeometryShader, GETBIT(nLevel, 1)); SETBIT(m_nPropFlags, kLtpGeometryShader, GETBIT(nLevel, 2)); } OdUInt32 geometryShaderUsageLevel() const { return (GETBIT(m_nPropFlags, kLwdGeometryShader) ? 1 : 0) | (GETBIT(m_nPropFlags, kLtpGeometryShader) ? 2 : 0); } void setUseColorModifiersShader(bool bSet) { SETBIT(m_nPropFlags, kColorModifyShader, bSet); } bool useColorModifiersShader() const { return GETBIT(m_nPropFlags, kColorModifyShader); } void setLineweightDepthOffset(bool bSet) { SETBIT(m_nPropFlags, kLwdDepthOffset, bSet); } bool useLineweightDepthOffset() const { return GETBIT(m_nPropFlags, kLwdDepthOffset); } void setShadowsRenderMode(OdUInt32 nMode) { SETBIT(m_nPropFlags, kEnableShadows , GETBIT(nMode, 1)); SETBIT(m_nPropFlags, kEnableVSMShadows , GETBIT(nMode, 2)); SETBIT(m_nPropFlags, kPointShadowCubeMap, GETBIT(nMode, 4)); SETBIT(m_nPropFlags, kPointShadowGS , GETBIT(nMode, 8)); SETBIT(m_nPropFlags, kShadowsSmoothness , GETBIT(nMode, 16)); } OdUInt32 shadowsRenderMode() const { return (GETBIT(m_nPropFlags, kEnableShadows) ? 1 : 0) | (GETBIT(m_nPropFlags, kEnableVSMShadows) ? 2 : 0) | (GETBIT(m_nPropFlags, kPointShadowCubeMap) ? 4 : 0) | (GETBIT(m_nPropFlags, kPointShadowGS) ? 8 : 0) | (GETBIT(m_nPropFlags, kShadowsSmoothness) ? 16 : 0); } void setVsmShadowsAmount(double fAmount) { m_vsmShadowsAmount = (float)fAmount; } double vsmShadowsAmount() const { return m_vsmShadowsAmount; } void setShadowMapSoftness(OdUInt32 nSoftness) { m_nShadowMapSoftness = nSoftness; } OdUInt32 shadowMapSoftnessOverride() const { return m_nShadowMapSoftness; } void setShadowMapSize(OdUInt32 nSize) { m_nShadowMapSize = nSize; } OdUInt32 shadowMapSizeOverride() const { return m_nShadowMapSize; } void setBlendingMode(OdUInt32 nBlendingMode) { m_nBlendingMode = nBlendingMode; } OdUInt32 blendingMode() const { return m_nBlendingMode; } void setDepthBufferMergeMode(OdUInt32 nDepthBufMergeMode) { SETBIT(m_nPropFlags, kDepthBufferMerge, GETBIT(nDepthBufMergeMode, 1)); SETBIT(m_nPropFlags, kDepthBufMergeDbg, GETBIT(nDepthBufMergeMode, 2)); } OdUInt32 depthBufferMergeMode() const { return (GETBIT(m_nPropFlags, kDepthBufMergeDbg) ? 2 : (GETBIT(m_nPropFlags, kDepthBufferMerge) ? 1 : 0)); } void setAntiAliasLevel(double aaLevel) { m_aaLevel = (float)aaLevel; } float antiAliasLevel() const { return m_aaLevel; } void setAntiAliasLevelExt(double aaLevel) { m_aaLevelExt = (float)aaLevel; } float antiAliasLevelExt() const { return m_aaLevelExt; } void setAntiAliasHltLevelExt(double aaLevel) { m_aaHltLevel = (float)aaLevel; } float antiAliasHltLevelExt() const { return m_aaHltLevel; } void setSSAOEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableSSAO, bEnable); } bool ssaoEnabled() const { return GETBIT(m_nPropFlags, kEnableSSAO); } void setSSAOLoops(OdUInt32 ssaoLoops) { m_ssaoLoops = ssaoLoops; } OdUInt32 ssaoLoops() const { return m_ssaoLoops; } void setSSAOFocus(double ssaoFocus) { m_ssaoFocus = (float)ssaoFocus; } float ssaoFocus() const { return m_ssaoFocus; } void setSSAOPower(double ssaoPower) { m_ssaoPower = (float)ssaoPower; } float ssaoPower() const { return m_ssaoPower; } void setSSAOBlurRadius(OdUInt32 ssaoBlurRadius) { m_ssaoBlurRadius = ssaoBlurRadius; } OdUInt32 ssaoBlurRadius() const { return m_ssaoBlurRadius; } void setSSAODynamicRadius(bool ssaoDynamicRadius) { SETBIT(m_nPropFlags, kSSAODynamicRadius, ssaoDynamicRadius); } bool ssaoDynamicRadius() const { return GETBIT(m_nPropFlags, kSSAODynamicRadius); } void setFxAAEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableFXAA, bEnable); } bool fxaaEnabled() const { return GETBIT(m_nPropFlags, kEnableFXAA); } void setAA2dEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableAA2d, bEnable); } bool aa2dEnabled() const { return GETBIT(m_nPropFlags, kEnableAA2d); } void setAAQuality(OdUInt32 nQuality) { m_aaQuality = odmin(nQuality, 5); } OdUInt32 aaQuality() const { return m_aaQuality; } void setGPUSelectionEnable(bool bEnable) { m_nGPUSelectionLevel = bEnable ? 1 : 0; } bool gpuSelectionEnabled() const { return m_nGPUSelectionLevel > 0; } void setGPUSelectionLevel(OdUInt32 nLevel) { m_nGPUSelectionLevel = odmin(nLevel, 3); } OdUInt32 gpuSelectionLevel() const { return m_nGPUSelectionLevel; } void setSMAAEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableSMAA, bEnable); } bool smaaEnabled() const { return GETBIT(m_nPropFlags, kEnableSMAA); } void setTextAAEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableTextAA, bEnable); } bool textAAEnabled() const { return GETBIT(m_nPropFlags, kEnableTextAA); } void setTextAAClearTypeEnable(bool bEnable) { SETBIT(m_nPropFlags, kEnableTextAAClearType, bEnable); } bool textAAClearTypeEnabled() const { return GETBIT(m_nPropFlags, kEnableTextAAClearType); } void setTextAANumSamples(OdUInt32 nSamples) { m_nTextAANumSamples = odmin(nSamples, 64); } OdUInt32 textAANumSamples() const { return m_nTextAANumSamples; } void setTextAATextureSize(OdUInt32 nSize) { m_nTextAATextureSize = odmin(nSize, 1024); } OdUInt32 textAATextureSize() const { return m_nTextAATextureSize; } void setTextAAAdditionalThickness(OdUInt32 nSize) { m_nTextAAAdditionalThickness = odmin(nSize, 64); } OdUInt32 textAAAdditionalThickness() const { return m_nTextAAAdditionalThickness; } void setBatchingEnable(OdUInt32 nVal) { SETBIT(m_nPropFlags, kEnableBatching, nVal > 0); SETBIT(m_nPropFlags, kPartialBatching, nVal == 1); } OdUInt32 batchingEnabled() const { return (GETBIT(m_nPropFlags, kEnableBatching) ? 2 : 0) - (GETBIT(m_nPropFlags, kPartialBatching) ? 1 : 0); } void setMaxBatchingFragmentation(double maxFrag) { m_batchingFragmentation = (float)maxFrag; } float maxBathingFragmentation() const { return m_batchingFragmentation; } void setBatchingVBOLimitOverride(OdUInt32 nOverride) { m_batchingSizeLimitOverride = nOverride; } OdUInt32 batchingVBOLimitOverride() const { return m_batchingSizeLimitOverride; } void setFXAALineWidth(double pFXAALineWidth) { m_FXAALineWidth = (float)pFXAALineWidth; } float fxaaLineWidth() const { return m_FXAALineWidth; } void setAnisotropy(double anisotropy) { m_anisotropy = (float)OdTrVisClamp(anisotropy, 0.0, 16.0); } float anisotropy() const { return m_anisotropy; } void put_RenderSettings(OdIntPtr) { } OdIntPtr get_RenderSettings() const { return (OdIntPtr)renditionHost()->renderSettingsManager(); } void put_SaveContextData(bool bSet) { renditionHost()->processContextData(bSet); } bool get_SaveContextData() const { return renditionHost()->hasContextData(); } void put_CheckRendererVersion(OdUInt32 nCheckVersion) { m_nCheckVersion = nCheckVersion; } OdUInt32 get_CheckRendererVersion() const { return renditionClient()->renderModule()->checkRendererVersion(renderClient(), m_nCheckVersion); } void put_RendererDriverInfo(const OdAnsiString &) { } OdAnsiString get_RendererDriverInfo() const { return renditionClient()->renderModule()->takeRendererInfo(renderClient()); } void setInteractivityOptions( OdUInt8 nOptions ) { m_interactivityOptions = nOptions; } OdUInt8 interactivityOptions() const { return m_interactivityOptions; } OdRxDictionaryPtr createPropertiesContainer() const override { static OdRxDictionaryPtr pDict = ::odrxCreateRxDictionary(); return pDict; } void generateProperties(OdRxDictionary* pInfo) const override { // TrGL2-specific properties ODRX_GENERATE_PROPERTY_TRV(VBOLevel) ODRX_GENERATE_PROPERTY_TRV(StaticVBOLimit) ODRX_GENERATE_PROPERTY_TRV(CombinedShadersStrategy) ODRX_GENERATE_PROPERTY_TRV(LineweightOptimization) ODRX_GENERATE_PROPERTY_TRV(LineweightCacheLimit) ODRX_GENERATE_PROPERTY_TRV(GeometryShaderUsage) ODRX_GENERATE_PROPERTY_TRV(UseColorModifiersShader) ODRX_GENERATE_PROPERTY_TRV(LineweightDepthOffset) ODRX_GENERATE_PROPERTY_TRV(ShadowsRenderMode) ODRX_GENERATE_PROPERTY_TRV(VsmShadowsAmount) ODRX_GENERATE_PROPERTY_TRV(ShadowMapSoftnessOverride) ODRX_GENERATE_PROPERTY_TRV(ShadowMapSizeOverride) ODRX_GENERATE_PROPERTY_TRV(BlendingMode) ODRX_GENERATE_PROPERTY_TRV(DepthBufferMergeMode) ODRX_GENERATE_PROPERTY_TRV(AntiAliasLevel) ODRX_GENERATE_PROPERTY_TRV(AntiAliasLevelExt) ODRX_GENERATE_PROPERTY_TRV(AntiAliasHltLevelExt) ODRX_GENERATE_PROPERTY_TRV(SSAOEnable) ODRX_GENERATE_PROPERTY_TRV(SSAOLoops) ODRX_GENERATE_PROPERTY_TRV(SSAOFocus) ODRX_GENERATE_PROPERTY_TRV(SSAOPower) ODRX_GENERATE_PROPERTY_TRV(SSAOBlurRadius) ODRX_GENERATE_PROPERTY_TRV(SSAODynamicRadius) ODRX_GENERATE_PROPERTY_TRV(FXAAEnable) ODRX_GENERATE_PROPERTY_TRV(AAQuality) ODRX_GENERATE_PROPERTY_TRV(AA2dEnable) ODRX_GENERATE_PROPERTY_TRV(GPUSelectionEnable) ODRX_GENERATE_PROPERTY_TRV(GPUSelectionLevel) ODRX_GENERATE_PROPERTY_TRV(SMAAEnable) ODRX_GENERATE_PROPERTY_TRV(TextAAEnable) ODRX_GENERATE_PROPERTY_TRV(TextAAClearTypeEnable) ODRX_GENERATE_PROPERTY_TRV(TextAATextureSize) ODRX_GENERATE_PROPERTY_TRV(TextAANumSamples) ODRX_GENERATE_PROPERTY_TRV(TextAAAdditionalThickness) ODRX_GENERATE_PROPERTY_TRV(UseBatching) ODRX_GENERATE_PROPERTY_TRV(BatchingMaxFragmentation) ODRX_GENERATE_PROPERTY_TRV(BatchingVBOLimitOverride) ODRX_GENERATE_PROPERTY_TRV(FXAALineWidth) ODRX_GENERATE_PROPERTY_TRV(Anisotropy) // Module-specific properties ODRX_GENERATE_PROPERTY_TRV(RenderSettings) ODRX_GENERATE_PROPERTY_TRV(SaveContextData) ODRX_GENERATE_PROPERTY_TRV(CheckRendererVersion) ODRX_GENERATE_PROPERTY_TRV(RendererDriverInfo) //Interactivity ODRX_GENERATE_PROPERTY_TRV(InteractivityOptions) } }; // TrGL2-specific properties ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, VBOLevel , OdGLES2PlatformBaseDevice, VBOLevel , setVBOLevel , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, StaticVBOLimit , OdGLES2PlatformBaseDevice, staticVBOLimit , setStaticVBOLimit , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, CombinedShadersStrategy , OdGLES2PlatformBaseDevice, isCombinedShadersStrategyEnabled, setCombinedShadersStrategy , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, LineweightOptimization , OdGLES2PlatformBaseDevice, lineweightOptimizationLevel , setLineweightOptimizationLevel, getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, LineweightCacheLimit , OdGLES2PlatformBaseDevice, lineweightCacheLimit , setLineweightCacheLimit , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, GeometryShaderUsage , OdGLES2PlatformBaseDevice, geometryShaderUsageLevel , setGeometryShaderUsageLevel , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, UseColorModifiersShader , OdGLES2PlatformBaseDevice, useColorModifiersShader , setUseColorModifiersShader , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, LineweightDepthOffset , OdGLES2PlatformBaseDevice, useLineweightDepthOffset , setLineweightDepthOffset , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, ShadowsRenderMode , OdGLES2PlatformBaseDevice, shadowsRenderMode , setShadowsRenderMode , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, VsmShadowsAmount , OdGLES2PlatformBaseDevice, vsmShadowsAmount , setVsmShadowsAmount , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, ShadowMapSoftnessOverride, OdGLES2PlatformBaseDevice, shadowMapSoftnessOverride , setShadowMapSoftness , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, ShadowMapSizeOverride , OdGLES2PlatformBaseDevice, shadowMapSizeOverride , setShadowMapSize , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, BlendingMode , OdGLES2PlatformBaseDevice, blendingMode , setBlendingMode , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, DepthBufferMergeMode , OdGLES2PlatformBaseDevice, depthBufferMergeMode , setDepthBufferMergeMode , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, AntiAliasLevel , OdGLES2PlatformBaseDevice, antiAliasLevel , setAntiAliasLevel , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, AntiAliasLevelExt , OdGLES2PlatformBaseDevice, antiAliasLevelExt , setAntiAliasLevelExt , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, AntiAliasHltLevelExt , OdGLES2PlatformBaseDevice, antiAliasHltLevelExt , setAntiAliasHltLevelExt , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAOEnable , OdGLES2PlatformBaseDevice, ssaoEnabled , setSSAOEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAOLoops , OdGLES2PlatformBaseDevice, ssaoLoops , setSSAOLoops , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAOFocus , OdGLES2PlatformBaseDevice, ssaoFocus , setSSAOFocus , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAOPower , OdGLES2PlatformBaseDevice, ssaoPower , setSSAOPower , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAOBlurRadius , OdGLES2PlatformBaseDevice, ssaoBlurRadius , setSSAOBlurRadius , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SSAODynamicRadius , OdGLES2PlatformBaseDevice, ssaoDynamicRadius , setSSAODynamicRadius , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, FXAAEnable , OdGLES2PlatformBaseDevice, fxaaEnabled , setFxAAEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, AAQuality , OdGLES2PlatformBaseDevice, aaQuality , setAAQuality , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, AA2dEnable , OdGLES2PlatformBaseDevice, aa2dEnabled , setAA2dEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, GPUSelectionEnable , OdGLES2PlatformBaseDevice, gpuSelectionEnabled , setGPUSelectionEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, GPUSelectionLevel , OdGLES2PlatformBaseDevice, gpuSelectionLevel , setGPUSelectionLevel , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SMAAEnable , OdGLES2PlatformBaseDevice, smaaEnabled , setSMAAEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, TextAAEnable , OdGLES2PlatformBaseDevice, textAAEnabled , setTextAAEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, TextAAClearTypeEnable , OdGLES2PlatformBaseDevice, textAAClearTypeEnabled , setTextAAClearTypeEnable , getBool); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, TextAATextureSize , OdGLES2PlatformBaseDevice, textAATextureSize , setTextAATextureSize , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, TextAANumSamples , OdGLES2PlatformBaseDevice, textAANumSamples , setTextAANumSamples , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, TextAAAdditionalThickness, OdGLES2PlatformBaseDevice, textAAAdditionalThickness , setTextAAAdditionalThickness , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, UseBatching , OdGLES2PlatformBaseDevice, batchingEnabled , setBatchingEnable , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, BatchingMaxFragmentation , OdGLES2PlatformBaseDevice, maxBathingFragmentation , setMaxBatchingFragmentation , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, BatchingVBOLimitOverride , OdGLES2PlatformBaseDevice, batchingVBOLimitOverride , setBatchingVBOLimitOverride , getUInt32); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, FXAALineWidth , OdGLES2PlatformBaseDevice, fxaaLineWidth , setFXAALineWidth , getDouble); ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdGLES2PlatformBaseDevice::, Anisotropy , OdGLES2PlatformBaseDevice, anisotropy , setAnisotropy , getDouble); // Module-specific properties ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdGLES2PlatformBaseDevice::, RenderSettings , OdGLES2PlatformBaseDevice, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdGLES2PlatformBaseDevice::, SaveContextData , OdGLES2PlatformBaseDevice, getBool) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdGLES2PlatformBaseDevice::, CheckRendererVersion, OdGLES2PlatformBaseDevice, getUInt32) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdGLES2PlatformBaseDevice::, RendererDriverInfo , OdGLES2PlatformBaseDevice, getAnsiString) // Interactivity ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV( OdGLES2PlatformBaseDevice::, InteractivityOptions, OdGLES2PlatformBaseDevice, interactivityOptions, setInteractivityOptions, getUInt8 ); // Base device for platform-dependent screen devices class _OdPlatformGLES2Device : public OdGLES2PlatformBaseDevice { protected: enum PropFlags2 { kCreateContext = kLastPropFlag << 1, kLastPropFlag_ = kCreateContext }; public: ODRX_DECLARE_PROPERTY_TRV(CreateContext) _OdPlatformGLES2Device() { SETBIT_1(m_nPropFlags, kCreateContext); } void put_CreateContext(bool bSet) { SETBIT(m_nPropFlags, kCreateContext, bSet); } bool get_CreateContext() const { return GETBIT(m_nPropFlags, kCreateContext); } DeviceSetupType deviceSetupOverride() const override { return kDtOnScreen; } void generateProperties(OdRxDictionary* pInfo) const override { ODRX_INHERIT_PROPERTIES_TRV(OdGLES2PlatformBaseDevice); ODRX_GENERATE_PROPERTY_TRV(CreateContext) } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(_OdPlatformGLES2Device::, CreateContext , _OdPlatformGLES2Device, getBool) #if defined(TD_USE_QT_LIB) // Qt-based cross-platform device implementation class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: QPointer m_pQWindow; // more priority than m_pQWidget if non-zero // since Qt 6.5.2 QPointer m_pQWidget; // QGLWidget or QOpenGLWidge since Qt 5.4 #ifdef OD_GLES2_WIN_RESOURCES OdGLES2RSTestDialog m_rsTestDlg; #endif // OD_GLES2_WIN_RESOURCES public: #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) ODRX_DECLARE_PROPERTY_TRV(QOpenGLWindow) ODRX_DECLARE_PROPERTY_TRV(QOpenGLWidget) #if QT_VERSION < QT_VERSION_CHECK(6,0,0) ODRX_DECLARE_PROPERTY_TRV(QGLWindow) // duplicates in old notation ODRX_DECLARE_PROPERTY_TRV(QGLWidget) #endif #endif #ifdef OD_GLES2_WIN_RESOURCES ODRX_DECLARE_PROPERTY_TRV(RenderSettingsDlg) #endif // OD_GLES2_WIN_RESOURCES OdPlatformGLES2Device() { } #ifdef OD_GLES2_WIN_RESOURCES ~OdPlatformGLES2Device() { m_rsTestDlg.destroyDialogWindow(); } void put_RenderSettingsDlg(OdIntPtr hParentWnd) { if (!m_rsTestDlg.isDialogPresent()) { QWidget* pWidget = qApp->activeWindow(); // QMainWindow HWND hwnd = (HWND) pWidget->winId(); m_rsTestDlg.createDialogWindow((HWND)hParentWnd, (HWND) hwnd, (OdTrRndRenderSettingsManager*)get_RenderSettings()); } else if (!hParentWnd) m_rsTestDlg.destroyDialogWindow(); } OdIntPtr get_RenderSettingsDlg() const { if (m_rsTestDlg.isDialogPresent()) return 1; return 0; } #endif // OD_GLES2_WIN_RESOURCES # if QT_VERSION >= QT_VERSION_CHECK(5,4,0) QWidget* put_QOpenGLWidget(QWidget* pQWidget) { if (pQWidget == m_pQWidget) return pQWidget; QWidget* pQWidgetPrev = m_pQWidget; ODA_ASSERT_ONCE(m_pQWindow.isNull() || !pQWidget); m_pQWidget = pQWidget; return pQWidgetPrev; } OdIntPtr put_QOpenGLWidget(OdIntPtr ptrQWidget) { QWidget* pQWidget = qobject_cast((QObject*)ptrQWidget); return (OdIntPtr)(QObject*)put_QOpenGLWidget(pQWidget); } OdIntPtr get_QOpenGLWidget() const { return (OdIntPtr)(QObject*)m_pQWidget; } QWindow* put_QOpenGLWindow(QWindow* pQWindow) { if (pQWindow == m_pQWindow) return pQWindow; QWindow* pWindowPrev = m_pQWindow; ODA_ASSERT_ONCE(!pQWindow || m_pQWidget.isNull()); m_pQWindow = pQWindow; return pWindowPrev; } OdIntPtr put_QOpenGLWindow(OdIntPtr ptrQWindow) { QWindow* pQWindow = qobject_cast((QObject*)ptrQWindow); return (OdIntPtr)(QObject*)put_QOpenGLWindow(pQWindow); } OdIntPtr get_QOpenGLWindow() const { return (OdIntPtr)(QObject*)m_pQWindow; } # if QT_VERSION < QT_VERSION_CHECK(6,0,0) QWindow* put_QGLWindow(QWindow* pQWindow) { if (pQWindow == m_pQWindow) return pQWindow; QWindow* pQWindowPrev = m_pQWindow; ODA_ASSERT_ONCE(!pQWindow || m_pQWidget.isNull()); m_pQWindow = pQWindow; return pQWindowPrev; } OdIntPtr put_QGLWindow(OdIntPtr ptrQWindow) { QWindow* pQWindow = qobject_cast((QObject*)ptrQWindow); return (OdIntPtr)(QObject*)put_QGLWindow(pQWindow); } OdIntPtr get_QGLWindow() const { return (OdIntPtr)(QObject*)m_pQWindow; } QWidget* put_QGLWidget(QWidget* pQWidget) { if (pQWidget == m_pQWidget) return pQWidget; QWidget* pQWidgetPrev = m_pQWidget; ODA_ASSERT_ONCE(!pQWidget || m_pQWindow.isNull()); m_pQWidget = pQWidget; return pQWidgetPrev; } OdIntPtr put_QGLWidget(OdIntPtr ptrQWidget) { QWidget* pQWidget = qobject_cast((QObject*) ptrQWidget); return (OdIntPtr)(QObject*) put_QGLWidget(pQWidget); } OdIntPtr get_QGLWidget() const { return (OdIntPtr)(QObject*)m_pQWidget; } QGLWidget* getQGLWidget() const { return qobject_cast(m_pQWidget); } # endif QOpenGLWindow* getQOpenGLWindow() const { return qobject_cast(m_pQWindow); } QOpenGLWidget* getQOpenGLWidget() const { return qobject_cast(m_pQWidget); } # endif static bool makeCurrentContext(QObject* pQObject, bool checkIsValid = true) { # if QT_VERSION >= QT_VERSION_CHECK(5,4,0) if (QOpenGLWindow* pQOpenGLWindow = qobject_cast(pQObject)) { if (checkIsValid && !pQOpenGLWindow->isValid()) return false; pQOpenGLWindow->makeCurrent(); } else if (QOpenGLWidget* pQOpenGLWidget = qobject_cast(pQObject)) { if (checkIsValid && !pQOpenGLWidget->isValid()) return false; pQOpenGLWidget->makeCurrent(); } else # endif # if QT_VERSION < QT_VERSION_CHECK(6,0,0) if (QGLWidget* pQGLWidget = qobject_cast(pQObject)) { if (checkIsValid && !pQGLWidget->isValid()) return false; pQGLWidget->makeCurrent(); } else # endif return false; return true; } void generateProperties(OdRxDictionary* pInfo) const { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) ODRX_GENERATE_PROPERTY_TRV(QOpenGLWindow) ODRX_GENERATE_PROPERTY_TRV(QOpenGLWidget) #if QT_VERSION < QT_VERSION_CHECK(6,0,0) ODRX_GENERATE_PROPERTY_TRV(QGLWindow) // duplicates in old notation ODRX_GENERATE_PROPERTY_TRV(QGLWidget) #endif #endif #ifdef OD_GLES2_WIN_RESOURCES ODRX_GENERATE_PROPERTY_TRV(RenderSettingsDlg) #endif // OD_GLES2_WIN_RESOURCES } void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen, bool bMobile, bool bDynamicVBO) { #if defined(ANDROID) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED) bMobile = true; #endif _OdPlatformGLES2Device::configureForPlatform(pRenderClient, bOffScreen, bMobile, bDynamicVBO); } }; #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, QOpenGLWindow, OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, QOpenGLWidget, OdPlatformGLES2Device, getIntPtr) #if QT_VERSION < QT_VERSION_CHECK(6,0,0) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, QGLWindow, OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, QGLWidget, OdPlatformGLES2Device, getIntPtr) #endif #endif #ifdef OD_GLES2_WIN_RESOURCES ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, RenderSettingsDlg, OdPlatformGLES2Device, getIntPtr) #endif // OD_GLES2_WIN_RESOURCES #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) #if 0 template class OdqOpenGLOffscreenGles : public T // QOpenGLWindow or QOpenGLWidget { protected: OdTrVectorizerUpdateHost *m_pCb; OdGsDCRect *m_pRect; QSurfaceFormat m_fmt; bool m_isWidget; void paintGL() { m_pCb->hostUpdate(m_pRect); } public: //explicit OdqOpenGLOffscreenGles(const QSurfaceFormat& format, Qt::WindowFlags f = Qt::Widget) //: QOpenGLWidget(NULL, f) explicit OdqOpenGLOffscreenGles(const QSurfaceFormat& format, bool isWidget) : T() , m_pCb(NULL) , m_pRect(NULL) , m_fmt(format) , m_isWidget(isWidget) { T::setFormat(format); //QSurfaceFormat::setDefaultFormat(format); } public: QPixmap renderPixmap(OdTrVectorizerUpdateHost *pCb, OdTrVisRenderClient *pClient, OdGsDCRect *pRect) { //m_pCb = pCb; //m_pRect = pRect; //return QOpenGLWidget::renderPixmap(pClient->outputWindowWidth(), pClient->outputWindowHeight()); //, true); renderToImage(pCb, pClient, pRect); QImage img = T::grabFramebuffer(); ODA_ASSERT_VAR(int w_ = img.width(); int w = pClient->outputWindowWidth(); int h_ = img.height(); int h = pClient->outputWindowHeight();) ODA_ASSERT_ONCE(w == w_ && h == h_); if (false) img.save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\grab.bmp", "BMP"); return QPixmap::fromImage(img); } void renderToImage(OdTrVectorizerUpdateHost *pCb, OdTrVisRenderClient *pClient, OdGsDCRect *pRect) { m_pCb = pCb; m_pRect = pRect; T::makeCurrent(); //QGLContext* pContext = const_cast(context()); QOpenGLContext* pContext = T::context(); ODA_ASSERT_ONCE(pContext && pContext->isValid()); if (pContext) pContext->create(); T::makeCurrent(); T::initializeGL(); int w = pClient->outputWindowWidth(), h = pClient->outputWindowHeight(); T::resizeGL(w, h); T::paintGL(); //# ifdef _DEBUG // QImage img = grabFrameBuffer(); // int w_ = img.width(); // int h_ = img.height(); // ODA_ASSERT_ONCE(w == w_ && h == h_); // img.save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\grab.bmp", "BMP"); //# endif } virtual QSize sizeHint() const { ODA_ASSERT_ONCE(m_pRect); if (!m_pRect) { QSize sz; // problem with qobject_cast as out of moc //sz = T::sizeHint(); //sz = QOpenGLWidget::sizeHint(); if (m_isWidget) sz = ((const QOpenGLWidget*) this)->QOpenGLWidget::sizeHint(); return sz; } QSize sz(Od_abs(m_pRect->m_max.x - m_pRect->m_min.x), Od_abs(m_pRect->m_max.y - m_pRect->m_min.y)); return sz; } }; #endif class OdqOpenGLOffscreen : public QOpenGLWidget // or QOpenGLWindow // public QObject { protected: OdTrVectorizerUpdateHost *m_pCb; OdGsDCRect *m_pRect; QSurfaceFormat m_fmt; void paintGL() { m_pCb->hostUpdate(m_pRect); } public: explicit OdqOpenGLOffscreen(const QSurfaceFormat& fmt) : m_pCb(NULL) , m_pRect(NULL) , m_fmt(fmt) { } public: QPixmap renderPixmap(OdTrVectorizerUpdateHost* pCb, OdTrVisRenderClient* pClient, OdGsDCRect* pRect) { //m_pCb = pCb; //m_pRect = pRect; //return QOpenGLWidget::renderPixmap(pClient->outputWindowWidth(), pClient->outputWindowHeight()); //, true); QImage img = renderToImage(pCb, pClient, pRect); ODA_ASSERT_VAR(int w_ = img.width(); int w = pClient->outputWindowWidth(); int h_ = img.height(); int h = pClient->outputWindowHeight();) ODA_ASSERT_ONCE(w == w_ && h == h_); if (false) img.save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\grab.bmp", "BMP"); return QPixmap::fromImage(img); } QImage renderToImage(OdTrVectorizerUpdateHost* pCb, OdTrVisRenderClient* pClient, OdGsDCRect* pRect) { m_pCb = pCb; m_pRect = pRect; // https://stackoverflow.com/questions/59338015/minimal-opengl-offscreen-rendering-using-qt QOpenGLContext openGLContext; openGLContext.setFormat(m_fmt); openGLContext.create(); ODA_ASSERT_ONCE(openGLContext.isValid()); if (!openGLContext.isValid()) return QImage(); //initializeOpenGLFunctions(); QOffscreenSurface surface; surface.setFormat(m_fmt); surface.create(); ODA_ASSERT_ONCE(surface.isValid()); if (!surface.isValid()) return QImage(); openGLContext.makeCurrent(&surface); int w = pClient->outputWindowWidth(), h = pClient->outputWindowHeight(); if (pRect) { w = Od_abs(pRect->m_max.x - pRect->m_min.x); h = Od_abs(pRect->m_max.y - pRect->m_min.y); } QSize vpSize = QSize(w, h); QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); QOpenGLFramebufferObject fbo(vpSize, fboFormat); QOpenGLFunctions* pFnc = openGLContext.functions(); pFnc->glViewport(0, 0, vpSize.width(), vpSize.height()); // pFnc->glViewport(0, 0, w, h); fbo.bind(); //T::makeCurrent(); //QOpenGLContext* pContext = T::context(); //ODA_ASSERT_ONCE(pContext && pContext->isValid()); //if (pContext) // pContext->create(); //T::makeCurrent(); //T::initializeGL(); //int w = pClient->outputWindowWidth(), // h = pClient->outputWindowHeight(); //T::resizeGL(w, h); //T::paintGL(); //if (false) //{ // openGLContext.functions()->glClearColor(0.3f, 0.0f, 0.7f, 1.0f); // openGLContext.functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //} paintGL(); //pCb->hostUpdate(pRect); if (false) fbo.release(); QImage img = fbo.toImage(); return img; } //virtual QSize sizeHint() const //{ // ODA_ASSERT_ONCE(m_pRect); // QSize sz(Od_abs(m_pRect->m_max.x - m_pRect->m_min.x), // Od_abs(m_pRect->m_max.y - m_pRect->m_min.y)); // return sz; //} }; #endif #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) class OdqOffscreenGles : public QGLWidget { protected: OdTrVectorizerUpdateHost *m_pCb; OdGsDCRect *m_pRect; void paintGL() { m_pCb->hostUpdate(m_pRect); } public: explicit OdqOffscreenGles(const QGLFormat& format, Qt::WindowFlags f = {}) : QGLWidget(format, 0, 0, f) , m_pCb(NULL) , m_pRect(NULL) { } public: QPixmap renderPixmap(OdTrVectorizerUpdateHost *pCb, OdTrVisRenderClient *pClient, OdGsDCRect *pRect) { m_pCb = pCb; m_pRect = pRect; return QGLWidget::renderPixmap(pClient->outputWindowWidth(), pClient->outputWindowHeight()); //, true); } void renderToImage(OdTrVectorizerUpdateHost *pCb, OdTrVisRenderClient *pClient, OdGsDCRect *pRect) { m_pCb = pCb; m_pRect = pRect; makeCurrent(); QGLContext* pContext = const_cast(context()); ODA_ASSERT_ONCE(pContext); if (pContext) pContext->create(); makeCurrent(); initializeGL(); int w = pClient->outputWindowWidth(), h = pClient->outputWindowHeight(); resizeGL(w, h); paintGL(); //# ifdef _DEBUG // QImage img = grabFrameBuffer(); // int w_ = img.width(); // int h_ = img.height(); // ODA_ASSERT_ONCE(w == w_ && h == h_); // img.save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\grab.bmp", "BMP"); //# endif } virtual QSize sizeHint() const { if (m_pRect) return QGLWidget::sizeHint(); QSize sz(Od_abs(m_pRect->m_max.x - m_pRect->m_min.x), Od_abs(m_pRect->m_max.y - m_pRect->m_min.y)); return sz; } }; #endif #elif defined(_WIN32) //#else of if defined(TD_USE_QT_LIB) /* Windows platform device implementation */ class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: OdIntPtr m_WindowHDC; OdIntPtr m_WindowHWND; OdIntPtr m_WGLContext; #ifdef OD_GLES2_WIN_RESOURCES OdGLES2RSTestDialog m_rsTestDlg; #endif // OD_GLES2_WIN_RESOURCES public: ODRX_DECLARE_PROPERTY_TRV(WindowHDC) ODRX_DECLARE_PROPERTY_TRV(WindowHWND) ODRX_DECLARE_PROPERTY_TRV(WGLContext) #ifdef OD_GLES2_WIN_RESOURCES ODRX_DECLARE_PROPERTY_TRV(RenderSettingsDlg) #endif // OD_GLES2_WIN_RESOURCES OdPlatformGLES2Device() : m_WindowHDC(NULL), m_WindowHWND(NULL), m_WGLContext(NULL) { } void put_WindowHDC(OdIntPtr hDc) { m_WindowHDC = hDc; } OdIntPtr get_WindowHDC() const { return m_WindowHDC; } void put_WindowHWND(OdIntPtr hWnd) { m_WindowHWND = hWnd; } OdIntPtr get_WindowHWND() const { return m_WindowHWND; } void put_WGLContext(OdIntPtr glCtx) { m_WGLContext = glCtx; } OdIntPtr get_WGLContext() const { return m_WGLContext; } #ifdef OD_GLES2_WIN_RESOURCES ~OdPlatformGLES2Device() override { m_rsTestDlg.destroyDialogWindow(); } void put_RenderSettingsDlg(OdIntPtr hParentWnd) { if (!m_rsTestDlg.isDialogPresent()) m_rsTestDlg.createDialogWindow((HWND)hParentWnd, (HWND)m_WindowHWND, (OdTrRndRenderSettingsManager*)get_RenderSettings()); } OdIntPtr get_RenderSettingsDlg() const { if (m_rsTestDlg.isDialogPresent()) return 1; return 0; } #endif // OD_GLES2_WIN_RESOURCES void generateProperties(OdRxDictionary* pInfo) const override { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(WindowHDC) ODRX_GENERATE_PROPERTY_TRV(WindowHWND) ODRX_GENERATE_PROPERTY_TRV(WGLContext) #ifdef OD_GLES2_WIN_RESOURCES ODRX_GENERATE_PROPERTY_TRV(RenderSettingsDlg) #endif // OD_GLES2_WIN_RESOURCES } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, WindowHDC , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, WindowHWND , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, WGLContext , OdPlatformGLES2Device, getIntPtr) #ifdef OD_GLES2_WIN_RESOURCES ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, RenderSettingsDlg, OdPlatformGLES2Device, getIntPtr) #endif // OD_GLES2_WIN_RESOURCES #elif defined(OD_TRGL2_IOS) /* iOS platform device implementation */ class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: OdIntPtr m_EAGLLayer; OdIntPtr m_EAGLContext; public: ODRX_DECLARE_PROPERTY_TRV(EAGLLayer) ODRX_DECLARE_PROPERTY_TRV(EAGLContext) OdPlatformGLES2Device() : m_EAGLLayer(NULL), m_EAGLContext(NULL) { } void put_EAGLLayer(OdIntPtr pLayer) { m_EAGLLayer = pLayer; } OdIntPtr get_EAGLLayer() const { return m_EAGLLayer; } void put_EAGLContext(OdIntPtr pContext) { m_EAGLContext = pContext; } OdIntPtr get_EAGLContext() const { return m_EAGLContext; } void generateProperties(OdRxDictionary* pInfo) const { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(EAGLLayer) ODRX_GENERATE_PROPERTY_TRV(EAGLContext) } void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen, bool bMobile, bool bDynamicVBO) { bMobile = true; _OdPlatformGLES2Device::configureForPlatform(pRenderClient, bOffScreen, bMobile, bDynamicVBO); } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, EAGLLayer , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, EAGLContext, OdPlatformGLES2Device, getIntPtr) #elif defined(ANDROID) /* Android platform device implementation */ class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: OdIntPtr m_NativeWindow; OdIntPtr m_WindowDisplay; OdIntPtr m_EGLDisplay; OdIntPtr m_EGLSurface; OdIntPtr m_EGLContext; public: ODRX_DECLARE_PROPERTY_TRV(ANativeWindow) ODRX_DECLARE_PROPERTY_TRV(WindowDisplay) ODRX_DECLARE_PROPERTY_TRV(EGLDisplay) ODRX_DECLARE_PROPERTY_TRV(EGLSurface) ODRX_DECLARE_PROPERTY_TRV(EGLContext) OdPlatformGLES2Device() : m_NativeWindow(NULL), m_WindowDisplay(NULL), m_EGLDisplay(NULL), m_EGLSurface(NULL), m_EGLContext(NULL) { } void put_ANativeWindow(OdIntPtr pWindow) { m_NativeWindow = pWindow; } OdIntPtr get_ANativeWindow() const { return m_NativeWindow; } void put_WindowDisplay(OdIntPtr pDisplay) { m_WindowDisplay = pDisplay; } OdIntPtr get_WindowDisplay() const { return m_WindowDisplay; } void put_EGLDisplay(OdIntPtr pDisplay) { m_EGLDisplay = pDisplay; } OdIntPtr get_EGLDisplay() const { return m_EGLDisplay; } void put_EGLSurface(OdIntPtr pSurf) { m_EGLSurface = pSurf; } OdIntPtr get_EGLSurface() const { return m_EGLSurface; } void put_EGLContext(OdIntPtr pCtx) { m_EGLContext = pCtx; } OdIntPtr get_EGLContext() const { return m_EGLContext; } void generateProperties(OdRxDictionary* pInfo) const { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(ANativeWindow) ODRX_GENERATE_PROPERTY_TRV(WindowDisplay) ODRX_GENERATE_PROPERTY_TRV(EGLDisplay) ODRX_GENERATE_PROPERTY_TRV(EGLSurface) ODRX_GENERATE_PROPERTY_TRV(EGLContext) } void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen, bool bMobile, bool bDynamicVBO) { bMobile = true; _OdPlatformGLES2Device::configureForPlatform(pRenderClient, bOffScreen, bMobile, bDynamicVBO); } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, ANativeWindow, OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, WindowDisplay, OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, EGLDisplay , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, EGLSurface , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, EGLContext , OdPlatformGLES2Device, getIntPtr) #elif defined(EMCC) /* Emscripten cross-compiler device implementation */ class OdPlatformGLES2Device : public _OdPlatformGLES2Device { public: OdPlatformGLES2Device() {} DeviceSetupType deviceSetupOverride() const { return kDtOnScreen; } // Avoid partial update generation void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen, bool bMobile, bool bDynamicVBO) { bOffScreen = false; /* To enable overlays */ bMobile = true; /* To disable sharing */ bDynamicVBO = true; /* WebGL specific */ _OdPlatformGLES2Device::configureForPlatform(pRenderClient, bOffScreen, bMobile, bDynamicVBO); } }; #elif defined(__linux__) /* Linux platform device implementation */ OdIntPtr odGLES2X11ChooseVisual(OdIntPtr display, bool bDoubleBufferEnabled); class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: OdIntPtr m_xDisplay; OdIntPtr m_xWindow; mutable OdIntPtr m_xVisual; OdIntPtr m_xContext; public: ODRX_DECLARE_PROPERTY_TRV(XDisplay) ODRX_DECLARE_PROPERTY_TRV(XWindow) ODRX_DECLARE_PROPERTY_TRV(XChooseVisual) ODRX_DECLARE_PROPERTY_TRV(GLXContext) OdPlatformGLES2Device() { m_xDisplay = 0; m_xWindow = 0; m_xVisual = 0; m_xContext = 0; } OdIntPtr getXDisplay() const { return m_xDisplay; } void setXDisplay(OdIntPtr dp) { m_xDisplay = dp; } OdIntPtr getXWindow() const { return m_xWindow; } void setXWindow(OdIntPtr win) { m_xWindow = win; } void setChooseVisual(OdIntPtr /*vinfo*/) { /* Could be answered only */ } OdIntPtr chooseVisual() const { if (!m_xVisual) m_xVisual = ::odGLES2X11ChooseVisual(m_xDisplay, m_pRenderClient->getProperty(OD_T("DoubleBufferEnabled"))->getBool()); return m_xVisual; } OdIntPtr getXContext() const { return m_xContext; } void setXContext(OdIntPtr ctx) { m_xContext = ctx; } void generateProperties(OdRxDictionary* pInfo) const { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(XDisplay) ODRX_GENERATE_PROPERTY_TRV(XWindow) ODRX_GENERATE_PROPERTY_TRV(XChooseVisual) ODRX_GENERATE_PROPERTY_TRV(GLXContext) } }; ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdPlatformGLES2Device::, XDisplay , OdPlatformGLES2Device, getXDisplay , setXDisplay , getIntPtr) ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdPlatformGLES2Device::, XWindow , OdPlatformGLES2Device, getXWindow , setXWindow , getIntPtr) ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdPlatformGLES2Device::, XChooseVisual, OdPlatformGLES2Device, chooseVisual, setChooseVisual, getIntPtr) ODRX_DEFINE_PROPERTY_METHODS_PREFIX_TRV(OdPlatformGLES2Device::, GLXContext , OdPlatformGLES2Device, getXContext , setXContext , getIntPtr) #elif defined(__APPLE__) /* MacOS platform device implementation */ class OdPlatformGLES2Device : public _OdPlatformGLES2Device { protected: OdIntPtr m_NSView; OdIntPtr m_NSOpenGLContext; public: ODRX_DECLARE_PROPERTY_TRV(NSView) ODRX_DECLARE_PROPERTY_TRV(NSOpenGLContext) OdPlatformGLES2Device() : m_NSView(NULL), m_NSOpenGLContext(NULL) { } void put_NSView(OdIntPtr pWindow) { m_NSView = pWindow; } OdIntPtr get_NSView() const { return m_NSView; } void put_NSOpenGLContext(OdIntPtr pContext) { m_NSOpenGLContext = pContext; } OdIntPtr get_NSOpenGLContext() const { return m_NSOpenGLContext; } void generateProperties(OdRxDictionary* pInfo) const { ODRX_INHERIT_PROPERTIES_TRV(_OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(NSView) ODRX_GENERATE_PROPERTY_TRV(NSOpenGLContext) } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, NSView , OdPlatformGLES2Device, getIntPtr) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformGLES2Device::, NSOpenGLContext, OdPlatformGLES2Device, getIntPtr) #else #pragma MARKMESSAGE("Unknown platform."); typedef _OdPlatformGLES2Device OdPlatformGLES2Device; #endif #ifndef TD_USE_QT_LIB class OdPlatformBitmapGLES2Device : public OdGLES2PlatformBaseDevice { protected: enum PropFlagsBmp { kOffscreenSceneGraph = kLastPropFlag << 1, kLastBmpPropFlag = kOffscreenSceneGraph }; protected: OdUInt32 m_idExternalFBO; public: ODRX_DECLARE_PROPERTY_TRV(ExternalFBO) ODRX_DECLARE_PROPERTY_TRV(ForceOffscreenSceneGraph) OdPlatformBitmapGLES2Device() : m_idExternalFBO(0) {} void put_ExternalFBO(OdUInt32 idExternalFBO) { m_idExternalFBO = idExternalFBO; } OdUInt32 get_ExternalFBO() const { return m_idExternalFBO; } void put_ForceOffscreenSceneGraph(bool bForceSg) { SETBIT(m_nPropFlags, kOffscreenSceneGraph, bForceSg); } bool get_ForceOffscreenSceneGraph() const { return GETBIT(m_nPropFlags, kOffscreenSceneGraph); } OdRxDictionaryPtr createPropertiesContainer() const override { static OdRxDictionaryPtr pDict = ::odrxCreateRxDictionary(); return pDict; } void generateProperties(OdRxDictionary* pInfo) const override { ODRX_INHERIT_PROPERTIES_TRV(OdGLES2PlatformBaseDevice); ODRX_GENERATE_PROPERTY_TRV(ExternalFBO) ODRX_GENERATE_PROPERTY_TRV(ForceOffscreenSceneGraph) } #ifdef EMCC DeviceSetupType deviceSetupOverride() const { return kDtOnScreen; } // Avoid partial update generation void configureForPlatform(OdTrVisRenderClient *pRenderClient, bool bOffScreen, bool bMobile, bool bDynamicVBO) { bOffScreen = false; /* To enable overlays */ bMobile = true; /* To disable sharing */ bDynamicVBO = true; /* WebGL specific */ OdGLES2PlatformBaseDevice::configureForPlatform(pRenderClient, bOffScreen, bMobile, bDynamicVBO); } #else DeviceSetupType deviceSetupOverride() const override { if (get_ForceOffscreenSceneGraph() || (renderClient()->hasProperty(OD_T("ForcePartialUpdate")) && renderClient()->getProperty(OD_T("ForcePartialUpdate"))->getBool())) return kDtOnScreen; return kDtOffScreen; } #endif }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformBitmapGLES2Device::, ExternalFBO, OdPlatformBitmapGLES2Device, getUInt32) ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformBitmapGLES2Device::, ForceOffscreenSceneGraph, OdPlatformBitmapGLES2Device, getBool) typedef OdTrVecLocalRenditionGsClient OdGLES2RenditionGsClient; #else // TD_USE_QT_LIB class OdPlatformBitmapGLES2Device : public OdPlatformGLES2Device { ODRX_DECLARE_PROPERTY_TRV(QImageFrame) protected: QImage* m_pFrame; #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) OdSharedPtr m_pOpenGlCtx; // OdSharedPtr m_pOpenGlCtx; #else OdSharedPtr m_pGlCtx; #endif public: ODRX_USING_HEAP_OPERATORS(OdPlatformGLES2Device); OdPlatformBitmapGLES2Device() : m_pFrame(NULL) { } void createContext() { #if 0 // QT_VERSION >= QT_VERSION_CHECK(5,4,0) ODA_ASSERT_ONCE(m_pQWidget.isNull()); bool useQOpenGLWindow = false, useQOpenGLWidget = false; if (m_pQWindow.data()) useQOpenGLWindow = true; else if (m_pQWidget.data()) useQOpenGLWidget = (getQOpenGLWidget() != NULL); //# if QT_VERSION >= QT_VERSION_CHECK(6,0,0) // if (!useQOpenGLWindow && !useQOpenGLWidget) // { // if (false) // useQOpenGLWindow = true; // else // useQOpenGLWidget = true; // } //# endif if (useQOpenGLWindow || useQOpenGLWidget) { if (m_pOpenGlCtx.get()) return; m_pRenderClient->setProperty(OD_T("DoubleBufferEnabled"), OdRxVariantValue(false)); QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); fmt.setVersion(2, 1); fmt.setProfile(QSurfaceFormat::CompatibilityProfile); // SUP-5015 if (false) fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer); else fmt.setSwapBehavior(QSurfaceFormat::SingleBuffer); //m_pOpenGlCtx = new OdqOpenGLOffscreenGles(fmt); if (useQOpenGLWindow) { m_pOpenGlCtx = new OdqOpenGLOffscreenGles(fmt, false); m_pQWindow = qobject_cast(m_pOpenGlCtx.get()); ODA_ASSERT_ONCE(m_pQWindow.data()) m_pQWidget = QWidget::createWindowContainer(m_pQWindow); ODA_ASSERT_ONCE(m_pQWidget.data()) } else if (useQOpenGLWidget) { m_pOpenGlCtx = new OdqOpenGLOffscreenGles(fmt, true); m_pQWidget = qobject_cast(m_pOpenGlCtx.get()); ODA_ASSERT_ONCE(m_pQWidget.data()) } return; } #endif #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (m_pOpenGlCtx.get()) return; m_pRenderClient->setProperty(OD_T("DoubleBufferEnabled"), OdRxVariantValue(false)); QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); fmt.setVersion(2, 1); fmt.setProfile(QSurfaceFormat::CompatibilityProfile); // SUP-5015 if (false) fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer); else fmt.setSwapBehavior(QSurfaceFormat::SingleBuffer); m_pOpenGlCtx = new OdqOpenGLOffscreen(fmt); ODA_ASSERT_ONCE(m_pOpenGlCtx.get()) #else if (m_pGlCtx.get()) return; m_pRenderClient->setProperty(OD_T("DoubleBufferEnabled"), OdRxVariantValue(false)); QGLFormat format = QGLFormat::defaultFormat(); format.setProfile(QGLFormat::CompatibilityProfile); // SUP-5015 format.setDoubleBuffer(false); m_pGlCtx = new OdqOffscreenGles(format); m_pQWidget = m_pGlCtx; #endif } OdRxDictionaryPtr createPropertiesContainer() const { static OdRxDictionaryPtr pDict = ::odrxCreateRxDictionary(); return pDict; } void generateProperties(OdRxDictionary* pInfo) const { if (pInfo->has("RasterImage")) pInfo->remove(OD_T("RasterImage")); if (pInfo->has("BitPerPixel")) pInfo->remove(OD_T("BitPerPixel")); ODRX_INHERIT_PROPERTIES_TRV(OdPlatformGLES2Device); ODRX_GENERATE_PROPERTY_TRV(QImageFrame) } bool onRenderingBegin(OdGsDCRect* pUpdatedRect = NULL, OdTrVectorizerUpdateHost* pUpdateHost = NULL) { ODA_ASSERT(m_pFrame); if (!m_pFrame) return false; bool bCreate = false; # if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (m_pOpenGlCtx.isNull()) # else if (m_pGlCtx.isNull()) # endif bCreate = true; if (bCreate) createContext(); int w = m_pRenderClient->outputWindowWidth(), h = m_pRenderClient->outputWindowHeight(); if (pUpdatedRect) { w = Od_abs(pUpdatedRect->m_max.x - pUpdatedRect->m_min.x); h = Od_abs(pUpdatedRect->m_max.y - pUpdatedRect->m_min.y); } // resize gives us incorrect result without it # if QT_VERSION >= QT_VERSION_CHECK(6,0,0) //if (m_pOpenGlCtx.get() && m_pQWindow.data()) //{ // QOpenGLWindow* pWindow = qobject_cast(m_pOpenGlCtx.get()); // ODA_ASSERT_ONCE(pWindow); // OdqOpenGLOffscreenGles* pOpenGlCtx // = (OdqOpenGLOffscreenGles*) pWindow; // as out of moc // pOpenGlCtx->setMaximumWidth(w); pOpenGlCtx->setMinimumWidth(w); // pOpenGlCtx->setMaximumHeight(h); pOpenGlCtx->setMinimumHeight(h); // pOpenGlCtx->resize(w, h); // ODA_ASSERT_VAR(QSize sz = pOpenGlCtx->size();) // ODA_ASSERT_ONCE(w == sz.width() && h == sz.height()); // pOpenGlCtx->renderToImage(pUpdateHost, m_pRenderClient, pUpdatedRect); // // @@@test // //if (false) // // m_pFrame->save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\test.bmp", "BMP"); // return false; // ? //} //else if (m_pOpenGlCtx.get() && m_pQWidget.data()) //{ // QOpenGLWidget* pWidget = qobject_cast(m_pOpenGlCtx.get()); // ODA_ASSERT_ONCE(pWidget); // OdqOpenGLOffscreenGles* pOpenGlCtx // = (OdqOpenGLOffscreenGles*) pWidget; // as out of moc // pOpenGlCtx->setMaximumWidth(w); pOpenGlCtx->setMinimumWidth(w); // pOpenGlCtx->setMaximumHeight(h); pOpenGlCtx->setMinimumHeight(h); // pOpenGlCtx->resize(w, h); // ODA_ASSERT_VAR(QSize sz = pOpenGlCtx->size();) // ODA_ASSERT_ONCE(w == sz.width() && h == sz.height()); // pOpenGlCtx->renderToImage(pUpdateHost, m_pRenderClient, pUpdatedRect); // // @@@test // //if (false) // // m_pFrame->save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\test.bmp", "BMP"); // return false; // ? //} if (m_pOpenGlCtx.get() && m_pQWindow.isNull() && m_pQWidget.isNull()) { OdqOpenGLOffscreen* pOpenGlCtx = m_pOpenGlCtx.get(); QImage img = pOpenGlCtx->renderToImage(pUpdateHost, m_pRenderClient, pUpdatedRect); if (m_pFrame) *m_pFrame = img; // @@@test if (false) m_pFrame->save("e:\\_Oda\\data\\_ode\\prod-176 qt6 with opengl\\plot_qt6.bmp", "BMP"); return false; // ? } # else if (m_pGlCtx.get()) { m_pGlCtx->setMaximumWidth(w); m_pGlCtx->setMinimumWidth(w); m_pGlCtx->setMaximumHeight(h); m_pGlCtx->setMinimumHeight(h); m_pGlCtx->resize(w, h); ODA_ASSERT_VAR(QSize sz = m_pGlCtx->size();) ODA_ASSERT_ONCE(w == sz.width() && h == sz.height()); m_pGlCtx->renderToImage(pUpdateHost, m_pRenderClient, pUpdatedRect); } *m_pFrame = m_pFrame->mirrored(); // @@@test //if (false) // m_pFrame->save("e:\\_Oda\\data\\_print_plot\\SUP-926 Whiteprint\\test.bmp", "BMP"); //return false; // ? # endif return false; } bool hasDirectRenderBuffer(bool* /*bTransparent*/ = NULL) const { return true; } OdUInt8 *getDirectRenderBuffer(OdUInt32* pWidth, OdUInt32* pHeight, OdUInt32* pFormat = NULL, OdUInt32* pAlignment = NULL) { OdUInt32 width = m_pRenderClient->outputWindowWidth(), height = m_pRenderClient->outputWindowHeight(), format = OdTrVisRenderClient::kRBufFmtRGB, alignment = 4; if (pWidth) *pWidth = width; if (pHeight) *pHeight = height; if (pFormat) *pFormat = format; if (pAlignment) *pAlignment = alignment; ODA_ASSERT(m_pFrame); if (m_pFrame) { ODA_ASSERT_ONCE(alignment == 4 || alignment == 1); //# if QT_VERSION < QT_VERSION_CHECK(5,0,0) enum QImage::Format fmt = QImage::Format_RGB888; // = QImage::Format_RGB32; //format = OdTrVisRenderClient::kRBufFmtRGB; //# else // enum QImage::Format fmt = QImage::Format_RGBA8888; // format = OdTrVisRenderClient::kRBufFmtRGBA; //# endif if (pFormat) *pFormat = format, *m_pFrame = QImage(width, height, fmt); uchar* pBits = m_pFrame->bits(); ODA_ASSERT_VAR(int szColors = m_pFrame->colorCount();) ODA_ASSERT_ONCE(!szColors); ODA_ASSERT_VAR(OdUInt32 szPerLine = m_pFrame->bytesPerLine();) ODA_ASSERT_ONCE( (alignment == 4 && szPerLine == OdGiRasterImage::calcBMPScanLineSize(width, 24)) || (alignment == 1 && szPerLine == width * 3)); m_pFrame->fill(Qt::white); return pBits; } return NULL; } void put_QImageFrame(OdIntPtr i) { m_pFrame = (QImage*)i; } OdIntPtr get_QImageFrame() const { return (OdIntPtr)m_pFrame; } }; ODRX_DEFINE_PROPERTY_PREFIX_TRV(OdPlatformBitmapGLES2Device::, QImageFrame, OdPlatformBitmapGLES2Device, getIntPtr) #include "gl2/TrGL2LocalContext.h" class OdGLES2QtRenditionGsClient : public OdTrVecLocalRenditionGsClient, protected OdTrVisRenderClient { protected: OdTrRndLocalContextPtr m_pExtContext; virtual bool hasProperty(const OdChar *pPropName) const { return !odStrCmp((const wchar_t*) pPropName, L"CreateContext"); } virtual OdRxVariantValue getProperty(const OdChar */*pPropName*/) const { return OdRxVariantValue(false); } virtual void setProperty(const OdChar * /*pPropName*/, OdRxVariantValue /*pValue*/) {} virtual int outputWindowWidth() const { return 0; } virtual int outputWindowHeight() const { return 0; } virtual void emitError(const char * /*pError*/) {} virtual void emitWarning(const char * /*pWarn*/) {} public: virtual OdTrRndLocalContextPtr createLocalContext(OdTrVisRenderClient *pDevice) { if (m_pExtContext.isNull()) { m_pExtContext = renderModule()->createLocalContext(this); m_pExtContext->createContext(this); } return OdTrGL2LocalContext::createLocalContext(pDevice); } virtual OdRxObjectPtr getPropertyObject(const OdChar* /*pPropName*/) const { return OdRxObjectPtr(); } virtual void setPropertyObject(const OdChar* /*pPropName*/, OdRxObjectPtr /*pValue*/) { } static OdTrRndLocalRenditionClientPtr createObject(OdTrRndRenderModule *pRenderModule) { OdSmartPtr pRC = OdRxObjectImpl::createObject(); pRC->m_pRenderModule = pRenderModule; return pRC; } }; typedef OdGLES2QtRenditionGsClient OdGLES2RenditionGsClient; #endif // TD_USE_QT_LIB class GLES2Module : public BaseTrVecModule { protected: OdTrRndLocalRenditionClientPtr m_pRenditionClient; OdTrVectorizerModuleHostPtr setupModuleHost(OdTrVectorizerModuleHost *pModuleHost) { if (m_pRenditionClient.isNull()) { OdTrRndRenderModulePtr pRenderModule = ::odrxDynamicLinker()->loadModule(OdTrGL2ModuleName, false); m_pRenditionClient = OdGLES2RenditionGsClient::createObject(pRenderModule); } static_cast(pModuleHost)->setRenditionClient(m_pRenditionClient); return pModuleHost; } protected: OdSmartPtr createDeviceObject() override { return createVectorizeDevice(setupModuleHost(OdRxObjectImpl::createObject()), OdTrVectorizerModuleHost::kDtOnScreen); } OdSmartPtr createViewObject() override { return createVectorizeView(); } OdSmartPtr createBitmapDeviceObject() override { return createVectorizeDevice(setupModuleHost(OdRxObjectImpl::createObject()), OdTrVectorizerModuleHost::kDtOffScreen); } OdSmartPtr createBitmapViewObject() override { return createVectorizeView(); } void initApp() override; void uninitApp() override; }; ODRX_DEFINE_DYNAMIC_MODULE(GLES2Module); void GLES2Module::initApp() { BaseTrVecModule::initApp(); } void GLES2Module::uninitApp() { BaseTrVecModule::uninitApp(); } #if defined(__linux__) #pragma GCC diagnostic pop #endif //