diff --git a/Aquaria/Hair.cpp b/Aquaria/Hair.cpp index eb6a5de..425a2b9 100644 --- a/Aquaria/Hair.cpp +++ b/Aquaria/Hair.cpp @@ -18,14 +18,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../BBGE/MathFunctions.h" +#include "MathFunctions.h" #include "Hair.h" #include "DSQ.h" #include "RenderBase.h" -Hair::Hair(int nodes, float segmentLength, float hairWidth) : RenderObject() +Hair::Hair(int nodes, float segmentLength, float hairWidth) + : RenderObject(), vbo(GPUBUF_DYNAMIC | GPUBUF_VERTEXBUF), ibo(GPUBUF_STATIC | GPUBUF_INDEXBUF) { this->segmentLength = segmentLength; this->hairWidth = hairWidth; @@ -35,17 +36,16 @@ Hair::Hair(int nodes, float segmentLength, float hairWidth) : RenderObject() hairNodes.resize(nodes); - + const float m = 1.0f / float(hairNodes.size()); for (size_t i = 0; i < hairNodes.size(); i++) { - float perc = (float(i)/(float(hairNodes.size()))); - if (perc < 0) - perc = 0; + const float perc = float(i) * m; hairNodes[i].percent = 1.0f-perc; Vector p(0, i*segmentLength, 0); hairNodes[i].position = p; - hairNodes[i].defaultPosition = p; } + + trisToDraw = ibo.initGridIndices_Triangles(2, nodes, false, GPUACCESS_DEFAULT); } void Hair::setHeadPosition(const Vector &vec) @@ -53,42 +53,55 @@ void Hair::setHeadPosition(const Vector &vec) hairNodes[0].position = vec; } -HairNode *Hair::getHairNode(int idx) +const HairNode *Hair::getHairNode(size_t idx) const { - HairNode *h = 0; - int sz = hairNodes.size(); - if (!(idx < 0 || idx >= sz)) - { - h = &hairNodes[idx]; - } - return h; + return idx < hairNodes.size() ? &hairNodes[idx] : NULL; } -void Hair::onRender(const RenderState& rs) const +void Hair::updateVBO() { - glBegin(GL_QUAD_STRIP); const float texBits = 1.0f / (hairNodes.size()-1); const Vector mul = !_hairfh ? Vector(1, 1) : Vector(-1, -1); Vector pl, pr; - for (size_t i = 0; i < hairNodes.size(); i++) + do { - if (i != hairNodes.size()-1) + float *p = (float*)vbo.beginWrite(GPUBUFTYPE_VEC2_TC, hairNodes.size() * 2 * (2*2) * sizeof(float), GPUACCESS_DEFAULT); + for (size_t i = 0; i < hairNodes.size(); i++) { - Vector diffVec = hairNodes[i+1].position - hairNodes[i].position; - diffVec.setLength2D(hairWidth); - pl = diffVec.getPerpendicularLeft() * mul; - pr = diffVec.getPerpendicularRight() * mul; + const Vector pc = hairNodes[i].position; + + if (i != hairNodes.size()-1) + { + Vector diffVec = hairNodes[i+1].position - hairNodes[i].position; + diffVec.setLength2D(hairWidth); + pl = diffVec.getPerpendicularLeft() * mul; + pr = diffVec.getPerpendicularRight() * mul; + } + *p++ = pc.x + pl.x; + *p++ = pc.y + pl.y; + *p++ = 0; + *p++ = texBits*i; + + *p++ = pc.x + pr.x; + *p++ = pc.y + pr.y; + *p++ = 1; + *p++ = texBits*i; } - - Vector p = hairNodes[i].position; - - glTexCoord2f(0, texBits*i); - glVertex3f(p.x + pl.x, p.y + pl.y, 0); - glTexCoord2f(1, texBits*i); - glVertex3f(p.x + pr.x, p.y + pr.y, 0); } - glEnd(); + while(!vbo.commitWrite()); +} + +void Hair::onUpdate(float dt) +{ + updateVBO(); + RenderObject::onUpdate(dt); +} + +void Hair::onRender(const RenderState& rs) const +{ + vbo.apply(); + ibo.drawElements(GL_TRIANGLES, trisToDraw); } void Hair::updatePositions() @@ -98,7 +111,6 @@ void Hair::updatePositions() Vector diff = hairNodes[i].position - hairNodes[i-1].position; - if (diff.getLength2D() < segmentLength) { diff.setLength2D(segmentLength); @@ -110,25 +122,9 @@ void Hair::updatePositions() diff.setLength2D(segmentLength); hairNodes[i].position = hairNodes[i-1].position + diff; } - } } -void Hair::returnToDefaultPositions(float dt) -{ - for (size_t i = 0; i < hairNodes.size(); i++) - { - Vector mov = hairNodes[i].defaultPosition - hairNodes[i].position; - if (!mov.isLength2DIn(2)) - { - if (mov.x != 0 || mov.y != 0) - { - mov *= dt; - hairNodes[i].position += mov; - } - } - } -} void Hair::exertForce(const Vector &force, float dt, int usePerc) { diff --git a/Aquaria/Hair.h b/Aquaria/Hair.h index 8e2ae49..a874e04 100644 --- a/Aquaria/Hair.h +++ b/Aquaria/Hair.h @@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __hair__ #define __hair__ -#include "../BBGE/Quad.h" +#include "RenderObject.h" +#include "RenderGrid.h" struct HairNode { @@ -29,7 +30,6 @@ struct HairNode {} float percent; // percent of how much force is affected on this node Vector position; // position of the hair node - Vector defaultPosition; // default position of the hair node }; class Hair : public RenderObject @@ -40,7 +40,6 @@ public: void exertForce(const Vector &force, float dt, int usePerc=0); void exertNodeForce(size_t idx, const Vector &force, float dt, int usePerc=0); void updatePositions(); - void returnToDefaultPositions(float dt); void setTextureFlip(bool flip) { _hairfh = flip; } float hairWidth; @@ -49,13 +48,16 @@ public: void setHeadPosition(const Vector &pos); - void exertWave(float dt); - void exertGravityWave(float dt); - HairNode *getHairNode(int idx); + const HairNode *getHairNode(size_t idx) const; protected: float segmentLength; + void onUpdate(float dt) OVERRIDE; void onRender(const RenderState& rs) const OVERRIDE; bool _hairfh; + size_t trisToDraw; + void updateVBO(); + + DynamicGPUBuffer vbo, ibo; }; #endif diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 778ba28..f04c28f 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -8334,7 +8334,7 @@ luaFunc(entity_getHairPosition) int idx = lua_tointeger(L, 2); if (se && se->hair) { - HairNode *h = se->hair->getHairNode(idx); + const HairNode *h = se->hair->getHairNode(idx); if (h) { x = h->position.x; diff --git a/BBGE/VertexBuffer.cpp b/BBGE/VertexBuffer.cpp index ff87ea1..62f19b4 100644 --- a/BBGE/VertexBuffer.cpp +++ b/BBGE/VertexBuffer.cpp @@ -321,6 +321,7 @@ size_t DynamicGPUBuffer::initGridIndices_Triangles(size_t w, size_t h, bool inve const size_t quadsx = w - 1; const size_t quadsy = h - 1; const size_t quads = quadsx * quadsy; + assert(quads); const size_t border = 4; // for GL_LINE_LOOP do {