diff --git a/Aquaria/Hair.cpp b/Aquaria/Hair.cpp index 425a2b9..8944623 100644 --- a/Aquaria/Hair.cpp +++ b/Aquaria/Hair.cpp @@ -46,6 +46,7 @@ Hair::Hair(int nodes, float segmentLength, float hairWidth) } trisToDraw = ibo.initGridIndices_Triangles(2, nodes, false, GPUACCESS_DEFAULT); + updateVBO(); } void Hair::setHeadPosition(const Vector &vec) @@ -60,34 +61,55 @@ const HairNode *Hair::getHairNode(size_t idx) const void Hair::updateVBO() { - const float texBits = 1.0f / (hairNodes.size()-1); + const size_t N = hairNodes.size(); + const float texBits = 1.0f / (N-1); const Vector mul = !_hairfh ? Vector(1, 1) : Vector(-1, -1); - Vector pl, pr; + const float u0 = !_hairfh ? 0.0f : 1.0f; + const float u1 = 1.0f - u0; + + Vector pl(NoInit), pr(NoInit); do { - 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++) + // 2 verts per hair node, each vertex is float xy+uv + + const size_t space = N * 2 * (2*2) * sizeof(float); + float * const begin = (float*)vbo.beginWrite(GPUBUFTYPE_VEC2_TC, space, GPUACCESS_DEFAULT); + float *p = begin; + + for(size_t i = 0; i < N-1; ++i) { - const Vector pc = hairNodes[i].position; + Vector cur = hairNodes[i].position; + Vector diffVec = hairNodes[i+1].position - cur; + diffVec.setLength2D(hairWidth); + pl = diffVec.getPerpendicularLeft(); + pr = diffVec.getPerpendicularRight(); + const float v = texBits * float(i); - 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++ = cur.x + pl.x; + *p++ = cur.y + pl.y; + *p++ = u0; + *p++ = v; - *p++ = pc.x + pr.x; - *p++ = pc.y + pr.y; - *p++ = 1; - *p++ = texBits*i; + *p++ = cur.x + pr.x; + *p++ = cur.y + pr.y; + *p++ = u1; + *p++ = v; } + + // last segment doesn't have a diff vec, just re-use last perpendiculars + Vector cur = hairNodes[N-1].position; + *p++ = cur.x + pl.x; + *p++ = cur.y + pl.y; + *p++ = u0; + *p++ = 1; + + *p++ = cur.x + pr.x; + *p++ = cur.y + pr.y; + *p++ = u1; + *p++ = 1; + + assert(((char*)p - (char*)begin) == space); } while(!vbo.commitWrite()); } @@ -102,6 +124,15 @@ void Hair::onRender(const RenderState& rs) const { vbo.apply(); ibo.drawElements(GL_TRIANGLES, trisToDraw); + + if(RenderObject::renderCollisionShape) + { + glBindTexture(GL_TEXTURE_2D, 0); + RenderObject::lastTextureApplied = 0; + glPointSize(2); + glColor3f(1,0,1); + glDrawArrays(GL_POINTS, 0, vbo.size() / (sizeof(float) * 4)); + } } void Hair::updatePositions() @@ -109,23 +140,11 @@ void Hair::updatePositions() for (size_t i = 1; i < hairNodes.size(); i++) { Vector diff = hairNodes[i].position - hairNodes[i-1].position; - - - if (diff.getLength2D() < segmentLength) - { - diff.setLength2D(segmentLength); - hairNodes[i].position = hairNodes[i-1].position + diff; - } - else if (diff.getLength2D() > segmentLength) - { - - diff.setLength2D(segmentLength); - hairNodes[i].position = hairNodes[i-1].position + diff; - } + diff.setLength2D(segmentLength); + hairNodes[i].position = hairNodes[i-1].position + diff; } } - void Hair::exertForce(const Vector &force, float dt, int usePerc) { const Vector f = force * dt; diff --git a/Aquaria/Hair.h b/Aquaria/Hair.h index a874e04..ce0c96c 100644 --- a/Aquaria/Hair.h +++ b/Aquaria/Hair.h @@ -57,7 +57,7 @@ protected: size_t trisToDraw; void updateVBO(); - DynamicGPUBuffer vbo, ibo; + DynamicGPUBuffer ibo, vbo; }; #endif diff --git a/BBGE/Vector.h b/BBGE/Vector.h index 061b9c3..81e3f26 100644 --- a/BBGE/Vector.h +++ b/BBGE/Vector.h @@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef float scalar_t; +enum _NoInit { NoInit }; + class Vector { public: @@ -37,6 +39,7 @@ public: Vector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a), y(b), z(c) {} Vector(const Vector &vec) : x(vec.x), y(vec.y), z(vec.z) {} + explicit inline Vector(_NoInit) {} float inline *getv(float *v) const diff --git a/BBGE/VertexBuffer.cpp b/BBGE/VertexBuffer.cpp index 62f19b4..d2b5213 100644 --- a/BBGE/VertexBuffer.cpp +++ b/BBGE/VertexBuffer.cpp @@ -167,6 +167,7 @@ struct BufPtrConfig void DynamicGPUBuffer::apply(BufDataType usetype) const { + assert(_datatype != BufDataType(-1)); // if this triggers, then the buffer was never filled with data if(!usetype) usetype = _datatype;