mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-05-11 19:43:50 +00:00
rework QuadGrid and some anim editor internal things to use VBOs
This commit is contained in:
parent
7b7681ffb6
commit
db5fcfa632
5 changed files with 186 additions and 73 deletions
|
@ -77,34 +77,73 @@ class TimelineTickRender : public RenderObject
|
|||
public:
|
||||
TimelineTickRender()
|
||||
: bg("black", Vector(400, 0))
|
||||
, vbo(GPUBUF_VERTEXBUF | GPUBUF_DYNAMIC)
|
||||
{
|
||||
addChild(&bg, PM_STATIC, RBP_ON);
|
||||
bg.setWidthHeight(800, TIMELINE_HEIGHT);
|
||||
bg.alphaMod = 0.2f;
|
||||
updateVBO();
|
||||
}
|
||||
|
||||
virtual ~TimelineTickRender()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onUpdate(float dt) OVERRIDE
|
||||
{
|
||||
const float h2 = TIMELINE_HEIGHT * 0.5f;
|
||||
const float tx = ae->getAnimTime() * (TIMELINE_GRIDSIZE / TIMELINE_UNIT);
|
||||
// Update data for last 2 vertices (last line)
|
||||
const float linedata[] =
|
||||
{
|
||||
tx + TIMELINE_X_OFFS, -h2,
|
||||
tx + TIMELINE_X_OFFS, h2
|
||||
};
|
||||
vbo.updatePartial((verts * 2 * sizeof(float)) - sizeof(linedata), &linedata[0], sizeof(linedata));
|
||||
|
||||
RenderObject::onUpdate(dt);
|
||||
}
|
||||
|
||||
void updateVBO()
|
||||
{
|
||||
const size_t lines = (size_t(800) / TIMELINE_GRIDSIZE) + 1;
|
||||
verts = lines * 2;
|
||||
const size_t bytes = verts * 2 * sizeof(float);
|
||||
const float h2 = TIMELINE_HEIGHT * 0.5f;
|
||||
float *p;
|
||||
do
|
||||
{
|
||||
p = (float*)vbo.beginWrite(GPUBUFTYPE_VEC2, bytes, GPUACCESS_DEFAULT);
|
||||
|
||||
for (int x = 0; x < 800; x += TIMELINE_GRIDSIZE)
|
||||
{
|
||||
*p++ = x + TIMELINE_X_OFFS; *p++ = -h2;
|
||||
*p++ = x + TIMELINE_X_OFFS; *p++ = h2;
|
||||
}
|
||||
|
||||
// Last 2 vertices -- colored differently
|
||||
const float tx = ae->getAnimTime() * (TIMELINE_GRIDSIZE / TIMELINE_UNIT);
|
||||
*p++ = tx + TIMELINE_X_OFFS; *p++ = -h2;
|
||||
*p++ = tx + TIMELINE_X_OFFS; *p++ = h2;
|
||||
|
||||
}
|
||||
while(!vbo.commitWriteExact(p));
|
||||
}
|
||||
|
||||
private:
|
||||
Quad bg;
|
||||
DynamicGPUBuffer vbo;
|
||||
size_t verts;
|
||||
void onRender(const RenderState& rs) const OVERRIDE
|
||||
{
|
||||
glLineWidth(1);
|
||||
glBegin(GL_LINES);
|
||||
vbo.apply();
|
||||
|
||||
glColor4f(1, 1, 1, 1);
|
||||
const float h2 = TIMELINE_HEIGHT * 0.5f;
|
||||
for (int x = 0; x < 800; x += TIMELINE_GRIDSIZE)
|
||||
{
|
||||
glVertex3f(x + TIMELINE_X_OFFS, -h2, 0);
|
||||
glVertex3f(x + TIMELINE_X_OFFS, h2, 0);
|
||||
}
|
||||
glDrawArrays(GL_LINES, 0, verts-2);
|
||||
|
||||
glColor4f(0, 1, 0, 1);
|
||||
float tx = ae->getAnimTime() * (TIMELINE_GRIDSIZE / TIMELINE_UNIT);
|
||||
glVertex3f(tx + TIMELINE_X_OFFS, -h2, 0);
|
||||
glVertex3f(tx + TIMELINE_X_OFFS, h2, 0);
|
||||
glEnd();
|
||||
glDrawArrays(GL_LINES, verts-2, 2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -115,7 +154,7 @@ public:
|
|||
DebugFont label;
|
||||
|
||||
TimelineRender(int page)
|
||||
: page(page), label(6)
|
||||
: page(page), label(6), vbo(GPUBUF_VERTEXBUF | GPUBUF_DYNAMIC)
|
||||
{
|
||||
setWidthHeight(800, 10);
|
||||
addChild(&label, PM_STATIC);
|
||||
|
@ -159,6 +198,30 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
DynamicGPUBuffer vbo;
|
||||
|
||||
void updateVBO()
|
||||
{
|
||||
SkeletalSprite *spr = ae->getPageSprite(page);
|
||||
if(!spr->isLoaded())
|
||||
return;
|
||||
|
||||
const float h2 = height * 0.5f;
|
||||
const float tx = spr->getAnimationLayer(0)->timer * (TIMELINE_GRIDSIZE / TIMELINE_UNIT);
|
||||
const float linedata[] =
|
||||
{
|
||||
tx + TIMELINE_X_OFFS, h2 - 5,
|
||||
tx + TIMELINE_X_OFFS, h2 + 5
|
||||
};
|
||||
vbo.upload(GPUBUFTYPE_VEC2, &linedata[0], sizeof(linedata));
|
||||
}
|
||||
|
||||
virtual void onUpdate(float dt) OVERRIDE
|
||||
{
|
||||
updateVBO();
|
||||
Quad::onUpdate(dt);
|
||||
}
|
||||
|
||||
void onRender(const RenderState& rs) const OVERRIDE
|
||||
{
|
||||
SkeletalSprite *spr = ae->getPageSprite(page);
|
||||
|
@ -176,13 +239,13 @@ private:
|
|||
Quad::onRender(rs);
|
||||
glPopMatrix();
|
||||
|
||||
glColor4f(0, 1, 0, 1);
|
||||
glLineWidth(3);
|
||||
glBegin(GL_LINES);
|
||||
float tx = spr->getAnimationLayer(0)->timer * (TIMELINE_GRIDSIZE / TIMELINE_UNIT);
|
||||
glVertex3f(tx + TIMELINE_X_OFFS, h2 - 5, 0);
|
||||
glVertex3f(tx + TIMELINE_X_OFFS, h2 + 5, 0);
|
||||
glEnd();
|
||||
if(vbo.size())
|
||||
{
|
||||
glColor4f(0, 1, 0, 1);
|
||||
glLineWidth(3);
|
||||
vbo.apply();
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<KeyframeWidget*> keyframes;
|
||||
|
@ -2167,6 +2230,7 @@ void AnimationEditor::selectPage(unsigned page)
|
|||
|
||||
void AnimationEditor::updateTimelineGrid()
|
||||
{
|
||||
timelineTicks->updateVBO();
|
||||
std::ostringstream os;
|
||||
os << "Grid: " << TIMELINE_GRIDSIZE;
|
||||
gridsize->setText(os.str());
|
||||
|
|
|
@ -5,15 +5,19 @@
|
|||
|
||||
QuadGrid::QuadGrid(size_t w, size_t h)
|
||||
: pauseLevel(0), _w(w+1), _h(h+1)
|
||||
, dirty(true)
|
||||
, vbo(GPUBUF_DYNAMIC | GPUBUF_VERTEXBUF)
|
||||
, ibo(GPUBUF_STATIC | GPUBUF_INDEXBUF)
|
||||
, _points((w+1) * (h+1))
|
||||
{
|
||||
addType(SCO_QUAD_GRID);
|
||||
_points.resize((w+1) * (h+1));
|
||||
resetUV();
|
||||
resetPos(1, 1);
|
||||
this->width = 2;
|
||||
this->height = 2;
|
||||
this->cull = false;
|
||||
this->repeatTexture = true;
|
||||
_numtris = ibo.initGridIndices_Triangles(w+1, h+1, false, GPUACCESS_DEFAULT);
|
||||
}
|
||||
|
||||
QuadGrid* QuadGrid::New(size_t w, size_t h)
|
||||
|
@ -46,6 +50,8 @@ void QuadGrid::resetUV(float xmul, float ymul)
|
|||
}
|
||||
v += incY;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void QuadGrid::resetPos(float w, float h, float xoffs, float yoffs)
|
||||
|
@ -66,50 +72,29 @@ void QuadGrid::resetPos(float w, float h, float xoffs, float yoffs)
|
|||
row[x].y = yy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void drawOnePoint(const QuadGrid::Point& p, float ox, float oy)
|
||||
{
|
||||
glTexCoord2f(p.u + ox, p.v + oy);
|
||||
glVertex2f(p.x, p.y);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
||||
void QuadGrid::onRender(const RenderState& rs) const
|
||||
{
|
||||
glColor4f(color.x, color.y, color.z, alpha.x * alphaMod);
|
||||
|
||||
const float ox = texOffset.x;
|
||||
const float oy = texOffset.y;
|
||||
const size_t NX = pointsX();
|
||||
|
||||
// go over grids
|
||||
const size_t W = quadsX();
|
||||
const size_t H = quadsY();
|
||||
for(size_t y = 0; y < H; ++y)
|
||||
{
|
||||
const Point * const row0 = &_points[y * NX];
|
||||
const Point * const row1 = row0 + NX;
|
||||
for(size_t x = 0; x < W; ++x)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
drawOnePoint(row0[x], ox, oy);
|
||||
drawOnePoint(row0[x+1], ox, oy);
|
||||
drawOnePoint(row1[x+1], ox, oy);
|
||||
drawOnePoint(row1[x], ox, oy);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
vbo.apply();
|
||||
ibo.drawElements(GL_TRIANGLES, _numtris);
|
||||
}
|
||||
|
||||
void QuadGrid::onUpdate(float dt)
|
||||
{
|
||||
if(pauseLevel < core->particlesPaused)
|
||||
return;
|
||||
const bool interp = texOffset.isInterpolating();
|
||||
if(!(pauseLevel < core->particlesPaused))
|
||||
{
|
||||
texOffset.update(dt);
|
||||
RenderObject::onUpdate(dt);
|
||||
}
|
||||
|
||||
texOffset.update(dt);
|
||||
|
||||
RenderObject::onUpdate(dt);
|
||||
if(dirty || interp)
|
||||
updateVBO();
|
||||
}
|
||||
|
||||
void QuadGrid::onSetTexture() // same as Quad::setTexture()
|
||||
|
@ -125,3 +110,24 @@ void QuadGrid::onSetTexture() // same as Quad::setTexture()
|
|||
height = 64;
|
||||
}
|
||||
}
|
||||
|
||||
void QuadGrid::updateVBO()
|
||||
{
|
||||
const size_t bytes = _points.size() * sizeof(Point);
|
||||
|
||||
do
|
||||
{
|
||||
const Point *s = &_points[0];
|
||||
Point *p = (Point*)vbo.beginWrite(GPUBUFTYPE_VEC2_TC, bytes, GPUACCESS_DEFAULT);
|
||||
|
||||
for(size_t i = 0; i < _points.size(); ++i, ++p, ++s)
|
||||
{
|
||||
p->x = s->x;
|
||||
p->y = s->y;
|
||||
p->u = s->u + texOffset.x;
|
||||
p->v = s->v + texOffset.y;
|
||||
}
|
||||
}
|
||||
while(!vbo.commitWrite());
|
||||
dirty = false;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include "RenderObject.h"
|
||||
#include "VertexBuffer.h"
|
||||
|
||||
/*
|
||||
This class is an extension for Quad, where coordinates and UV coords can be set freely.
|
||||
|
@ -34,6 +35,7 @@ public:
|
|||
|
||||
inline Point& operator()(size_t x, size_t y)
|
||||
{
|
||||
dirty = true;
|
||||
return _points[y * _w + x];
|
||||
}
|
||||
|
||||
|
@ -59,12 +61,17 @@ public:
|
|||
public:
|
||||
InterpolatedVector texOffset;
|
||||
int pauseLevel;
|
||||
|
||||
bool dirty;
|
||||
|
||||
private:
|
||||
QuadGrid(size_t w, size_t h);
|
||||
const size_t _w, _h; // number of points in each direction (2x3 quads => 3x4 grid points)
|
||||
void updateVBO();
|
||||
|
||||
DynamicGPUBuffer vbo, ibo;
|
||||
|
||||
std::vector<Point> _points;
|
||||
size_t _numtris;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -141,16 +141,7 @@ bool DynamicGPUBuffer::_commitWrite(size_t used)
|
|||
// -> didn't map, but wrote to host memory. upload it.
|
||||
assert(_h_data);
|
||||
assert(used <= _h_cap);
|
||||
if(used)
|
||||
{
|
||||
if(used <= _d_cap)
|
||||
glBufferSubDataARB(_gl_binding, 0, used, _h_data); // update existing buffer
|
||||
else
|
||||
{
|
||||
_d_cap = used;
|
||||
glBufferDataARB(_gl_binding, used, _h_data, _gl_usage); // alloc new buffer
|
||||
}
|
||||
}
|
||||
_uploadFromHost(_h_data, used);
|
||||
}
|
||||
// else nothing to do
|
||||
|
||||
|
@ -161,21 +152,63 @@ bool DynamicGPUBuffer::_commitWrite(size_t used)
|
|||
void DynamicGPUBuffer::upload(BufDataType type, const void* data, size_t size)
|
||||
{
|
||||
_datatype = type;
|
||||
_size = size;
|
||||
|
||||
if(_HasARB)
|
||||
{
|
||||
const unsigned id = _ensureDBuf();
|
||||
unsigned& last = s_lastBuffer[_usage & GPUBUF_BINDING_MASK];
|
||||
if(id != last)
|
||||
{
|
||||
last = id;
|
||||
glBindBufferARB(_gl_binding, id);
|
||||
}
|
||||
_d_cap = size;
|
||||
glBufferDataARB(_gl_binding, size, data, _gl_usage);
|
||||
const unsigned id = _Bind(_ensureDBuf(), _gl_binding, _usage);
|
||||
_uploadFromHost(data, size);
|
||||
}
|
||||
else
|
||||
memcpy(_ensureBytes(size), data, size);
|
||||
{
|
||||
void *dst = _ensureBytes(size);
|
||||
if(data)
|
||||
memcpy(dst, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned DynamicGPUBuffer::_Bind(unsigned id, unsigned binding, unsigned usage)
|
||||
{
|
||||
unsigned& last = s_lastBuffer[usage & GPUBUF_BINDING_MASK];
|
||||
if(id != last)
|
||||
{
|
||||
last = id;
|
||||
glBindBufferARB(binding, id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
// Assumes buffer is already bound
|
||||
void DynamicGPUBuffer::_uploadFromHost(const void * data, size_t size)
|
||||
{
|
||||
assert(_HasARB);
|
||||
if(size)
|
||||
{
|
||||
if(size <= _d_cap)
|
||||
glBufferSubDataARB(_gl_binding, 0, size, data); // update existing buffer
|
||||
else
|
||||
{
|
||||
_d_cap = size;
|
||||
glBufferDataARB(_gl_binding, size, data, _gl_usage); // alloc new buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicGPUBuffer::updatePartial(size_t offset, const void * data, size_t size)
|
||||
{
|
||||
if(_HasARB)
|
||||
{
|
||||
assert(_bufid); // Must have been previously allocated
|
||||
assert(offset + size <= _d_cap);
|
||||
_Bind(_bufid, _gl_binding, _usage);
|
||||
glBufferSubDataARB(_gl_binding, offset, size, data);
|
||||
}
|
||||
|
||||
if(_h_data)
|
||||
{
|
||||
assert(offset + size <= _h_cap);
|
||||
memcpy((char*)_h_data + offset, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned s_gltype[] =
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
bool commitWriteExact(const void *p); // asserts that as many bytes as allocated were written
|
||||
|
||||
void upload(BufDataType type, const void *data, size_t size);
|
||||
void updatePartial(size_t offset, const void *data, size_t size);
|
||||
|
||||
// uses own data for indexing and prev. applied buffer for the data to draw
|
||||
void drawElements(unsigned glmode, size_t n, size_t first = 0) const;
|
||||
|
@ -93,6 +94,8 @@ private:
|
|||
void* _ensureBytes(size_t bytes);
|
||||
unsigned _ensureDBuf();
|
||||
bool _commitWrite(size_t used);
|
||||
void _uploadFromHost(const void *data, size_t size);
|
||||
static unsigned _Bind(unsigned id, unsigned binding, unsigned usage);
|
||||
|
||||
unsigned _bufid;
|
||||
unsigned _gl_binding;
|
||||
|
|
Loading…
Add table
Reference in a new issue