소스 검색

extra draw gui

add the extra functions for drawing gui elements
RoundedRectangle:

All draw rect functions now pass through roundedRectangle which uses a shader and can draw borders, and rounds the corners

Draw thick line:
draws a line thicker than 1 pixel, uses a geometry shader to do this

Draw Circle:
Draws a circle with a border parameter.
marauder2k7 1 년 전
부모
커밋
c9d70de609

+ 263 - 84
Engine/source/gfx/gfxDrawUtil.cpp

@@ -34,7 +34,7 @@
 #include "gfx/gfxPrimitiveBuffer.h"
 #include "gfx/primBuilder.h"
 #include "gfx/gfxDebugEvent.h"
-
+#include "materials/shaderData.h"
 #include "math/mPolyhedron.impl.h"
 
 
@@ -45,7 +45,7 @@ GFXDrawUtil::GFXDrawUtil( GFXDevice * d)
    mTextAnchorColor.set(0xFF, 0xFF, 0xFF, 0xFF);
    mFontRenderBatcher = new FontRenderBatcher();
 
-   _setupStateBlocks();   
+   _setupStateBlocks();
 }
 
 GFXDrawUtil::~GFXDrawUtil()
@@ -90,6 +90,33 @@ void GFXDrawUtil::_setupStateBlocks()
    rectFill.setZReadWrite(false);
    rectFill.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
    mRectFillSB = mDevice->createStateBlock(rectFill);
+
+   // Find ShaderData
+   ShaderData* shaderData;
+   mRoundRectangleShader = Sim::findObject("RoundedRectangleGUI", shaderData) ? shaderData->getShader() : NULL;
+   if (!mRoundRectangleShader)
+   {
+      Con::errorf("GFXDrawUtil - could not find Rounded Rectangle shader");
+   }
+   // Create ShaderConstBuffer and Handles
+   mRoundRectangleShaderConsts = mRoundRectangleShader->allocConstBuffer();
+
+   mCircleShader = Sim::findObject("CircularGUI", shaderData) ? shaderData->getShader() : NULL;
+   if (!mCircleShader)
+   {
+      Con::errorf("GFXDrawUtil - could not find circle shader");
+   }
+   // Create ShaderConstBuffer and Handles
+   mCircleShaderConsts = mCircleShader->allocConstBuffer();
+
+   mThickLineShader = Sim::findObject("ThickLineGUI", shaderData) ? shaderData->getShader() : NULL;
+   if (!mThickLineShader)
+   {
+      Con::errorf("GFXDrawUtil - could not find Thick line shader");
+   }
+   // Create ShaderConstBuffer and Handles
+   mThickLineShaderConsts = mThickLineShader->allocConstBuffer();
+
 }
 
 //-----------------------------------------------------------------------------
@@ -118,13 +145,13 @@ void GFXDrawUtil::setTextAnchorColor( const ColorI &ancColor )
 //-----------------------------------------------------------------------------
 // Draw Text
 //-----------------------------------------------------------------------------
-U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF16 *in_string, 
+U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
                           const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
 {
    return drawTextN( font, ptDraw, in_string, dStrlen(in_string), colorTable, maxColorIndex, rot );
 }
 
-U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF8 *in_string, 
+U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF8 *in_string,
                           const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
 {
    return drawTextN( font, ptDraw, in_string, dStrlen(in_string), colorTable, maxColorIndex, rot );
@@ -154,7 +181,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF8 *in_s
    return drawTextN( font, ptDraw, ubuf, n, colorTable, maxColorIndex, rot );
 }
 
-U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_string, 
+U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
                            U32 n, const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
 {
    // return on zero length strings
@@ -178,11 +205,11 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
 
    S32 ptX = 0;
 
-   // Queue everything for render.   
+   // Queue everything for render.
    mFontRenderBatcher->init(font, n);
 
    U32 i;
-   UTF16 c;   
+   UTF16 c;
    for (i = 0, c = in_string[i]; i < n && in_string[i]; i++, c = in_string[i])
    {
       switch(c)
@@ -193,25 +220,25 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
       case 14:
          {
             // Color code
-            if (colorTable) 
+            if (colorTable)
             {
-               static U8 remap[15] = 
-               { 
+               static U8 remap[15] =
+               {
                   0x0, // 0 special null terminator
                   0x0, // 1 ascii start-of-heading??
-                  0x1, 
-                  0x2, 
-                  0x3, 
-                  0x4, 
-                  0x5, 
-                  0x6, 
+                  0x1,
+                  0x2,
+                  0x3,
+                  0x4,
+                  0x5,
+                  0x6,
                   0x0, // 8 special backspace
                   0x0, // 9 special tab
                   0x0, // a special \n
-                  0x7, 
+                  0x7,
                   0x8,
                   0x0, // a special \r
-                  0x9 
+                  0x9
                };
 
                U8 remapped = remap[c];
@@ -256,7 +283,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
          }
 
          // Tab character
-      case dT('\t'): 
+      case dT('\t'):
          {
             if ( tabci == NULL )
                tabci = &(font->getCharInfo( dT(' ') ));
@@ -272,7 +299,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
          // Don't draw invalid characters.
       default:
          {
-            if( !font->isValidChar( c ) ) 
+            if( !font->isValidChar( c ) )
                continue;
          }
       }
@@ -354,7 +381,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
 {
    // Sanity if no texture is specified.
    if(!texture)
-      return;   
+      return;
 
    GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile );
    verts.lock();
@@ -369,13 +396,13 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
    F32 screenTop    = dstRect.point.y;
    F32 screenBottom = (dstRect.point.y + dstRect.extent.y);
 
-   if( in_flip & GFXBitmapFlip_X ) 
+   if( in_flip & GFXBitmapFlip_X )
    {
       F32 temp = texLeft;
       texLeft = texRight;
       texRight = temp;
    }
-   if( in_flip & GFXBitmapFlip_Y ) 
+   if( in_flip & GFXBitmapFlip_Y )
    {
       F32 temp = texTop;
       texTop = texBottom;
@@ -435,7 +462,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
       AssertFatal(false, "No GFXDrawUtil state block defined for this filter type!");
       mDevice->setStateBlock(mBitmapStretchSB);
       break;
-   }   
+   }
    mDevice->setTexture( 0, texture );
    mDevice->setupGenericShaders( GFXDevice::GSModColorTexture );
 
@@ -445,7 +472,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
 //-----------------------------------------------------------------------------
 // Draw Rectangle
 //-----------------------------------------------------------------------------
-void GFXDrawUtil::drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color ) 
+void GFXDrawUtil::drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color )
 {
    drawRect( Point2F((F32)upperLeft.x,(F32)upperLeft.y),Point2F((F32)lowerRight.x,(F32)lowerRight.y),color);
 }
@@ -513,57 +540,94 @@ void GFXDrawUtil::drawRect( const Point2F &upperLeft, const Point2F &lowerRight,
 //-----------------------------------------------------------------------------
 // Draw Rectangle Fill
 //-----------------------------------------------------------------------------
-void GFXDrawUtil::drawRectFill( const RectF &rect, const ColorI &color )
+void GFXDrawUtil::drawRectFill(const RectF& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
 {
-   drawRectFill(rect.point, Point2F(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color );
+   drawRoundedRect(0.0f, rect.point, Point2F(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
 }
 
-void GFXDrawUtil::drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color ) 
-{   
-   drawRectFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color);
+void GFXDrawUtil::drawRectFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
+{
+   drawRoundedRect(0.0f, Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, borderSize, borderColor);
 }
 
-void GFXDrawUtil::drawRectFill( const RectI &rect, const ColorI &color )
+void GFXDrawUtil::drawRectFill(const RectI& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
 {
-   drawRectFill(rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color );
+   drawRoundedRect(0.0f, rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
 }
 
-void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color )
+void GFXDrawUtil::drawRectFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, const F32& borderSize,const ColorI& borderColor)
+{
+   // draw a rounded rect with 0 radiuse.
+   drawRoundedRect(0.0f, upperLeft, lowerRight, color, borderSize, borderColor);
+}
+
+void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius, const RectI& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
+{
+   drawRoundedRect(cornerRadius, rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
+}
+
+void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius, const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
+{
+   drawRoundedRect(cornerRadius, Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, borderSize, borderColor);
+}
+
+void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius,
+   const Point2F& upperLeft,
+   const Point2F& lowerRight,
+   const ColorI& color,
+   const F32& borderSize,
+   const ColorI& borderColor)
 {
-   //
-   // Convert Box   a----------x
-   //               |          |
-   //               x----------b
-   // Into Quad
-   //               v0---------v1
-   //               | a       x |
-   //               |           |
-   //               | x       b |
-   //               v2---------v3
-   //
 
    // NorthWest and NorthEast facing offset vectors
-   Point2F nw(-0.5,-0.5); /*  \  */
-   Point2F ne(0.5,-0.5); /*  /  */
+   Point2F nw(-0.5, -0.5); /*  \  */
+   Point2F ne(0.5, -0.5); /*  /  */
 
    GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
    verts.lock();
 
    F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
-   
-   verts[0].point.set( upperLeft.x+nw.x + ulOffset, upperLeft.y+nw.y + ulOffset, 0.0f );
-   verts[1].point.set( lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
-   verts[2].point.set( upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
-   verts[3].point.set( lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
+
+   verts[0].point.set(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset, 0.0f);
+   verts[1].point.set(lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
+   verts[2].point.set(upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
+   verts[3].point.set(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
    for (S32 i = 0; i < 4; i++)
       verts[i].color = color;
 
    verts.unlock();
+   mDevice->setVertexBuffer(verts);
 
    mDevice->setStateBlock(mRectFillSB);
-   mDevice->setVertexBuffer( verts );
-   mDevice->setupGenericShaders();
-   mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 );
+
+   Point2F topLeftCorner(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset);
+   Point2F bottomRightCorner(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset);
+
+   /*mDevice->setupGenericShaders();*/
+   GFX->setShader(mRoundRectangleShader);
+   GFX->setShaderConstBuffer(mRoundRectangleShaderConsts);
+
+   MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
+   Point2F size((F32)(bottomRightCorner.x - topLeftCorner.x), (F32)(bottomRightCorner.y - topLeftCorner.y));
+
+   F32 minExtent = mMin(size.x, size.y);
+
+   F32 radius = cornerRadius;
+   if ((minExtent * 0.5) < radius)
+   {
+      radius = mClampF(radius, 0.0f, (minExtent * 0.5));
+   }
+
+   mRoundRectangleShaderConsts->set(mRoundRectangleShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
+   mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$radius"), radius);
+   mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$sizeUni"), size);
+   mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$borderSize"), borderSize);
+   mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$borderCol"), borderColor);
+
+   Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0)));
+   mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$rectCenter"), rectCenter);
+
+   mDevice->drawPrimitive(GFXTriangleStrip, 0, 2);
 }
 
 void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle )
@@ -608,7 +672,73 @@ void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinA
 }
 
 //-----------------------------------------------------------------------------
-// Draw Line
+// Draw Circle : FILL
+//-----------------------------------------------------------------------------
+void GFXDrawUtil::drawCircleFill(const RectI& rect, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
+{
+   drawCircleFill(rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, radius, borderSize, borderColor);
+}
+
+void GFXDrawUtil::drawCircleFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
+{
+   drawCircleFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, radius, borderSize, borderColor);
+}
+
+void GFXDrawUtil::drawCircleFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
+{
+   // NorthWest and NorthEast facing offset vectors
+   Point2F nw(-0.5, -0.5); /*  \  */
+   Point2F ne(0.5, -0.5); /*  /  */
+
+   GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
+   verts.lock();
+
+   F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
+
+   verts[0].point.set(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset, 0.0f);
+   verts[1].point.set(lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
+   verts[2].point.set(upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
+   verts[3].point.set(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
+   for (S32 i = 0; i < 4; i++)
+      verts[i].color = color;
+
+   verts.unlock();
+   mDevice->setVertexBuffer(verts);
+
+   mDevice->setStateBlock(mRectFillSB);
+
+   Point2F topLeftCorner(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset);
+   Point2F bottomRightCorner(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset);
+
+   /*mDevice->setupGenericShaders();*/
+   GFX->setShader(mCircleShader);
+   GFX->setShaderConstBuffer(mCircleShaderConsts);
+
+   MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
+   Point2F size((F32)(bottomRightCorner.x - topLeftCorner.x), (F32)(bottomRightCorner.y - topLeftCorner.y));
+
+   Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0)));
+   mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$rectCenter"), rectCenter);
+
+   F32 minExtent = mMin(size.x, size.y);
+   F32 shaderRadius = radius;
+
+   if ((minExtent * 0.5) < shaderRadius)
+   {
+      shaderRadius = mClampF(radius, 0.0f, (minExtent * 0.5));
+   }
+
+   mCircleShaderConsts->set(mCircleShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
+   mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$radius"), shaderRadius);
+   mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$sizeUni"), size);
+   mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$borderSize"), borderSize);
+   mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$borderCol"), borderColor);
+
+   mDevice->drawPrimitive(GFXTriangleStrip, 0, 2);
+}
+
+//-----------------------------------------------------------------------------
+// Draw Lines : Single Pixel
 //-----------------------------------------------------------------------------
 void GFXDrawUtil::drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color )
 {
@@ -648,6 +778,55 @@ void GFXDrawUtil::drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, cons
    mDevice->drawPrimitive( GFXLineList, 0, 1 );
 }
 
+//-----------------------------------------------------------------------------
+// Draw Lines : Thick
+//-----------------------------------------------------------------------------
+void GFXDrawUtil::drawThickLine(const Point2I& startPt, const Point2I& endPt, const ColorI& color, const F32& thickness)
+{
+   drawThickLine(startPt.x, startPt.y, 0.0f, endPt.x, endPt.y, 0.0f, color, thickness);
+}
+
+void GFXDrawUtil::drawThickLine(const Point2F& startPt, const Point2F& endPt, const ColorI& color, const F32& thickness)
+{
+   drawThickLine(startPt.x, startPt.y, 0.0f, endPt.x, endPt.y, 0.0f, color, thickness);
+}
+
+void GFXDrawUtil::drawThickLine(F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI& color, const F32& thickness)
+{
+   // less than 2 just draw an ordinary line... why you ever here....
+   if (thickness < 2.0f)
+   {
+      drawLine(x1, y1, z1, x2, y2, z2, color);
+      return;
+   }
+
+   GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 2, GFXBufferTypeVolatile);
+   verts.lock();
+
+   verts[0].point.set(x1, y1, z1);
+   verts[1].point.set(x2, y2, z2);
+   verts[0].color = color;
+   verts[1].color = color;
+
+   verts.unlock();
+
+   mDevice->setVertexBuffer(verts);
+   mDevice->setStateBlock(mRectFillSB);
+   GFX->setShader(mThickLineShader);
+   GFX->setShaderConstBuffer(mThickLineShaderConsts);
+
+   MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
+   mThickLineShaderConsts->set(mThickLineShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
+   mThickLineShaderConsts->setSafe(mThickLineShader->getShaderConstHandle("$thickness"), thickness);
+
+   const Point2I& resolution = GFX->getActiveRenderTarget()->getSize();
+   Point2F TargetSize(1.0 / (F32)resolution.x, 1.0 / (F32)resolution.y);
+
+   mThickLineShaderConsts->setSafe(mThickLineShader->getShaderConstHandle("$oneOverViewport"), TargetSize);
+
+   mDevice->drawPrimitive(GFXLineList, 0, 1);
+}
+
 //-----------------------------------------------------------------------------
 // 3D World Draw Misc
 //-----------------------------------------------------------------------------
@@ -713,13 +892,13 @@ void GFXDrawUtil::drawSphere( const GFXStateBlockDesc &desc, F32 radius, const P
 
 //-----------------------------------------------------------------------------
 
-static const Point3F cubePoints[8] = 
+static const Point3F cubePoints[8] =
 {
    Point3F(-1, -1, -1), Point3F(-1, -1,  1), Point3F(-1,  1, -1), Point3F(-1,  1,  1),
    Point3F( 1, -1, -1), Point3F( 1, -1,  1), Point3F( 1,  1, -1), Point3F( 1,  1,  1)
 };
 
-static const U32 cubeFaces[6][4] = 
+static const U32 cubeFaces[6][4] =
 {
    { 0, 4, 6, 2 }, { 0, 2, 3, 1 }, { 0, 1, 5, 4 },
    { 3, 2, 6, 7 }, { 7, 6, 4, 5 }, { 3, 7, 5, 1 }
@@ -812,7 +991,7 @@ void GFXDrawUtil::drawPolygon( const GFXStateBlockDesc& desc, const Point3F* poi
       for( U32 i = 0; i < numPoints; ++ i )
          xfm->mulP( verts[ i ].point );
    }
-   
+
    if( isWireframe )
    {
       verts[ numVerts - 1 ].point = verts[ 0 ].point;
@@ -899,7 +1078,7 @@ void GFXDrawUtil::_drawSolidCube( const GFXStateBlockDesc &desc, const Point3F &
    for(S32 i = 0; i < 6; i++)
    {
       idx = cubeFaces[i][0];
-      verts[vertexIndex].point = cubePoints[idx] * halfSize;      
+      verts[vertexIndex].point = cubePoints[idx] * halfSize;
       verts[vertexIndex].color = color;
       vertexIndex++;
 
@@ -1113,10 +1292,10 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
 	   cubePts[i] = cubePoints[i]/2;
    }
 
-   // 8 corner points of the box   
+   // 8 corner points of the box
    for ( U32 i = 0; i < 8; i++ )
    {
-      //const Point3F &start = cubePoints[i];  
+      //const Point3F &start = cubePoints[i];
 
       // 3 lines per corner point
       for ( U32 j = 0; j < 3; j++ )
@@ -1128,7 +1307,7 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
          scaledObjMat.mulP(start);
          PrimBuild::vertex3fv(start);
          scaledObjMat.mulP(end);
-         PrimBuild::vertex3fv(end);            
+         PrimBuild::vertex3fv(end);
       }
    }
 
@@ -1164,10 +1343,10 @@ void GFXDrawUtil::drawCapsule( const GFXStateBlockDesc &desc, const Point3F &cen
 }
 
 void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3F &center, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm )
-{	
+{
    MatrixF mat;
    if ( xfm )
-      mat = *xfm;      
+      mat = *xfm;
    else
       mat = MatrixF::Identity;
 
@@ -1176,7 +1355,7 @@ void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3
    verts.lock();
    for (S32 i=0; i<numPoints + 1; i++)
    {
-      S32 imod = i % numPoints;      
+      S32 imod = i % numPoints;
       verts[2 * i].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, height/2 );
       verts[2 * i].color = color;
       verts[2 * i + 1].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, -height/2 );
@@ -1208,7 +1387,7 @@ void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3
    if ( xfm )
       sphereMat = *xfm;
    else
-      sphereMat = MatrixF::Identity;   
+      sphereMat = MatrixF::Identity;
 
    sphereCenter.set( 0, 0, 0.5f * height );
    mat.mulV( sphereCenter );
@@ -1284,12 +1463,12 @@ void GFXDrawUtil::_drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F
 }
 
 void GFXDrawUtil::drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color )
-{   
+{
    VectorF uvec = tipPnt - basePnt;
    F32 height = uvec.len();
    uvec.normalize();
    MatrixF mat( true );
-   MathUtils::getMatrixFromUpVector( uvec, &mat );   
+   MathUtils::getMatrixFromUpVector( uvec, &mat );
    mat.setPosition(basePnt);
 
    Point3F scale( baseRadius, baseRadius, height );
@@ -1359,7 +1538,7 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
    F32 height = uvec.len();
    uvec.normalize();
    MatrixF mat( true );
-   MathUtils::getMatrixFromUpVector( uvec, &mat );   
+   MathUtils::getMatrixFromUpVector( uvec, &mat );
    mat.setPosition(basePnt);
 
    Point3F scale( radius, radius, height * 2 );
@@ -1425,14 +1604,14 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
 }
 
 void GFXDrawUtil::drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color, F32 baseRad )
-{   
+{
    GFXTransformSaver saver;
 
    // Direction and length of the arrow.
    VectorF dir = end - start;
    F32 len = dir.len();
-   dir.normalize();   
-   len *= 0.2f;      
+   dir.normalize();
+   len *= 0.2f;
 
    // Base of the cone will be a distance back from the end of the arrow
    // proportional to the total distance of the arrow... 0.3f looks about right.
@@ -1464,11 +1643,11 @@ void GFXDrawUtil::drawFrustum( const Frustum &f, const ColorI &color )
 
    // Draw near and far planes.
    for (U32 offset = 0; offset < 8; offset+=4)
-   {      
+   {
       drawLine(points[offset+0], points[offset+1], color);
       drawLine(points[offset+2], points[offset+3], color);
       drawLine(points[offset+0], points[offset+2], color);
-      drawLine(points[offset+1], points[offset+3], color);            
+      drawLine(points[offset+1], points[offset+3], color);
    }
 
    // connect the near and far planes
@@ -1512,13 +1691,13 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
    U32 vSteps = 0;
    if( step.y > 0 )
       vSteps = size.y / step.y + 0.5 + 1;
-      
+
    if( uSteps <= 1 || vSteps <= 1 )
       return;
-      
+
    const U32 numVertices = uSteps * 2 + vSteps * 2;
    const U32 numLines = uSteps + vSteps;
-   
+
    Point3F origin;
    switch( plane )
    {
@@ -1552,14 +1731,14 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
             verts[vertCount].point = Point3F( start + step.x * i, origin.y + size.y, origin.z );
          else
             verts[vertCount].point = Point3F( start + step.x * i, origin.y,  origin.z + size.y );
-            
+
          verts[vertCount].color = color;
          ++vertCount;
       }
    }
 
    if( plane == PlaneXY || plane == PlaneYZ )
-   {      
+   {
       U32 num;
       F32 stp;
       if( plane == PlaneXY )
@@ -1574,7 +1753,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
       }
 
       F32 start = mFloor( origin.y / stp + 0.5f ) * stp;
-         
+
       for ( U32 i = 0; i < num; i++ )
       {
          verts[vertCount].point = Point3F( origin.x, start + stp * i, origin.z );
@@ -1585,7 +1764,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
             verts[vertCount].point = Point3F( origin.x + size.x, start + stp * i, origin.z );
          else
             verts[vertCount].point = Point3F( origin.x, start + stp * i, origin.z + size.x );
-            
+
          verts[vertCount].color = color;
          ++vertCount;
       }
@@ -1604,7 +1783,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
             verts[vertCount].point = Point3F( origin.x + size.x, origin.y, start + step.y * i );
          else
             verts[vertCount].point = Point3F( origin.x, origin.y + size.x, start + step.y * i );
-            
+
          verts[vertCount].color = color;
          ++vertCount;
       }
@@ -1629,7 +1808,7 @@ void GFXDrawUtil::drawTransform( const GFXStateBlockDesc &desc, const MatrixF &m
    GFXVertexBufferHandle<GFXVertexPCT> verts( mDevice, 6, GFXBufferTypeVolatile );
    verts.lock();
 
-   const static ColorI defColors[3] = 
+   const static ColorI defColors[3] =
    {
       ColorI::RED,
       ColorI::GREEN,
@@ -1655,7 +1834,7 @@ void GFXDrawUtil::drawTransform( const GFXStateBlockDesc &desc, const MatrixF &m
    {
       verts[1].point *= *scale;
       verts[3].point *= *scale;
-      verts[5].point *= *scale;      
+      verts[5].point *= *scale;
    }
 
    verts.unlock();

+ 56 - 22
Engine/source/gfx/gfxDrawUtil.h

@@ -46,22 +46,36 @@ public:
    ~GFXDrawUtil();
 
    //-----------------------------------------------------------------------------
-   // Draw Rectangles
+   // Draw Rectangles : OUTLINE
    //-----------------------------------------------------------------------------
-   void drawRect( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color );
-   void drawRect( const RectF &rect, const ColorI &color );
-   void drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color );
-   void drawRect( const RectI &rect, const ColorI &color );
+   void drawRect(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color);
+   void drawRect(const RectF& rect, const ColorI& color);
+   void drawRect(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color);
+   void drawRect(const RectI& rect, const ColorI& color);
 
-   void drawRectFill( const Point2F &upperL, const Point2F &lowerR, const ColorI &color );
-   void drawRectFill( const RectF &rect, const ColorI &color );
-   void drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color );
-   void drawRectFill( const RectI &rect, const ColorI &color );
+   //-----------------------------------------------------------------------------
+   // Draw Rectangles : FILL
+   //-----------------------------------------------------------------------------
+
+   void drawRectFill(const Point2F& upperL, const Point2F& lowerR, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRectFill(const RectF& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRectFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRectFill(const RectI& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRoundedRect(const F32& cornerRadius, const RectI& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRoundedRect(const F32& cornerRadius, const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawRoundedRect(const F32& cornerRadius, const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+
+   void draw2DSquare(const Point2F& screenPoint, F32 width, F32 spinAngle = 0.0f);
 
-   void draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle = 0.0f );
+   //-----------------------------------------------------------------------------
+   // Draw Circle : FILL
+   //-----------------------------------------------------------------------------
+   void drawCircleFill(const RectI& rect, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawCircleFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
+   void drawCircleFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
 
    //-----------------------------------------------------------------------------
-   // Draw Lines
+   // Draw Lines : Single Pixel
    //-----------------------------------------------------------------------------
    void drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color );
    void drawLine( const Point2F &startPt, const Point2F &endPt, const ColorI &color );
@@ -69,6 +83,13 @@ public:
    void drawLine( F32 x1, F32 y1, F32 x2, F32 y2, const ColorI &color );
    void drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color );
 
+   //-----------------------------------------------------------------------------
+   // Draw Lines : Thick
+   //-----------------------------------------------------------------------------
+   void drawThickLine(const Point2I& startPt, const Point2I& endPt, const ColorI& color, const F32& thickness);
+   void drawThickLine(const Point2F& startPt, const Point2F& endPt, const ColorI& color, const F32& thickness);
+   void drawThickLine(F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI& color, const F32& thickness);
+
    //-----------------------------------------------------------------------------
    // Draw Text
    //-----------------------------------------------------------------------------
@@ -92,7 +113,7 @@ public:
 
    //-----------------------------------------------------------------------------
    // Draw Bitmaps
-   //-----------------------------------------------------------------------------  
+   //-----------------------------------------------------------------------------
    void drawBitmap( GFXTextureObject*texture, const Point2F &in_rAt, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
    void drawBitmapSR( GFXTextureObject*texture, const Point2F &in_rAt, const RectF &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
    void drawBitmapStretch( GFXTextureObject*texture, const RectF &dstRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
@@ -108,15 +129,15 @@ public:
    //-----------------------------------------------------------------------------
    void drawTriangle( const GFXStateBlockDesc &desc, const Point3F &p0, const Point3F &p1, const Point3F &p2, const ColorI &color, const MatrixF *xfm = NULL );
    void drawPolygon( const GFXStateBlockDesc& desc, const Point3F* points, U32 numPoints, const ColorI& color, const MatrixF* xfm = NULL );
-   void drawCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );   
-   void drawCube( const GFXStateBlockDesc &desc, const Box3F &box, const ColorI &color, const MatrixF *xfm = NULL );   
-   void drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const MatrixF &objMat, const ColorI &color );   
-   void drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop = true, bool drawBottom = true, const MatrixF *xfm = NULL );      
+   void drawCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
+   void drawCube( const GFXStateBlockDesc &desc, const Box3F &box, const ColorI &color, const MatrixF *xfm = NULL );
+   void drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const MatrixF &objMat, const ColorI &color );
+   void drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop = true, bool drawBottom = true, const MatrixF *xfm = NULL );
    void drawCapsule( const GFXStateBlockDesc &desc, const Point3F &center, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm = NULL );
-   void drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );      
-   void drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );      
+   void drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
+   void drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
    void drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color, F32 baseRad = 0.0f);
-   void drawFrustum( const Frustum& f, const ColorI &color );   
+   void drawFrustum( const Frustum& f, const ColorI &color );
 
    /// Draw a solid or wireframe (depending on fill mode of @a desc) polyhedron with the given color.
    ///
@@ -128,7 +149,7 @@ public:
 
    /// Draws a solid XY plane centered on the point with the specified dimensions.
    void drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const ColorI &color );
-   
+
    enum Plane
    {
       PlaneXY,
@@ -142,7 +163,7 @@ public:
    /// Draws axis lines representing the passed matrix.
    /// If scale is NULL axes will be drawn the length they exist within the MatrixF.
    /// If colors is NULL the default colors are RED, GREEEN, BLUE ( x, y, z ).
-   void drawTransform( const GFXStateBlockDesc &desc, const MatrixF &mat, const Point3F *scale = NULL, const ColorI colors[3] = NULL );  
+   void drawTransform( const GFXStateBlockDesc &desc, const MatrixF &mat, const Point3F *scale = NULL, const ColorI colors[3] = NULL );
 
 protected:
 
@@ -174,8 +195,21 @@ protected:
    GFXStateBlockRef mBitmapStretchWrapSB;
    GFXStateBlockRef mBitmapStretchWrapLinearSB;
    GFXStateBlockRef mRectFillSB;
-   
+
    FontRenderBatcher* mFontRenderBatcher;
+
+   // Expanded shaders
+   // rounded rectangle.
+   GFXShaderRef mRoundRectangleShader;
+   GFXShaderConstBufferRef mRoundRectangleShaderConsts;
+
+   // thick line.
+   GFXShaderRef mCircleShader;
+   GFXShaderConstBufferRef mCircleShaderConsts;
+
+   // thick line.
+   GFXShaderRef mThickLineShader;
+   GFXShaderConstBufferRef mThickLineShaderConsts;
 };
 
 #endif // _GFX_GFXDRAWER_H_

+ 10 - 51
Engine/source/gui/shaderEditor/guiShaderEditor.cpp

@@ -134,45 +134,6 @@ void GuiShaderEditor::onPreRender()
    setUpdate();
 }
 
-void GuiShaderEditor::drawThickLine(const Point2I& pt1, const Point2I& pt2, U32 thickness, ColorI col1, ColorI col2)
-{
-   Point2F dir = Point2F(pt2.x - pt1.x, pt2.y - pt1.y);
-   if (dir == Point2F::Zero)
-      return;
-
-   Point2F unitDir = dir / mSqrt(dir.x * dir.x + dir.y * dir.y);
-   Point2F unitPerp(-unitDir.y, unitDir.x);
-   Point2F offset = (thickness / 2.0f) * unitPerp;
-
-   GFX->setStateBlock(mDefaultGuiSB);
-
-   Point2F lT = Point2F(pt1.x, pt1.y) + offset;
-   Point2F lB = Point2F(pt1.x, pt1.y) - offset;
-   Point2F rT = Point2F(pt2.x, pt2.y) + offset;
-   Point2F rB = Point2F(pt2.x, pt2.y) - offset;
-
-
-   PrimBuild::begin(GFXTriangleStrip, 4);
-
-   // top left.
-   PrimBuild::color(col1);
-   PrimBuild::vertex2f(lT.x, lT.y);
-
-   // bottom left.
-   PrimBuild::color(col1);
-   PrimBuild::vertex2f(lB.x, lB.y);
-
-   // top right.
-   PrimBuild::color(col2);
-   PrimBuild::vertex2f(rT.x, rT.y);
-
-   // bottom right.
-   PrimBuild::color(col2);
-   PrimBuild::vertex2f(rB.x, rB.y);
-
-   PrimBuild::end();
-}
-
 void GuiShaderEditor::renderNodes(Point2I offset, const RectI& updateRect)
 {
    // Save the current clip rect
@@ -224,17 +185,14 @@ void GuiShaderEditor::renderNodes(Point2I offset, const RectI& updateRect)
             if (node->mSelected)
                border = mProfile->mBorderColorSEL;
 
-            RectI socketRect(pos, Point2I(mNodeSize, mNodeSize));
-            drawer->drawRect(socketRect, border);
-            socketRect.inset(1, 1);
-
             ColorI fill = mProfile->mFillColor;
             if (hasConnection(input))
             {
                fill = ColorI::WHITE;
             }
 
-            drawer->drawRectFill(socketRect, fill);
+            RectI socketRect(pos, Point2I(mNodeSize, mNodeSize));
+            drawer->drawCircleFill(socketRect, fill, mNodeSize / 2, 2.0f, border);
          }
 
          for (NodeOutput* output : node->mOutputNodes)
@@ -246,9 +204,8 @@ void GuiShaderEditor::renderNodes(Point2I offset, const RectI& updateRect)
             if (node->mSelected)
                border = mProfile->mBorderColorSEL;
 
-            RectI socketRect(pos, Point2I(mNodeSize, mNodeSize));
-            drawer->drawRect(socketRect, border);
-            socketRect.inset(1, 1);
+            if(node->mSelected)
+               border = mProfile->mBorderColorSEL;
 
             ColorI fill = mProfile->mFillColor;
             if (hasConnection(output))
@@ -256,7 +213,8 @@ void GuiShaderEditor::renderNodes(Point2I offset, const RectI& updateRect)
                fill = ColorI::WHITE;
             }
 
-            drawer->drawRectFill(socketRect, fill);
+            RectI socketRect(pos, Point2I(mNodeSize, mNodeSize));
+            drawer->drawCircleFill(socketRect, fill, mNodeSize / 2, 2.0f, border);
          }
       }
    }
@@ -292,7 +250,7 @@ void GuiShaderEditor::renderConnections(Point2I offset, const RectI& updateRect)
       start += Point2I(mNodeSize / 2, mNodeSize / 2);
       end += Point2I(mNodeSize / 2, mNodeSize / 2);
 
-      drawThickLine(start, end, mNodeSize/3);
+      drawer->drawThickLine(start, end,ColorI(255,255,255,255), (F32)mNodeSize/3);
    }
 
    // Restore the clip rect to what it was at the start
@@ -328,11 +286,12 @@ void GuiShaderEditor::onRender(Point2I offset, const RectI& updateRect)
 
             RectI sockActive(start, Point2I(mNodeSize, mNodeSize));
             start += Point2I(mNodeSize / 2, mNodeSize / 2);
-            drawThickLine(start, mLastMousePos + offset, mNodeSize/3);
+
+            drawer->drawThickLine(start, mLastMousePos + offset, ColorI(255, 255, 255, 255), (F32)mNodeSize / 3);
 
             // draw socket overlay over the top of the line.
             sockActive.inset(1, 1);
-            drawer->drawRectFill(sockActive, ColorI(255, 255, 255));
+            drawer->drawCircleFill(sockActive, ColorI(255, 255, 255), mNodeSize / 2);
          }
       }
       // Draw selection rectangle last so it is rendered on top.

+ 9 - 11
Engine/source/gui/shaderEditor/nodes/shaderNode.cpp

@@ -108,7 +108,13 @@ void GuiShaderNode::renderNode(Point2I offset, const RectI& updateRect, const S3
    RectI winRect;
    winRect.point = offset;
    winRect.extent = getExtent();
-   drawer->drawRectFill(winRect, mProfile->mFillColor);
+
+   ColorI border = mProfile->mBorderColor;
+
+   if (mSelected)
+      border = mProfile->mBorderColorSEL;
+
+   drawer->drawRoundedRect(15.0f, winRect, mProfile->mFillColor, 3.0f, border);
 
    // draw header
    ColorI header(50, 50, 50, 128);
@@ -148,7 +154,7 @@ void GuiShaderNode::renderNode(Point2I offset, const RectI& updateRect, const S3
    U32 headerSize = 30;
    headRect.point = offset;
    headRect.extent = Point2I(getExtent().x, headerSize);
-   drawer->drawRectFill(headRect, header);
+   drawer->drawRoundedRect(15.0f, headRect, header);
 
    // draw header text.
    U32 strWidth = mProfile->mFont->getStrWidth(mTitle.c_str());
@@ -157,14 +163,6 @@ void GuiShaderNode::renderNode(Point2I offset, const RectI& updateRect, const S3
    drawer->drawText(mProfile->mFont, headerPos + offset, mTitle);
    drawer->clearBitmapModulation();
 
-   ColorI border = mProfile->mBorderColor;
-
-   if (mSelected)
-      border = mProfile->mBorderColorSEL;
-
-   drawer->drawRect(winRect, border);
-
-
    if (mInputNodes.size() > 0 || mOutputNodes.size() > 0)
    {
       U32 textPadX = nodeSize, textPadY = mProfile->mFont->getFontSize() + (nodeSize / 2);
@@ -175,7 +173,7 @@ void GuiShaderNode::renderNode(Point2I offset, const RectI& updateRect, const S3
          drawer->drawText(mProfile->mFont, slotPos + offset, input->name);
 
          if (input->pos == Point2I::Zero || mPrevNodeSize != nodeSize)
-            input->pos = Point2I(-(nodeSize / 2), slotPos.y + ((mProfile->mFont->getFontSize() / 2) - (nodeSize / 2)));
+            input->pos = Point2I(-(nodeSize / 2) + 1, slotPos.y + ((mProfile->mFont->getFontSize() / 2) - (nodeSize / 2)));
 
          slotPos.y += textPadY;
       }

+ 28 - 0
Templates/BaseGame/game/core/rendering/scripts/gfxData/shaders.tscript

@@ -149,4 +149,32 @@ singleton ShaderData( CubemapSaveShader )
    samplerNames[0] = "$cubemapTex";
 	
    pixVersion = 3.0;
+};
+
+//-----------------------------------------------------------------------------
+// GUI shaders
+//-----------------------------------------------------------------------------
+singleton ShaderData( RoundedRectangleGUI )
+{
+   DXVertexShaderFile   = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
+   DXPixelShaderFile    = $Core::CommonShaderPath @ "/fixedFunction/roundedRectangleP.hlsl";
+      
+   pixVersion = 3.0;   
+};
+
+singleton ShaderData( CircularGUI )
+{
+   DXVertexShaderFile   = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
+   DXPixelShaderFile    = $Core::CommonShaderPath @ "/fixedFunction/circleP.hlsl";
+      
+   pixVersion = 3.0;   
+};
+
+singleton ShaderData( ThickLineGUI )
+{
+   DXVertexShaderFile   = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
+   DXGeometryShaderFile = $Core::CommonShaderPath @ "/fixedFunction/thickLineG.hlsl";
+   DXPixelShaderFile    = $Core::CommonShaderPath @ "/fixedFunction/thickLineP.hlsl";
+      
+   pixVersion = 3.0;   
 };

+ 66 - 0
Templates/BaseGame/game/core/rendering/shaders/fixedFunction/circleP.hlsl

@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../shaderModel.hlsl"
+
+struct Conn
+{
+   float4 HPOS             : TORQUE_POSITION;
+   float4 color            : COLOR;
+};
+
+uniform float2 sizeUni;
+uniform float radius;
+uniform float2 rectCenter;
+uniform float borderSize;
+uniform float4 borderCol;
+
+float circle(float2 p, float radius)
+{
+    float dist = length(p - float2(0.5,0.5));
+    return 1.0 - smoothstep(radius - (radius*0.01), 
+                            radius + (radius*0.01),
+                            dot(dist,dist) * 4.0);
+}
+ 
+float4 main(Conn IN) : TORQUE_TARGET0
+{   
+    float distance = length(IN.HPOS.xy - rectCenter);
+    if(distance > radius)
+    {
+        discard;
+    }
+
+    if(distance < radius)
+    {
+        if(distance < (radius - borderSize))
+        {
+            return IN.color;
+        }
+        else
+        {
+            return borderCol;
+        }
+    }
+
+    return IN.color;
+}

+ 109 - 0
Templates/BaseGame/game/core/rendering/shaders/fixedFunction/roundedRectangleP.hlsl

@@ -0,0 +1,109 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../shaderModel.hlsl"
+
+struct Conn
+{
+   float4 HPOS             : TORQUE_POSITION;
+   float4 color            : COLOR;
+};
+
+uniform float2 sizeUni;
+uniform float2 rectCenter;
+uniform float radius;
+uniform float borderSize;
+uniform float4 borderCol;
+
+float RoundedRectSDF(float2 p, float2 size, float radius)
+{
+    float2 halfSize = size / 2.0;
+
+    // Calculate distance to each side of the rectangle
+    float2 dist = abs(p) - halfSize + radius;
+
+    // Compute the distance to the rounded corners
+    float cornerDist = length(max(abs(p) - (halfSize - float2(radius, radius)), 0.0));
+
+    // Return the minimum distance (negative inside, positive outside)
+    return min(max(dist.x, dist.y), 0.0) + cornerDist - radius;
+}
+ 
+float4 main(Conn IN) : TORQUE_TARGET0
+{  
+    float2 p = IN.HPOS.xy;
+    float2 halfSize = sizeUni * 0.5;
+    float halfBorder = borderSize * 0.5; 
+    
+    p -= rectCenter;
+
+    // Calculate signed distance field for rounded rectangle 
+    float4 fromColor = IN.color;
+    // alpha
+    float4 toColor = float4(0.0, 0.0, 0.0, 0.0);
+
+    float cornerRadius = radius;
+
+    // if ((p.y < 0.0 && p.x < 0.0) || // top left corner
+    //     (p.y < 0.0 && p.x > 0.0) || // top right corner
+    //     (p.y > 0.0 && p.x > 0.0) || // bottom right corner.  
+    //     (p.y > 0.0 && p.x < 0.0))  // bottom left corner
+    // {
+    //     cornerRadius = radius;   
+    // } 
+
+    if(cornerRadius > 0.0 || halfBorder > 0.0)
+    {
+        float sdf = RoundedRectSDF(p, sizeUni, cornerRadius - halfBorder);
+
+        clip(0.01 - sdf);
+
+        if(halfBorder > 0.0)
+        {
+            if(sdf < 0.0)
+            {
+                // if ((p.y >= -halfSize.y - radius + halfBorder && p.y <= -halfSize.y + radius - halfBorder)  ||  // top border
+                //     (p.y >= halfSize.y - radius + halfBorder && p.y <= halfSize.y + radius - halfBorder)    ||  // bottom border
+                //     (p.x >= -halfSize.x - radius + halfBorder && p.x <= -halfSize.x + radius - halfBorder)  ||  // left border
+                //     (p.x >= halfSize.x - radius + halfBorder && p.x <= halfSize.x + radius - halfBorder) ) {    // right border
+                    
+                // }
+
+                toColor = borderCol;  
+            }
+            
+            sdf = abs(sdf) - halfBorder;
+
+            // Apply smoothing to create rounded effect  
+            float blending = smoothstep(1.0, -1.0, sdf); 
+
+            return lerp(fromColor, toColor, blending);
+        }
+        
+        float alpha = smoothstep(1.0, 0.0, sdf); 
+        return float4(IN.color.rgb, IN.color.a * alpha);
+    }
+    else
+    { 
+        return IN.color;
+    }
+}

+ 77 - 0
Templates/BaseGame/game/core/rendering/shaders/fixedFunction/thickLineG.hlsl

@@ -0,0 +1,77 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../shaderModel.hlsl"
+
+struct Conn
+{
+   float4 HPOS             : TORQUE_POSITION;
+   float4 color            : COLOR;
+};
+
+struct PSConn
+{
+   float4 HPOS             : TORQUE_POSITION;
+   float4 color            : COLOR;
+};
+
+uniform float thickness;
+uniform float2 oneOverViewport;
+
+[maxvertexcount(4)]
+void main(line Conn lineSegment[2], inout TriangleStream<PSConn> outstream)
+{
+    // Calculate the direction of the line segment
+    float2 direction = normalize(lineSegment[1].HPOS.xy - lineSegment[0].HPOS.xy);
+
+    // Calculate perpendicular direction
+    float2 perpendicular = normalize(float2(-direction.y, direction.x));
+
+    // Calculate offset for thickness 
+    float2 offset = float2(thickness * oneOverViewport.x, thickness *  oneOverViewport.y) * perpendicular;
+ 
+    // Calculate vertices for the line with thickness
+    float2 p0 = lineSegment[0].HPOS.xy + offset;
+    float2 p1 = lineSegment[0].HPOS.xy - offset;
+    float2 p2 = lineSegment[1].HPOS.xy + offset;
+    float2 p3 = lineSegment[1].HPOS.xy - offset;
+
+    PSConn output;
+
+    output.HPOS = float4(p0, 0.0f, 1.0f);
+    output.color = lineSegment[0].color;
+    outstream.Append(output);
+
+    output.HPOS = float4(p1, 0.0f, 1.0f);
+    output.color = lineSegment[0].color;
+    outstream.Append(output);
+
+    output.HPOS = float4(p2, 0.0f, 1.0f);
+    output.color = lineSegment[1].color;
+    outstream.Append(output);
+
+    output.HPOS = float4(p3, 0.0f, 1.0f);
+    output.color = lineSegment[1].color;
+    outstream.Append(output);
+
+    outstream.RestartStrip();
+}

+ 34 - 0
Templates/BaseGame/game/core/rendering/shaders/fixedFunction/thickLineP.hlsl

@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../shaderModel.hlsl"
+
+struct PSConn
+{
+   float4 HPOS             : TORQUE_POSITION;
+   float4 color            : COLOR;
+};
+
+float4 main(PSConn IN) : TORQUE_TARGET0
+{
+   return IN.color;
+}