//! Returns unique ID used to manage resource in graphic driver.
const TCollection_AsciiString& GetId() const { return myID; }
+ //! Returns GLSL header (version code and extensions).
+ const TCollection_AsciiString& Header() const { return myHeader; }
+
+ //! Setup GLSL header containing language version code and used extensions.
+ //! Will be prepended to the very beginning of the source code.
+ //! Example:
+ //! @code
+ //! #version 300 es
+ //! #extension GL_ARB_bindless_texture : require
+ //! @endcode
+ void SetHeader (const TCollection_AsciiString& theHeader) { myHeader = theHeader; }
+
//! Attaches shader object to the program object.
Standard_EXPORT Standard_Boolean AttachShader (const Handle(Graphic3d_ShaderObject)& theShader);
TCollection_AsciiString myID; //!< The unique identifier of program object.
Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects.
Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables.
+ TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions
};
};
+//! FBO blit is available in OpenGL 3.0+.
+//! Moved out from OpenGl_ArbFBO since it is unavailable in OpenGL ES 2.0.
+struct OpenGl_ArbFBOBlit : protected OpenGl_GlFunctions
+{
+
+ using OpenGl_GlFunctions::glBlitFramebuffer;
+
+};
+
#endif // _OpenGl_ArbFBO_H__
arbIns (NULL),
arbDbg (NULL),
arbFBO (NULL),
+ arbFBOBlit (NULL),
extGS (NULL),
extBgra(Standard_False),
extAnis(Standard_False),
arbIns = NULL;
arbDbg = NULL;
arbFBO = NULL;
+ arbFBOBlit = NULL;
extGS = NULL;
#if defined(GL_ES_VERSION_2_0)
core20 = (OpenGl_GlCore20* )(&(*myFuncs));
core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
- arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
+ arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
+ }
+ if (IsGlGreaterEqual (3, 0)
+ && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
+ {
+ arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
}
hasHighp = CheckExtension ("OES_fragment_precision_high");
// initialize FBO extension (ARB)
if (hasFBO)
{
- arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
+ arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
+ arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
extPDS = Standard_True; // extension for EXT, but part of ARB
}
struct OpenGl_ArbIns;
struct OpenGl_ArbDbg;
struct OpenGl_ArbFBO;
+struct OpenGl_ArbFBOBlit;
struct OpenGl_ExtGS;
struct OpenGl_ArbTexBindless;
OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced
OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output
OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
+ OpenGl_ArbFBOBlit* arbFBOBlit; //!< glBlitFramebuffer function, moved out from OpenGl_ArbFBO structure for compatibility with OpenGL ES 2.0
OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4
Standard_Boolean extBgra; //!< GL_EXT_bgra or GL_EXT_texture_format_BGRA8888 on OpenGL ES
Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic
IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource)
-static inline bool isOddNumber (const GLsizei theNumber)
-{
- return theNumber & 0x01;
-}
-
-static inline GLsizei getEvenNumber (const GLsizei theNumber)
-{
- return isOddNumber (theNumber) ? (theNumber + 1) : theNumber;
-}
-
-//! Notice - 0 is not power of two here
-static inline bool isPowerOfTwo (const GLsizei theNumber)
-{
- return !(theNumber & (theNumber - 1));
-}
-
// =======================================================================
// function : OpenGl_FrameBuffer
// purpose :
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
}
+// =======================================================================
+// function : BindDrawBuffer
+// purpose :
+// =======================================================================
+void OpenGl_FrameBuffer::BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx)
+{
+ theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
+}
+
+// =======================================================================
+// function : BindReadBuffer
+// purpose :
+// =======================================================================
+void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
+{
+ theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
+}
+
// =======================================================================
// function : UnbindBuffer
// purpose :
Standard_EXPORT void ChangeViewport (const GLsizei theVPSizeX,
const GLsizei theVPSizeY);
- //! Bind frame buffer (to render into the texture).
+ //! Bind frame buffer for drawing and reading (to render into the texture).
Standard_EXPORT virtual void BindBuffer (const Handle(OpenGl_Context)& theGlCtx);
+ //! Bind frame buffer for drawing GL_DRAW_FRAMEBUFFER (to render into the texture).
+ Standard_EXPORT virtual void BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx);
+
+ //! Bind frame buffer for reading GL_READ_FRAMEBUFFER
+ Standard_EXPORT virtual void BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx);
+
//! Unbind frame buffer.
Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
#define GL_UNSIGNED_INT_24_8 0x84FA
#define GL_DEPTH24_STENCIL8 0x88F0
+ #define GL_READ_FRAMEBUFFER 0x8CA8
+ #define GL_DRAW_FRAMEBUFFER 0x8CA9
+
// GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
::glVertexAttribPointer (index, size, type, normalized, stride, pointer);
}
+public: //! @name OpenGL ES 3.0
+
+ typedef void (*glBlitFramebuffer_t)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ glBlitFramebuffer_t glBlitFramebuffer;
+
#else // OpenGL ES vs. desktop
public: //! @name OpenGL 1.2
myFlatPrograms = OpenGl_SetOfShaderPrograms();
myMapOfLightPrograms.Clear();
myFontProgram.Nullify();
+ myBlitProgram.Nullify();
switchLightPrograms();
}
return Standard_True;
}
+// =======================================================================
+// function : prepareStdProgramFboBlit
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
+{
+ Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+ TCollection_AsciiString aSrcVert =
+ EOL"THE_SHADER_OUT vec2 TexCoord;"
+ EOL"void main()"
+ EOL"{"
+ EOL" TexCoord = occVertex.zw;"
+ EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
+ EOL"}";
+
+ TCollection_AsciiString aSrcFrag =
+ EOL"uniform sampler2D uColorSampler;"
+ EOL"uniform sampler2D uDepthSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
+ EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
+ EOL"}";
+
+#if defined(GL_ES_VERSION_2_0)
+ if (myContext->IsGlGreaterEqual (3, 0))
+ {
+ aProgramSrc->SetHeader ("#version 300 es");
+ }
+ else
+ {
+ // there is no way to draw into depth buffer
+ aSrcFrag =
+ EOL"uniform sampler2D uColorSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
+ EOL"}";
+ }
+#endif
+
+ aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
+ aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+ TCollection_AsciiString aKey;
+ if (!Create (aProgramSrc, aKey, myBlitProgram))
+ {
+ myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+ return Standard_False;
+ }
+
+ myContext->BindProgram (myBlitProgram);
+ myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
+ myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
+ myContext->BindProgram (NULL);
+ return Standard_True;
+}
+
// =======================================================================
// function : prepareStdProgramFlat
// purpose :
return bindProgramWithState (myFontProgram, theAspect);
}
+ //! Bind program for FBO blit operation.
+ Standard_Boolean BindFboBlitProgram()
+ {
+ if (myBlitProgram.IsNull())
+ {
+ prepareStdProgramFboBlit();
+ }
+ return !myBlitProgram.IsNull()
+ && myContext->BindProgram (myBlitProgram);
+ }
+
public:
//! Returns current state of OCCT light sources.
//! Prepare standard GLSL program for textured font.
Standard_EXPORT Standard_Boolean prepareStdProgramFont();
+ //! Prepare standard GLSL program for FBO blit operation.
+ Standard_EXPORT Standard_Boolean prepareStdProgramFboBlit();
+
//! Prepare standard GLSL program without lighting.
Standard_EXPORT Standard_Boolean prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
const Standard_Integer theBits);
Handle(OpenGl_SetOfShaderPrograms) myLightPrograms; //!< pointer to active lighting programs matrix
OpenGl_SetOfShaderPrograms myFlatPrograms; //!< programs matrix without lighting
Handle(OpenGl_ShaderProgram) myFontProgram; //!< standard program for textured text
+ Handle(OpenGl_ShaderProgram) myBlitProgram; //!< standard program for FBO blit emulation
OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on shading model and lights configuration
OpenGl_Context* myContext; //!< OpenGL context
return Standard_False;
}
+ TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty()
+ ? (myProxy->Header() + "\n")
+ : TCollection_AsciiString();
+
TCollection_AsciiString aDeclarations;
aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
{
case Graphic3d_TOS_VERTEX:
{
- aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+ aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
break;
}
case Graphic3d_TOS_FRAGMENT:
TCollection_AsciiString aPrefix (theCtx->hasHighp
? "precision highp float;\n"
: "precision mediump float;\n");
- aSource = aPrefix + aSource;
+ aSource = aHeader + aPrefix + aSource;
#endif
break;
}
theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName);
return Standard_True;
}
-
+
// =======================================================================
// function : SetAttribute
// purpose :
myBVHSelector.SetViewVolume (myCamera);
}
- const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
- const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
+ const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
+ const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
{
aManager->UpdateLightSourceStateTo (&myLights);
// commercial license or contractual agreement.
#include <OpenGl_GlCore15.hxx>
+#include <OpenGl_ArbFBO.hxx>
#include <InterfaceGraphic.hxx>
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_Sampler.hxx>
+#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Texture.hxx>
#include <OpenGl_Utils.hxx>
#include <OpenGl_View.hxx>
PolygonOffset_applied (THE_DEFAULT_POFFSET)
{
myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ myResultFBO = new OpenGl_FrameBuffer();
if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
{
myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
}
+ if (!myResultFBO.IsNull())
+ {
+ myResultFBO->Release (myGlContext.operator->());
+ myResultFBO.Nullify();
+ }
+ if (myFullScreenQuad.IsValid())
+ {
+ myFullScreenQuad.Release (myGlContext.operator->());
+ }
+
ReleaseRaytraceResources();
}
aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight);
}
+ Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
+ Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
+
+ if (myResultFBO->GetVPSizeX() != aSizeX
+ || myResultFBO->GetVPSizeY() != aSizeY)
+ {
+ myResultFBO->Init (aGlCtx, aSizeX, aSizeY);
+ }
+ if (myResultFBO->IsValid())
+ {
+ myResultFBO->SetupViewport (aGlCtx);
+ }
+
+ const Standard_Boolean isImmediate = myView->HasImmediateStructures()
+ || myResultFBO->IsValid();
+
myToRedrawGL = Standard_True;
if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
&& myComputeInitStatus != OpenGl_RT_FAIL)
myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
SetRenderFilter (myRaytraceFilter);
- Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
- Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
-
if (myOpenGlFBO.IsNull())
{
myOpenGlFBO = new OpenGl_FrameBuffer();
redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
myOpenGlFBO->UnbindBuffer (aGlCtx);
- const Standard_Boolean isImmediate = myView->HasImmediateStructures();
Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
- theCOverLayer, theCUnderLayer, aFrameBuffer);
+ theCOverLayer, theCUnderLayer,
+ myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer);
if (isImmediate)
{
- RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+ RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
}
SetRenderFilter (aRenderFilter);
if (myToRedrawGL)
{
// draw entire frame using normal OpenGL pipeline
- if (aFrameBuffer != NULL)
+ if (myResultFBO->IsValid())
+ {
+ myResultFBO->BindBuffer (aGlCtx);
+ }
+ else if (aFrameBuffer != NULL)
{
aFrameBuffer->BindBuffer (aGlCtx);
}
- const Standard_Boolean isImmediate = myView->HasImmediateStructures();
redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
if (isImmediate)
{
- RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+ RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
}
theCView.WasRedrawnGL = Standard_True;
void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
const Aspect_CLayer2d& theCUnderLayer,
const Aspect_CLayer2d& theCOverLayer,
- const Standard_Boolean theToForce)
+ const Standard_Boolean theToForce,
+ OpenGl_FrameBuffer* theTargetFBO)
{
if (!Activate())
{
#if !defined(GL_ES_VERSION_2_0)
glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
#endif
- if (!myView->HasImmediateStructures())
+ if (!myView->HasImmediateStructures()
+ && !myResultFBO->IsValid())
{
if (theToForce
|| !myIsImmediateDrawn)
return;
}
- if (isDoubleBuffer && myTransientDrawToFront)
+ if (myResultFBO->IsValid()
+ && myGlContext->IsRender())
+ {
+ if (!myBackBufferRestored)
+ {
+ Redraw (theCView, theCUnderLayer, theCOverLayer);
+ return;
+ }
+
+ // clear destination before blitting
+ if (theTargetFBO != NULL)
+ {
+ theTargetFBO->BindBuffer (myGlContext);
+ }
+ else
+ {
+ myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
+ }
+ #if !defined(GL_ES_VERSION_2_0)
+ myGlContext->core20fwd->glClearDepth (1.0);
+ #else
+ myGlContext->core20fwd->glClearDepthf (1.0f);
+ #endif
+ myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ /*#if !defined(GL_ES_VERSION_2_0)
+ if (myGlContext->arbFBOBlit != NULL)
+ {
+ myResultFBO->BindReadBuffer (myGlContext);
+ if (theTargetFBO != NULL)
+ {
+ theTargetFBO->BindDrawBuffer (myGlContext);
+ }
+ else
+ {
+ myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
+ }
+ // we don't copy stencil buffer here... does it matter for performance?
+ myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
+ 0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+
+ if (theTargetFBO != NULL)
+ {
+ theTargetFBO->BindBuffer (myGlContext);
+ }
+ else
+ {
+ myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
+ }
+ }
+ else
+ #endif*/
+ {
+ myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
+ myGlContext->core20fwd->glDepthMask (GL_TRUE);
+ myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
+
+ DisableTexture();
+ if (!myFullScreenQuad.IsValid())
+ {
+ OpenGl_Vec4 aQuad[4] =
+ {
+ OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
+ OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
+ OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
+ OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
+ };
+ myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
+ }
+
+ const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
+ if (myFullScreenQuad.IsValid()
+ && aManager->BindFboBlitProgram())
+ {
+ myResultFBO->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
+ myResultFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
+ myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
+
+ myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
+
+ myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
+ myResultFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
+ myResultFBO->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
+ }
+ }
+ }
+ else if (isDoubleBuffer && myTransientDrawToFront)
{
if (!myBackBufferRestored)
{
aStructure->Render (aWS);
}
- if (isDoubleBuffer && myTransientDrawToFront)
+ if (myResultFBO->IsValid())
+ {
+ if (theTargetFBO == NULL
+ && myGlContext->IsRender()
+ && !myGlContext->caps->buffersNoSwap)
+ {
+ myGlContext->SwapBuffers();
+ }
+ }
+ else if (isDoubleBuffer && myTransientDrawToFront)
{
glFlush();
MakeBackBufCurrent();
void RedrawImmediate (const Graphic3d_CView& theCView,
const Aspect_CLayer2d& theCUnderLayer,
const Aspect_CLayer2d& theCOverLayer,
- const Standard_Boolean theToForce = Standard_False);
+ const Standard_Boolean theToForce = Standard_False,
+ OpenGl_FrameBuffer* theTargetFBO = NULL);
void Invalidate (const Graphic3d_CView& /*theCView*/)
{
//! Framebuffer (FBO) for pre-raytrace rendering by OpenGL.
Handle(OpenGl_FrameBuffer) myOpenGlFBO;
+ //! Framebuffer stores cached main presentation of the view (without presentation of immediate layers).
+ Handle(OpenGl_FrameBuffer) myResultFBO;
+
+ //! Vertices for full-screen quad rendering.
+ OpenGl_VertexBuffer myFullScreenQuad;
+
//! State of OpenGL view.
Standard_Size myViewModificationStatus;
//! State of OpenGL layer list.
#define THE_MAX_LIGHTS 8
#define THE_MAX_CLIP_PLANES 8
+// compatibility macros
+#if (__VERSION__ >= 130)
+ #define THE_ATTRIBUTE in
+ #define THE_SHADER_IN in
+ #define THE_SHADER_OUT out
+ #define THE_OUT out
+ #define occTexture2D texture
+#else
+ #define THE_ATTRIBUTE attribute
+ #define THE_SHADER_IN varying
+ #define THE_SHADER_OUT varying
+ #define THE_OUT
+ #define occTexture2D texture2D
+#endif
+
// Vertex attributes
#ifdef VERTEX_SHADER
- attribute vec4 occVertex;
- attribute vec3 occNormal;
- attribute vec4 occTexCoord;
- attribute vec4 occVertColor;
+ THE_ATTRIBUTE vec4 occVertex;
+ THE_ATTRIBUTE vec3 occNormal;
+ THE_ATTRIBUTE vec4 occTexCoord;
+ THE_ATTRIBUTE vec4 occVertColor;
+#elif (__VERSION__ >= 130)
+ out vec4 occFragColor;
+#else
+ #define occFragColor gl_FragColor
#endif
// Matrix state
+vglinfo
vdump $imagedir/${test_image}.png
puts ""
}
if { [string compare $command "shading"] == 0 } {
+ vglinfo
vdump $imagedir/${test_image}.png
} else {
isos 0