فهرست منبع

Merge branch 'next' of https://github.com/sgrenier/GamePlay into next

sgrenier 12 سال پیش
والد
کامیت
5698657cba
6فایلهای تغییر یافته به همراه109 افزوده شده و 2 حذف شده
  1. 1 0
      gameplay/src/CheckBox.cpp
  2. 5 0
      gameplay/src/ImageControl.cpp
  3. 5 0
      gameplay/src/RadioButton.cpp
  4. 51 2
      gameplay/src/RenderState.cpp
  5. 22 0
      gameplay/src/RenderState.h
  6. 25 0
      gameplay/src/Slider.cpp

+ 1 - 0
gameplay/src/CheckBox.cpp

@@ -56,6 +56,7 @@ void CheckBox::setChecked(bool checked)
 void CheckBox::setImageSize(float width, float height)
 {
     _imageSize.set(width, height);
+    _dirty = true;
 }
 
 const Vector2& CheckBox::getImageSize() const

+ 5 - 0
gameplay/src/ImageControl.cpp

@@ -76,6 +76,7 @@ void ImageControl::setImage(const char* path)
     _tw = 1.0f / texture->getWidth();
     _th = 1.0f / texture->getHeight();
     texture->release();
+    _dirty = true;
 }
 
 void ImageControl::setRegionSrc(float x, float y, float width, float height)
@@ -86,11 +87,13 @@ void ImageControl::setRegionSrc(float x, float y, float width, float height)
     _uvs.u2 = (x + width) * _tw;
     _uvs.v1 = 1.0f - (y * _th);
     _uvs.v2 = 1.0f - ((y + height) * _th);
+    _dirty = true;
 }
 
 void ImageControl::setRegionSrc(const Rectangle& region)
 {
     setRegionSrc(region.x, region.y, region.width, region.height);
+    _dirty = true;
 }
 
 const Rectangle& ImageControl::getRegionSrc() const
@@ -101,11 +104,13 @@ const Rectangle& ImageControl::getRegionSrc() const
 void ImageControl::setRegionDst(float x, float y, float width, float height)
 {
     _dstRegion.set(x, y, width, height);
+    _dirty = true;
 }
 
 void ImageControl::setRegionDst(const Rectangle& region)
 {
     setRegionDst(region.x, region.y, region.width, region.height);
+    _dirty = true;
 }
 
 const Rectangle& ImageControl::getRegionDst() const

+ 5 - 0
gameplay/src/RadioButton.cpp

@@ -66,12 +66,17 @@ bool RadioButton::isSelected() const
 
 void RadioButton::setSelected(bool selected)
 {
+    if (selected != _selected)
+    {
+        _dirty = true;
+    }
     _selected = selected;
 }
 
 void RadioButton::setImageSize(float width, float height)
 {
     _imageSize.set(width, height);
+    _dirty = true;
 }
 
 const Vector2& RadioButton::getImageSize() const

+ 51 - 2
gameplay/src/RenderState.cpp

@@ -18,6 +18,7 @@
 #define RS_STENCIL_WRITE 256
 #define RS_STENCIL_FUNC 512
 #define RS_STENCIL_OP 1024
+#define RS_FRONT_FACE 2048
 
 #define RS_ALL_ONES 0xFFFFFFFF
 
@@ -513,7 +514,7 @@ void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context)
 RenderState::StateBlock::StateBlock()
     : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(true), _depthFunction(RenderState::DEPTH_LESS),
       _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
-	  _stencilTestEnabled(false), _stencilWrite(RS_ALL_ONES), 
+      _cullFaceSide(CULL_FACE_SIDE_BACK), _frontFace(FRONT_FACE_CCW), _stencilTestEnabled(false), _stencilWrite(RS_ALL_ONES), 
 	  _stencilFunction(RenderState::STENCIL_ALWAYS), _stencilFunctionRef(0), _stencilFunctionMask(RS_ALL_ONES), 
 	  _stencilOpSfail(RenderState::STENCIL_OP_KEEP), _stencilOpDpfail(RenderState::STENCIL_OP_KEEP), _stencilOpDppass(RenderState::STENCIL_OP_KEEP),
       _bits(0L)
@@ -578,6 +579,11 @@ void RenderState::StateBlock::bindNoRestore()
         GL_ASSERT( glCullFace((GLenum)_cullFaceSide) );
         _defaultState->_cullFaceSide = _cullFaceSide;
     }
+    if ((_bits & RS_FRONT_FACE) && (_frontFace != _defaultState->_frontFace))
+    {
+        GL_ASSERT( glFrontFace((GLenum)_frontFace) );
+        _defaultState->_frontFace = _frontFace;
+    }
     if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
     {
         if (_depthTestEnabled) 
@@ -667,6 +673,12 @@ void RenderState::StateBlock::restore(long stateOverrideBits)
         _defaultState->_bits &= ~RS_CULL_FACE_SIDE;
         _defaultState->_cullFaceSide = RenderState::CULL_FACE_SIDE_BACK;
     }
+    if (!(stateOverrideBits & RS_FRONT_FACE) && (_defaultState->_bits & RS_FRONT_FACE))
+    {
+        GL_ASSERT( glFrontFace((GLenum)GL_CCW) );
+        _defaultState->_bits &= ~RS_FRONT_FACE;
+        _defaultState->_frontFace = RenderState::FRONT_FACE_CCW;
+    }
     if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState->_bits & RS_DEPTH_TEST))
     {
         GL_ASSERT( glDisable(GL_DEPTH_TEST) );
@@ -742,6 +754,7 @@ void RenderState::StateBlock::cloneInto(StateBlock* state)
     state->_blendSrc = _blendSrc;
     state->_blendDst = _blendDst;
     state->_cullFaceSide = _cullFaceSide;
+    state->_frontFace = _frontFace;
 	state->_stencilTestEnabled = _stencilTestEnabled;
 	state->_stencilWrite = _stencilWrite;
 	state->_stencilFunction = _stencilFunction;
@@ -882,11 +895,29 @@ static RenderState::CullFaceSide parseCullFaceSide(const char* value)
         return RenderState::CULL_FACE_SIDE_FRONT_AND_BACK;
     else
     {
-        GP_ERROR("Unsupported cull face side value (%s). Will default to BACK if errors are treated as warnings)", value);
+        GP_ERROR("Unsupported cull face side value (%s). Will default to BACK if errors are treated as warnings.", value);
         return RenderState::CULL_FACE_SIDE_BACK;
     }
 }
 
+static RenderState::FrontFace parseFrontFace(const char* value)
+{
+    GP_ASSERT(value);
+
+    // Convert string to uppercase for comparison
+    std::string upper(value);
+    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
+    if (upper == "CCW")
+        return RenderState::FRONT_FACE_CCW;
+    else if (upper == "CW")
+        return RenderState::FRONT_FACE_CW;
+    else
+    {
+        GP_ERROR("Unsupported front face side value (%s). Will default to CCW if errors are treated as warnings.", value);
+        return RenderState::FRONT_FACE_CCW;
+    }
+}
+
 static RenderState::StencilFunction parseStencilFunc(const char* value)
 {
     GP_ASSERT(value);
@@ -971,6 +1002,10 @@ void RenderState::StateBlock::setState(const char* name, const char* value)
     {
         setCullFaceSide(parseCullFaceSide(value));
     }
+    else if (strcmp(name, "frontFace") == 0)
+    {
+        setFrontFace(parseFrontFace(value));
+    }
     else if (strcmp(name, "depthTest") == 0)
     {
         setDepthTest(parseBoolean(value));
@@ -1089,6 +1124,20 @@ void RenderState::StateBlock::setCullFaceSide(CullFaceSide side)
     }
 }
 
+void RenderState::StateBlock::setFrontFace(FrontFace winding)
+{
+    _frontFace = winding;
+    if (_frontFace == FRONT_FACE_CCW)
+    {
+        // Default front face
+        _bits &= ~RS_FRONT_FACE;
+    }
+    else
+    {
+        _bits |= RS_FRONT_FACE;
+    }
+}
+
 void RenderState::StateBlock::setDepthTest(bool enabled)
 {
     _depthTestEnabled = enabled;

+ 22 - 0
gameplay/src/RenderState.h

@@ -180,6 +180,17 @@ public:
         CULL_FACE_SIDE_FRONT_AND_BACK = GL_FRONT_AND_BACK
     };
 
+    /**
+     * Defines the winding of vertices in faces that are considered front facing.
+     *
+     * The initial front face mode is set to FRONT_FACE_CCW.
+     */
+    enum FrontFace
+    {
+        FRONT_FACE_CW,
+        FRONT_FACE_CCW
+    };
+
 	/**
      * Defines the supported stencil compare functions.
 	 * 
@@ -280,10 +291,20 @@ public:
          * Sets the side of the facets to cull.
          *
          * When not explicitly set, the default is to cull back-facing facets.
+         *
          * @param side The side to cull.
          */
         void setCullFaceSide(CullFaceSide side);
 
+        /**
+         * Sets the winding for front facing polygons.
+         *
+         * By default, counter-clockwise wound polygons are considered front facing.
+         *
+         * @param winding The winding for front facing polygons.
+         */
+        void setFrontFace(FrontFace winding);
+
         /**
          * Toggles depth testing.
          *
@@ -396,6 +417,7 @@ public:
         Blend _blendSrc;
         Blend _blendDst;
         CullFaceSide _cullFaceSide;
+        FrontFace _frontFace;
 		bool _stencilTestEnabled;
 		unsigned int _stencilWrite;
 		StencilFunction _stencilFunction;

+ 25 - 0
gameplay/src/Slider.cpp

@@ -59,6 +59,10 @@ Slider* Slider::create(Theme::Style* style, Properties* properties)
 
 void Slider::setMin(float min)
 {
+    if (_min != _min)
+    {
+        _dirty = true;
+    }
     _min = min;
 }
 
@@ -69,6 +73,10 @@ float Slider::getMin() const
 
 void Slider::setMax(float max)
 {
+    if (max != _max)
+    {
+        _dirty = true;
+    }
     _max = max;
 }
 
@@ -94,11 +102,20 @@ float Slider::getValue() const
 
 void Slider::setValue(float value)
 {
+    float oldValue = _value;
     _value = MATH_CLAMP(value, _min, _max);
+    if (_value != value)
+    {
+        _dirty = true;
+    }
 }
 
 void Slider::setValueTextVisible(bool valueTextVisible)
 {
+    if (valueTextVisible != _valueTextVisible)
+    {
+        _dirty = true;
+    }
     _valueTextVisible = valueTextVisible;
 }
 
@@ -109,6 +126,10 @@ bool Slider::isValueTextVisible() const
 
 void Slider::setValueTextAlignment(Font::Justify alignment)
 {
+    if (alignment != _alignment)
+    {
+        _dirty = true;
+    }
     _valueTextAlignment = alignment;
 }
 
@@ -119,6 +140,10 @@ Font::Justify Slider::getValueTextAlignment() const
 
 void Slider::setValueTextPrecision(unsigned int precision)
 {
+    if (precision != _valueTextPrecision)
+    {
+        _dirty = true;
+    }
     _valueTextPrecision = precision;
 }