Plane: Add fallback without GL_REPEAT texture wrapping
This isn't supported under GLES 2.0 for npot textures.
This commit is contained in:
parent
a17043f785
commit
20e46a98dd
|
@ -97,6 +97,7 @@ void initGLFunctions()
|
|||
|
||||
// FIXME: Set based on GL kind
|
||||
gl.unpack_subimage = true;
|
||||
gl.npot_repeat = true;
|
||||
|
||||
#define HAVE_EXT(_ext) ext.contains("GL_" #_ext)
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ struct GLFunctions
|
|||
GL_DEBUG_KHR_FUN
|
||||
|
||||
bool unpack_subimage;
|
||||
bool npot_repeat;
|
||||
|
||||
#undef GL_FUN
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "gl-util.h"
|
||||
#include "quad.h"
|
||||
#include "quadarray.h"
|
||||
#include "transform.h"
|
||||
#include "etc-internal.h"
|
||||
#include "shader.h"
|
||||
|
@ -35,6 +36,12 @@
|
|||
|
||||
#include <sigc++/connection.h>
|
||||
|
||||
static float fwrap(float value, float range)
|
||||
{
|
||||
float res = fmod(value, range);
|
||||
return res < 0 ? res + range : res;
|
||||
}
|
||||
|
||||
struct PlanePrivate
|
||||
{
|
||||
Bitmap *bitmap;
|
||||
|
@ -50,7 +57,7 @@ struct PlanePrivate
|
|||
|
||||
bool quadSourceDirty;
|
||||
|
||||
Quad quad;
|
||||
SimpleQuadArray qArray;
|
||||
|
||||
EtcTemps tmp;
|
||||
|
||||
|
@ -68,6 +75,8 @@ struct PlanePrivate
|
|||
{
|
||||
prepareCon = shState->prepareDraw.connect
|
||||
(sigc::mem_fun(this, &PlanePrivate::prepare));
|
||||
|
||||
qArray.resize(1);
|
||||
}
|
||||
|
||||
~PlanePrivate()
|
||||
|
@ -77,13 +86,53 @@ struct PlanePrivate
|
|||
|
||||
void updateQuadSource()
|
||||
{
|
||||
FloatRect srcRect;
|
||||
srcRect.x = (sceneGeo.yOrigin + ox) / zoomX;
|
||||
srcRect.y = (sceneGeo.xOrigin + oy) / zoomY;
|
||||
srcRect.w = sceneGeo.rect.w / zoomX;
|
||||
srcRect.h = sceneGeo.rect.h / zoomY;
|
||||
if (gl.npot_repeat)
|
||||
{
|
||||
FloatRect srcRect;
|
||||
srcRect.x = (sceneGeo.yOrigin + ox) / zoomX;
|
||||
srcRect.y = (sceneGeo.xOrigin + oy) / zoomY;
|
||||
srcRect.w = sceneGeo.rect.w / zoomX;
|
||||
srcRect.h = sceneGeo.rect.h / zoomY;
|
||||
|
||||
quad.setTexRect(srcRect);
|
||||
Quad::setTexRect(&qArray.vertices[0], srcRect);
|
||||
qArray.commit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bitmap)
|
||||
return;
|
||||
|
||||
/* Scaled (zoomed) bitmap dimensions */
|
||||
double sw = bitmap->width() * zoomX;
|
||||
double sh = bitmap->height() * zoomY;
|
||||
|
||||
/* Plane offset wrapped by scaled bitmap dims */
|
||||
float wox = fwrap(ox, sw);
|
||||
float woy = fwrap(oy, sh);
|
||||
|
||||
/* Viewport dimensions */
|
||||
int vpw = sceneGeo.rect.w;
|
||||
int vph = sceneGeo.rect.h;
|
||||
|
||||
/* Amount the scaled bitmap is tiled (repeated) */
|
||||
size_t tilesX = ceil((vpw - sw + wox) / sw) + 1;
|
||||
size_t tilesY = ceil((vph - sh + woy) / sh) + 1;
|
||||
|
||||
FloatRect tex = bitmap->rect();
|
||||
|
||||
qArray.resize(tilesX * tilesY);
|
||||
|
||||
for (size_t y = 0; y < tilesY; ++y)
|
||||
for (size_t x = 0; x < tilesX; ++x)
|
||||
{
|
||||
SVertex *vert = &qArray.vertices[(y*tilesX + x) * 4];
|
||||
FloatRect pos(x*sw - wox, y*sh - woy, sw, sh);
|
||||
|
||||
Quad::setTexPosRect(vert, tex, pos);
|
||||
}
|
||||
|
||||
qArray.commit();
|
||||
}
|
||||
|
||||
void prepare()
|
||||
|
@ -238,18 +287,22 @@ void Plane::draw()
|
|||
glState.blendMode.pushSet(p->blendType);
|
||||
|
||||
p->bitmap->bindTex(*base);
|
||||
TEX::setRepeat(true);
|
||||
|
||||
p->quad.draw();
|
||||
if (gl.npot_repeat)
|
||||
TEX::setRepeat(true);
|
||||
|
||||
TEX::setRepeat(false);
|
||||
p->qArray.draw();
|
||||
|
||||
if (gl.npot_repeat)
|
||||
TEX::setRepeat(false);
|
||||
|
||||
glState.blendMode.pop();
|
||||
}
|
||||
|
||||
void Plane::onGeometryChange(const Scene::Geometry &geo)
|
||||
{
|
||||
p->quad.setPosRect(FloatRect(geo.rect));
|
||||
if (gl.npot_repeat)
|
||||
Quad::setPosRect(&p->qArray.vertices[0], FloatRect(geo.rect));
|
||||
|
||||
p->sceneGeo = geo;
|
||||
p->quadSourceDirty = true;
|
||||
|
|
Loading…
Reference in New Issue