1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 09:44:02 +00:00
Aquaria/BBGE/RenderAPI.cpp

183 lines
3.7 KiB
C++

#include "RenderAPI.h"
#include "Base.h"
#include "RenderBase.h"
namespace RenderAPI {
void BufferBase::destroy()
{
deleteBuffer(&_bufid);
}
void BufferBase::upload(Hint usage)
{
updateBuffer(&_bufid, _data, _bytes, usage);
}
// ----- GL backend starts here -----
// TODO: move backend to separate file once finalized
struct BlendParams
{
GLenum src, dst;
};
static const BlendParams s_blendParams[] =
{
{ GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
{ GL_SRC_ALPHA, GL_ONE },
{ GL_ZERO, GL_SRC_ALPHA },
{ GL_ZERO, GL_SRC_COLOR },
};
static const GLenum s_primTypes[] =
{
GL_POINTS,
GL_LINES,
GL_LINE_STRIP,
GL_QUADS,
GL_QUAD_STRIP
};
static void renderNonIndexed(const ObjectData& d)
{
switch(d.layout)
{
case RAPI_LAYOUT_2D:
{
::glColor4fv(&d.color.r);
const size_t n = d.verts->bytes() / sizeof(float);
const float *p = (const float*)d.verts->data();
const float * const end = p + n;
for( ; p < end; p += 4) // Vertex2D
{
::glTexCoord2f(p[0], p[1]);
::glVertex2f(p[2], p[3]);
}
}
break;
case RAPI_LAYOUT_2D_COLOR:
{
const size_t n = d.verts->bytes() / sizeof(float);
const float *p = (const float*)d.verts->data();
const float * const end = p + n;
for( ; p < end; p += 8) // Vertex2DColor
{
::glColor4fv(&p[4]);
::glTexCoord2f(p[0], p[1]);
::glVertex2f(p[2], p[3]);
}
}
break;
}
}
static void renderIndexed(const ObjectData& d)
{
switch(d.layout)
{
case RAPI_LAYOUT_2D:
{
::glColor4fv(&d.color.r);
const size_t n = d.indices->bytes() / sizeof(unsigned short);
const unsigned short *idx = (const unsigned short*)d.indices->data();
const float * const pbase = (const float*)d.verts->data();
const unsigned short * const end = idx + n;
for( ; idx < end; ++idx)
{
const float *p = pbase + *idx;
::glTexCoord2f(p[0], p[1]);
::glVertex2f(p[2], p[3]);
}
}
break;
case RAPI_LAYOUT_2D_COLOR:
{
const size_t n = d.indices->bytes() / sizeof(unsigned short);
const unsigned short *idx = (const unsigned short*)d.indices->data();
const float * const pbase = (const float*)d.verts->data();
const unsigned short * const end = idx + n;
for( ; idx < end; ++idx)
{
const float *p = pbase + *idx;
::glColor4fv(&p[4]);
::glTexCoord2f(p[0], p[1]);
::glVertex2f(p[2], p[3]);
}
}
break;
}
}
void render(const ObjectData* objs, size_t n)
{
::glPushMatrix();
char lastblend = BLEND_DISABLED - 1; // always fail the first check
unsigned lasttex = unsigned(-1);
const ObjectData* const end = objs + n;
for( ; objs < end; ++objs)
{
const ObjectData& d = *objs;
if(lastblend != d.blend)
{
lastblend = d.blend;
unsigned ublend = unsigned(int(d.blend)); // this underflows if BLEND_DISABLED
if (ublend < Countof(s_blendParams))
{
::glEnable(GL_BLEND);
const BlendParams& bp = s_blendParams[ublend];
::glBlendFunc(bp.src, bp.dst);
}
else
{
::glDisable(GL_BLEND);
::glDisable(GL_ALPHA_TEST);
}
}
::glLoadMatrixf(d.pmat);
const unsigned prim = d.prim;
switch(prim)
{
case RAPI_PRIM_POINTS:
::glPointSize(d.u.linewidth);
break;
case RAPI_PRIM_LINES:
case RAPI_PRIM_LINE_STRIP:
::glLineWidth(d.u.linewidth);
break;
default:
if(d.u.texid != lasttex)
{
lasttex = d.u.texid;
::glBindTexture(GL_TEXTURE_2D, d.u.texid);
}
}
::glBegin(s_primTypes[prim]);
if(!d.indices)
renderNonIndexed(d);
else
renderIndexed(d);
::glEnd();
}
::glPopMatrix();
}
void updateBuffer(unsigned* pbufid, const void* data, size_t bytes, RenderAPI::BufferBase::Hint usage)
{
}
void deleteBuffer(unsigned* pbufid)
{
}
}