diff --git a/include/eepp/graphics/arcdrawable.hpp b/include/eepp/graphics/arcdrawable.hpp index a988fcd52..ccc9b0488 100644 --- a/include/eepp/graphics/arcdrawable.hpp +++ b/include/eepp/graphics/arcdrawable.hpp @@ -1,24 +1,45 @@ #ifndef EE_GRAPHICS_ARCDRAWABLE #define EE_GRAPHICS_ARCDRAWABLE +#include #include namespace EE { namespace Graphics { class ArcDrawable : public PrimitiveDrawable { public: - ArcDrawable( const Float& radius, Uint32 segmentsCount = 0, const Float& arcAngle = 360.f , const Float& arcStartAngle = 0.f ); + ArcDrawable(); + + ArcDrawable( const Float& radius, Uint32 segmentsCount = 64, const Float& arcAngle = 360.f , const Float& arcStartAngle = 0.f ); virtual Sizef getSize(); virtual void draw( const Vector2f& position ); virtual void draw( const Vector2f& position, const Sizef& size ); + + Float getRadius() const; + + void setRadius(const Float & radius); + + Float getArcAngle() const; + + void setArcAngle(const Float & arcAngle); + + Float getArcStartAngle() const; + + void setArcStartAngle(const Float & arcStartAngle); + + Uint32 getSegmentsCount() const; + + void setSegmentsCount(const Uint32 & segmentsCount); protected: Float mRadius; Uint32 mSegmentsCount; Float mArcAngle; Float mArcStartAngle; + + void updateVertex(); }; }} diff --git a/include/eepp/graphics/circledrawable.hpp b/include/eepp/graphics/circledrawable.hpp new file mode 100644 index 000000000..94d2668d5 --- /dev/null +++ b/include/eepp/graphics/circledrawable.hpp @@ -0,0 +1,17 @@ +#ifndef EE_GRAPHICS_CIRCLEDRAWABLE_HPP +#define EE_GRAPHICS_CIRCLEDRAWABLE_HPP + +#include + +namespace EE { namespace Graphics { + +class CircleDrawable : public ArcDrawable { + public: + CircleDrawable(); + + CircleDrawable( const Float& radius, const Uint32& segmentsCount ); +}; + +}} + +#endif diff --git a/include/eepp/graphics/graphicshelper.hpp b/include/eepp/graphics/graphicshelper.hpp index 2912fba87..a647ad62a 100755 --- a/include/eepp/graphics/graphicshelper.hpp +++ b/include/eepp/graphics/graphicshelper.hpp @@ -188,6 +188,8 @@ enum EE_DRAWABLE_TYPE { DRAWABLE_TEXTURE, DRAWABLE_SUBTEXTURE, DRAWABLE_SPRITE, + DRAWABLE_ARC, + DRAWABLE_RECTANGLE, DRAWABLE_CUSTOM }; diff --git a/include/eepp/graphics/primitivedrawable.hpp b/include/eepp/graphics/primitivedrawable.hpp index cd742b048..d404aeced 100644 --- a/include/eepp/graphics/primitivedrawable.hpp +++ b/include/eepp/graphics/primitivedrawable.hpp @@ -5,24 +5,30 @@ namespace EE { namespace Graphics { +class VertexBuffer; + class PrimitiveDrawable : public Drawable { public: PrimitiveDrawable( EE_DRAWABLE_TYPE drawableType ); + virtual ~PrimitiveDrawable(); + + virtual void draw( const Vector2f& position, const Sizef& size ); + /** Set the fill mode used to draw primitives */ - void setFillMode( const EE_FILL_MODE& Mode ); + virtual void setFillMode( const EE_FILL_MODE& Mode ); /** @return The fill mode used to draw primitives */ const EE_FILL_MODE& getFillMode() const; /** Set the blend mode used to draw primitives */ - void setBlendMode( const EE_BLEND_MODE& Mode ); + virtual void setBlendMode( const EE_BLEND_MODE& Mode ); /** @return The blend mode used to draw primitives */ const EE_BLEND_MODE& getBlendMode() const; /** Set the line width to draw primitives */ - void setLineWidth( const Float& width ); + virtual void setLineWidth( const Float& width ); /** @return The line with to draw primitives */ const Float& getLineWidth() const; @@ -30,6 +36,18 @@ class PrimitiveDrawable : public Drawable { EE_FILL_MODE mFillMode; EE_BLEND_MODE mBlendMode; Float mLineWidth; + Vector2f mPosition; + bool mNeedsUpdate; + bool mRecreateVertexBuffer; + VertexBuffer * mVertexBuffer; + + virtual void onAlphaChange(); + + virtual void onColorFilterChange(); + + void prepareVertexBuffer( const EE_DRAW_MODE& drawableType ); + + virtual void updateVertex() = 0; }; }} diff --git a/include/eepp/graphics/rectangledrawable.hpp b/include/eepp/graphics/rectangledrawable.hpp new file mode 100644 index 000000000..4152419da --- /dev/null +++ b/include/eepp/graphics/rectangledrawable.hpp @@ -0,0 +1,24 @@ +#ifndef EE_GRAPHICS_RECTANGLEDRAWABLE +#define EE_GRAPHICS_RECTANGLEDRAWABLE + +#include + +namespace EE { namespace Graphics { + +class RectangleDrawable : PrimitiveDrawable { + public: + RectangleDrawable(); + + ~RectangleDrawable(); + + virtual Sizef getSize(); + + virtual void draw( const Vector2f& position ); + + virtual void draw( const Vector2f& position, const Sizef& size ); + +}; + +}} + +#endif diff --git a/include/eepp/graphics/vertexbufferogl.hpp b/include/eepp/graphics/vertexbufferogl.hpp index 845ea0ec2..bb21a59ed 100644 --- a/include/eepp/graphics/vertexbufferogl.hpp +++ b/include/eepp/graphics/vertexbufferogl.hpp @@ -12,8 +12,6 @@ class EE_API VertexBufferOGL : public VertexBuffer { public: VertexBufferOGL( const Uint32& VertexFlags = VERTEX_FLAGS_DEFAULT, EE_DRAW_MODE DrawType = DM_QUADS, const Int32& ReserveVertexSize = 0, const Int32& ReserveIndexSize = 0, EE_VBO_USAGE_TYPE UsageType = VBO_USAGE_TYPE_STATIC ); - virtual ~VertexBufferOGL(); - void bind(); void draw(); diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 2cd13ec18..5f3603892 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1,4 +1,5 @@ ../../include/eepp/graphics/arcdrawable.hpp +../../include/eepp/graphics/circledrawable.hpp ../../include/eepp/graphics/drawable.hpp ../../include/eepp/graphics/drawablesearcher.hpp ../../include/eepp/graphics/font.hpp @@ -7,6 +8,7 @@ ../../include/eepp/graphics/fonttruetypeloader.hpp ../../include/eepp/graphics/graphicshelper.hpp ../../include/eepp/graphics/primitivedrawable.hpp +../../include/eepp/graphics/rectangledrawable.hpp ../../include/eepp/graphics/renderer/base.hpp ../../include/eepp/graphics/renderer/opengl.hpp ../../include/eepp/graphics/renderer/renderer.hpp @@ -36,6 +38,7 @@ ../../include/eepp/ui/uiwidget.hpp ../../src/eepp/gaming/mapobjectlayer.cpp ../../src/eepp/graphics/arcdrawable.cpp +../../src/eepp/graphics/circledrawable.cpp ../../src/eepp/graphics/drawable.cpp ../../src/eepp/graphics/drawablesearcher.cpp ../../src/eepp/graphics/fonttruetype.cpp @@ -44,6 +47,7 @@ ../../src/eepp/graphics/pixeldensity.cpp ../../src/eepp/graphics/pixelperfect.cpp ../../src/eepp/graphics/primitivedrawable.cpp +../../src/eepp/graphics/rectangledrawable.cpp ../../src/eepp/graphics/renderer/openglext.hpp ../../src/eepp/graphics/renderer/renderer.cpp ../../src/eepp/graphics/renderer/renderer.cpp diff --git a/src/eepp/graphics/arcdrawable.cpp b/src/eepp/graphics/arcdrawable.cpp index 85fa33fd3..2038299ef 100644 --- a/src/eepp/graphics/arcdrawable.cpp +++ b/src/eepp/graphics/arcdrawable.cpp @@ -1,58 +1,103 @@ #include -#include +#include namespace EE { namespace Graphics { +ArcDrawable::ArcDrawable() : + PrimitiveDrawable( DRAWABLE_ARC ), + mRadius( 0 ), + mSegmentsCount( 64 ), + mArcAngle( 360 ), + mArcStartAngle( 0 ) +{ +} + ArcDrawable::ArcDrawable( const Float & radius, Uint32 segmentsCount, const Float & arcAngle, const Float & arcStartAngle ) : - PrimitiveDrawable( DRAWABLE_CUSTOM ), + PrimitiveDrawable( DRAWABLE_ARC ), mRadius( radius ), mSegmentsCount( segmentsCount ), mArcAngle( arcAngle ), mArcStartAngle( arcStartAngle ) { + if(mSegmentsCount < 6) mSegmentsCount = 6; + mSegmentsCount = mSegmentsCount > 360 ? 360 : mSegmentsCount; } Sizef ArcDrawable::getSize() { return Sizef( mRadius * 2, mRadius * 2 ); } -void ArcDrawable::draw( const Vector2f& position ) { +void ArcDrawable::draw(const Vector2f & position) { draw( position, getSize() ); } void ArcDrawable::draw( const Vector2f& position, const Sizef& size ) { - BatchRenderer * sBR = GlobalBatchRenderer::instance(); - if ( size.getWidth() * 0.5f != mRadius ) { mRadius = size.getWidth() * 0.5f; + mNeedsUpdate = true; } + PrimitiveDrawable::draw( position, size ); +} + +Float ArcDrawable::getRadius() const { + return mRadius; +} + +void ArcDrawable::setRadius(const Float & radius) { + mRadius = radius; + mNeedsUpdate = true; +} + +Float ArcDrawable::getArcAngle() const { + return mArcAngle; +} + +void ArcDrawable::setArcAngle(const Float & arcAngle) { + mArcAngle = arcAngle; + mNeedsUpdate = true; +} + +Float ArcDrawable::getArcStartAngle() const { + return mArcStartAngle; +} + +void ArcDrawable::setArcStartAngle(const Float & arcStartAngle) { + mArcStartAngle = arcStartAngle; + mNeedsUpdate = true; +} + +Uint32 ArcDrawable::getSegmentsCount() const { + return mSegmentsCount; +} + +void ArcDrawable::setSegmentsCount(const Uint32 & segmentsCount) { + mSegmentsCount = segmentsCount; if(mSegmentsCount < 6) mSegmentsCount = 6; mSegmentsCount = mSegmentsCount > 360 ? 360 : mSegmentsCount; + mNeedsUpdate = true; +} + +void ArcDrawable::updateVertex() { + prepareVertexBuffer( mFillMode == DRAW_LINE ? DM_LINE_STRIP : DM_TRIANGLE_FAN ); Float angleShift = 360 / static_cast(mSegmentsCount); Float arcAngleA = mArcAngle > 360 ? mArcAngle - 360 * std::floor( mArcAngle / 360 ) : mArcAngle; - sBR->setTexture( NULL ); - switch( mFillMode ) { case DRAW_LINE: { - sBR->setLineWidth( mLineWidth ); - - mSegmentsCount = Uint32( (Float)mSegmentsCount * (Float)eeabs( arcAngleA ) / 360 ); + Uint32 segmentsCount = Uint32( (Float)mSegmentsCount * (Float)eeabs( arcAngleA ) / 360 ); Float startAngle = Math::radians(mArcStartAngle); - Float theta = Math::radians(arcAngleA) / Float(mSegmentsCount - 1); + Float theta = Math::radians(arcAngleA) / Float(segmentsCount - 1); Float tangetialFactor = eetan(theta); Float radialFactor = eecos(theta); Float x = mRadius * eecos(startAngle); Float y = mRadius * eesin(startAngle); - sBR->lineStripBegin(); - sBR->lineStripSetColor( mColor ); - - for( Uint32 ii = 0; ii < mSegmentsCount; ii++ ) { - sBR->batchLineStrip(x + position.x, y + position.y); + for( Uint32 ii = 0; ii < segmentsCount; ii++ ) { + mVertexBuffer->addVertex( Vector2f( x + mPosition.x, y + mPosition.y ) ); + mVertexBuffer->addColor( mColor ); Float tx = -y; Float ty = x; @@ -68,22 +113,24 @@ void ArcDrawable::draw( const Vector2f& position, const Sizef& size ) { } case DRAW_FILL: { - sBR->triangleFanBegin(); - sBR->triangleFanSetColor( mColor ); - for( Float i = 0; i < arcAngleA; i+= angleShift ) { Float startAngle = mArcStartAngle + i; - sBR->batchTriangleFan( position.x , position.y, - position.x + mRadius * Math::sinAng( startAngle ), position.y + mRadius * Math::cosAng( startAngle ), - position.x + mRadius * Math::sinAng( startAngle + angleShift ), position.y + mRadius * Math::cosAng( startAngle + angleShift ) ); + mVertexBuffer->addVertex( Vector2f( mPosition.x , mPosition.y ) ); + mVertexBuffer->addColor( mColor ); + + mVertexBuffer->addVertex( Vector2f( mPosition.x + mRadius * Math::sinAng( startAngle ), mPosition.y + mRadius * Math::cosAng( startAngle ) ) ); + mVertexBuffer->addColor( mColor ); + + mVertexBuffer->addVertex( Vector2f( mPosition.x + mRadius * Math::sinAng( startAngle + angleShift ), mPosition.y + mRadius * Math::cosAng( startAngle + angleShift ) ) ); + mVertexBuffer->addColor( mColor ); } break; } } - sBR->draw(); + mNeedsUpdate = false; } }} diff --git a/src/eepp/graphics/circledrawable.cpp b/src/eepp/graphics/circledrawable.cpp new file mode 100644 index 000000000..3c971f3e2 --- /dev/null +++ b/src/eepp/graphics/circledrawable.cpp @@ -0,0 +1,14 @@ +#include + +namespace EE { namespace Graphics { + +CircleDrawable::CircleDrawable() : + ArcDrawable( 0, 64 ) +{ +} + +CircleDrawable::CircleDrawable( const Float& radius, const Uint32& segmentsCount ) : + ArcDrawable( radius, segmentsCount ) +{} + +}} diff --git a/src/eepp/graphics/primitivedrawable.cpp b/src/eepp/graphics/primitivedrawable.cpp index 12ccdfcb3..f88453f78 100644 --- a/src/eepp/graphics/primitivedrawable.cpp +++ b/src/eepp/graphics/primitivedrawable.cpp @@ -1,14 +1,50 @@ #include +#include +#include namespace EE { namespace Graphics { PrimitiveDrawable::PrimitiveDrawable(EE_DRAWABLE_TYPE drawableType) : - Drawable( drawableType ) + Drawable( drawableType ), + mNeedsUpdate( true ), + mRecreateVertexBuffer( true ), + mVertexBuffer( NULL ) { } -void PrimitiveDrawable::setFillMode( const EE_FILL_MODE& Mode ) { +PrimitiveDrawable::~PrimitiveDrawable() { + eeSAFE_DELETE( mVertexBuffer ); +} + +void PrimitiveDrawable::draw( const Vector2f & position, const Sizef& size ) { + if ( mPosition != position ) { + mPosition = position; + mNeedsUpdate = true; + } + + if ( mNeedsUpdate ) + updateVertex(); + + if ( NULL != mVertexBuffer ) { + BatchRenderer * BR = GlobalBatchRenderer::instance(); + + BR->draw(); + + Float lw = BR->getLineWidth(); + BR->setLineWidth( mLineWidth ); + + mVertexBuffer->bind(); + mVertexBuffer->draw(); + mVertexBuffer->unbind(); + + BR->setLineWidth( lw ); + } +} + +void PrimitiveDrawable::setFillMode(const EE_FILL_MODE & Mode) { mFillMode = Mode; + mNeedsUpdate = true; + mRecreateVertexBuffer = true; } const EE_FILL_MODE& PrimitiveDrawable::getFillMode() const { @@ -31,4 +67,22 @@ const Float& PrimitiveDrawable::getLineWidth() const { return mLineWidth; } +void PrimitiveDrawable::onAlphaChange() { + mNeedsUpdate = true; +} + +void PrimitiveDrawable::onColorFilterChange() { + mNeedsUpdate = true; +} + +void PrimitiveDrawable::prepareVertexBuffer( const EE_DRAW_MODE& drawableType ) { + if ( mRecreateVertexBuffer ) { + eeSAFE_DELETE( mVertexBuffer ); + mVertexBuffer = VertexBuffer::NewVertexArray( VERTEX_FLAGS_PRIMITIVE, drawableType ); + mRecreateVertexBuffer = false; + } + + mVertexBuffer->clear(); +} + }} diff --git a/src/eepp/graphics/rectangledrawable.cpp b/src/eepp/graphics/rectangledrawable.cpp new file mode 100644 index 000000000..27262c42e --- /dev/null +++ b/src/eepp/graphics/rectangledrawable.cpp @@ -0,0 +1,27 @@ +#include + +namespace EE { namespace Graphics { + +RectangleDrawable::RectangleDrawable() : + PrimitiveDrawable( DRAWABLE_RECTANGLE ) +{ +} + +RectangleDrawable::~RectangleDrawable() { + +} + +Sizef RectangleDrawable::getSize() { + +} + +void RectangleDrawable::draw(const Vector2f & position) { + +} + +void RectangleDrawable::draw(const Vector2f & position, const Sizef & size) { + +} + + +}} diff --git a/src/eepp/graphics/vertexbufferogl.cpp b/src/eepp/graphics/vertexbufferogl.cpp index cab7ee59b..c1300921f 100644 --- a/src/eepp/graphics/vertexbufferogl.cpp +++ b/src/eepp/graphics/vertexbufferogl.cpp @@ -9,9 +9,6 @@ VertexBufferOGL::VertexBufferOGL( const Uint32& VertexFlags, EE_DRAW_MODE DrawTy { } -VertexBufferOGL::~VertexBufferOGL() { -} - void VertexBufferOGL::bind() { setVertexStates(); } diff --git a/src/examples/empty_window/empty_window.cpp b/src/examples/empty_window/empty_window.cpp index 4771b8bb8..25cfff8f2 100644 --- a/src/examples/empty_window/empty_window.cpp +++ b/src/examples/empty_window/empty_window.cpp @@ -1,6 +1,6 @@ #include -#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_TEST 0x0B90 #define GL_EQUAL 0x0202 #define GL_NEVER 0x0200 #define GL_KEEP 0x1E00 @@ -9,6 +9,7 @@ EE::Window::Window * win = NULL; float circ = 0, circ2 = 0; int op = 1; +ArcDrawable arcDrawable( 100, 64 ); void mainLoop() { @@ -79,12 +80,10 @@ void mainLoop() GLi->Disable(GL_STENCIL_TEST); */ - ArcDrawable arcDrawable( 100, 64 ); - arcDrawable.setColorFilter( ColorA( 220, 0, 0, 200 ) ); - arcDrawable.setFillMode( DRAW_FILL ); + arcDrawable.setArcAngle( circ ); + arcDrawable.setArcStartAngle( circ2 ); arcDrawable.draw( winCenter ); - // Draw frame win->display(); } @@ -98,9 +97,10 @@ EE_MAIN_FUNC int main (int argc, char * argv []) // Check if created if ( win->isOpen() ) { // Set window background color - win->setClearColor( RGB( 50, 50, 50 ) ); + win->setClearColor( Color( 50, 50, 50 ) ); - GLi->polygonMode( ); + arcDrawable.setColorFilter( ColorA( 0, 255, 0, 150 ) ); + arcDrawable.setFillMode( DRAW_FILL ); // Set the MainLoop function and run it // This is the application loop, it will loop until the window is closed.