Skip to content

Commit

Permalink
Made Tegra 3 friendly.
Browse files Browse the repository at this point in the history
Tegra 3 has some limitations on GL_REPEAT and mipmapping when it comes
to non power of two textures, and is strict when it comes to missing
precision specifiers in shaders.
  • Loading branch information
capisce committed Sep 25, 2012
1 parent cd21f98 commit 35c74c9
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 58 deletions.
43 changes: 40 additions & 3 deletions common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,32 @@ void drawTexture(const QRectF &target, const QSizeF &viewport, GLuint texture, q
program->disableAttributeArray(texCoordAttr);
}

GLuint generateTexture(const QImage &image, bool mipmaps)
int isPowerOfTwo (unsigned int x)
{
return !(x & (x - 1));
}

bool canUseMipmaps(const QSize &size)
{
static bool initialized = false;
static bool supportsNonPowerOfTwoMipmaps = true;
if (!initialized) {
printf("VENDOR string: %s\n", glGetString(GL_VENDOR));
printf("RENDERER string: %s\n", glGetString(GL_RENDERER));

supportsNonPowerOfTwoMipmaps = !QByteArray(reinterpret_cast<const char *>(glGetString(GL_RENDERER))).contains("Tegra 3");
initialized = true;

printf("Supports non-power-of-two mipmaps: %d\n", int(supportsNonPowerOfTwoMipmaps));
}

return supportsNonPowerOfTwoMipmaps || (isPowerOfTwo(size.width()) && isPowerOfTwo(size.height()));
}

GLuint generateTexture(const QImage &image, bool mipmaps, bool repeat)
{
mipmaps = mipmaps && canUseMipmaps(image.size());

GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
Expand All @@ -233,14 +257,16 @@ GLuint generateTexture(const QImage &image, bool mipmaps)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);

return id;
}

void updateSubImage(GLuint texture, const QImage &image, const QRect &rect, bool mipmaps)
{
mipmaps = mipmaps && canUseMipmaps(image.size());

QVector<uchar> data;
for (int i = rect.y(); i <= rect.bottom(); ++i) {
QRgb *p = (QRgb *)image.scanLine(i);
Expand Down Expand Up @@ -344,3 +370,14 @@ bool useSimpleShading()
return simple;
}

bool fpsDebug()
{
static bool initialized = false;
static bool fpsDebug = false;
if (!initialized) {
fpsDebug = QCoreApplication::arguments().contains(QLatin1String("--show-fps"));
initialized = true;
}
return fpsDebug;
}

4 changes: 3 additions & 1 deletion common.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void drawTexture(const QRectF &target, const QSizeF &viewport, GLuint texture, q
void drawRect(const QRectF &target, const QSizeF &viewport, const QColor &color, GLdouble z = 0.0);
void drawConvexSolid(const Camera &camera, const QVector<QVector3D> &outline, const QColor &color);

GLuint generateTexture(const QImage &image, bool mipmaps = true);
GLuint generateTexture(const QImage &image, bool mipmaps = true, bool repeat = true);
void updateSubImage(GLuint texture, const QImage &image, const QRect &rect, bool mipmaps = true);

QOpenGLShaderProgram *generateShaderProgram(QObject *parent, QByteArray vsrc, QByteArray fsrc);
Expand All @@ -53,6 +53,8 @@ enum TileType

QVector<QVector3D> tile(int x, int z, TileType type, QVector3D scale = QVector3D(1, 1, 1), QVector3D dim = QVector3D(1, 1, 1));

bool canUseMipmaps(const QSize &size);
bool useSimpleShading();
bool fpsDebug();

#endif
2 changes: 1 addition & 1 deletion entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,6 @@ void Entity::initialize()
m_tileWidth = w;
m_tileHeight = h;

m_texture = generateTexture(image, false);
m_texture = generateTexture(image, false, false);
m_textureSize = image.size();
}
2 changes: 1 addition & 1 deletion light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void Light::initialize(QObject *parent)
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" vec4 pos = vertexAttr + offset;\n"
" highp vec4 pos = vertexAttr + offset;\n"
" gl_Position = matrix * pos;\n"
"}\n";

Expand Down
3 changes: 2 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ int main(int argc, char **argv)
app.setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents);

View view(app.primaryScreen()->geometry());
view.showFullScreen();
view.resize(1280, 800);
view.show();

return app.exec();
}
32 changes: 17 additions & 15 deletions surfaceitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ SurfaceItem::SurfaceItem(WaylandSurface *surface)
connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
connect(surface, SIGNAL(sizeChanged()), this, SLOT(sizeChanged()));
m_dirty = QRect(QPoint(), surface->size());

qDebug() << "surface size:" << surface->size();
m_opacityAnimation = new QPropertyAnimation(this, "opacity");
m_opacityAnimation->setDuration(400);
sizeChanged();
Expand Down Expand Up @@ -107,7 +109,7 @@ void SurfaceItem::initialize(const Map &map, QObject *parent)
"uniform lowp float focusColor;\n"
"void main(void)\n"
"{\n"
" vec4 tex = texture2D(texture, texCoord);\n"
" lowp vec4 tex = texture2D(texture, texCoord);\n"
" gl_FragColor = tex * 0.9 * focusColor * tex.a;\n"
"}\n"
:
Expand All @@ -122,22 +124,22 @@ void SurfaceItem::initialize(const Map &map, QObject *parent)
"uniform lowp float focusColor;\n"
"void main(void)\n"
"{\n"
" vec4 tex = texture2D(texture, texCoord);\n"
" vec2 dt = abs(texCoord - vec2(0.5));\n"
" vec3 toEyeN = normalize(eye - p);\n"
" vec4 result = tex * 0.9;\n" // light source
" highp vec4 tex = texture2D(texture, texCoord);\n"
" highp vec2 dt = abs(texCoord - vec2(0.5));\n"
" highp vec3 toEyeN = normalize(eye - p);\n"
" highp vec4 result = tex * 0.9;\n" // light source
" for (int i = 0; i < NUM_LIGHTS; ++i) {\n"
" vec3 toLight = lights[i] - p;\n"
" vec3 toLightN = normalize(toLight);\n"
" float normalDotLight = dot(toLightN, normal);\n"
" float lightDistance = length(toLight);\n"
" float reflectionDotView = max(0.0, dot(normalize(((2.0 * normal) * normalDotLight) - toLightN), toEyeN));\n"
" vec3 specular = 0.5 * vec3(0.75 * pow(reflectionDotView, 8.0) / max(1.5, 0.8 * lightDistance));\n"
" highp vec3 toLight = lights[i] - p;\n"
" highp vec3 toLightN = normalize(toLight);\n"
" highp float normalDotLight = dot(toLightN, normal);\n"
" highp float lightDistance = length(toLight);\n"
" highp float reflectionDotView = max(0.0, dot(normalize(((2.0 * normal) * normalDotLight) - toLightN), toEyeN));\n"
" highp vec3 specular = 0.5 * vec3(0.75 * pow(reflectionDotView, 8.0) / max(1.5, 0.8 * lightDistance));\n"
" if (i < numLights)\n"
" result += vec4(specular, 1.0);\n"
" }\n"
" vec4 blend = mix(vec4(0.0), result * tex.a, (1.0 - smoothstep(0.5 - pixelSize.x, 0.5, dt.x)) * (1.0 - smoothstep(0.5 - pixelSize.y, 0.5, dt.y)));\n"
" gl_FragColor = min(blend, vec4(1.0)) * focusColor;\n"
" highp vec4 blend = mix(vec4(0.0), result * tex.a, (1.0 - smoothstep(0.5 - pixelSize.x, 0.5, dt.x)) * (1.0 - smoothstep(0.5 - pixelSize.y, 0.5, dt.y)));\n"
" gl_FragColor = mix(min(blend, vec4(1.0)) * focusColor, tex, focusColor);\n"
"}\n";

fsrc.replace("NUM_LIGHTS", QByteArray::number(map.maxLights()));
Expand Down Expand Up @@ -218,7 +220,7 @@ uint SurfaceItem::textureId() const
if (m_textureSize != image.size()) {
if (!m_textureSize.isNull())
glDeleteTextures(1, &m_textureId);
const_cast<SurfaceItem *>(this)->m_textureId = generateTexture(image, true);
const_cast<SurfaceItem *>(this)->m_textureId = generateTexture(image, true, false);
const_cast<SurfaceItem *>(this)->m_textureSize = image.size();
} else if (!m_dirty.isNull()) {
updateSubImage(m_textureId, image, m_dirty, true);
Expand All @@ -227,7 +229,7 @@ uint SurfaceItem::textureId() const
id = m_textureId;
}

if (m_mipmap) {
if (m_mipmap && canUseMipmaps(m_textureSize)) {
glBindTexture(GL_TEXTURE_2D, id);
ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Expand Down
67 changes: 31 additions & 36 deletions view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@

static void frameRendered()
{
if (!fpsDebug())
return;

static int frameCount = 0;
static QTime lastTime = QTime::currentTime();

Expand All @@ -70,8 +73,8 @@ QSurfaceFormat createFormat()
{
QSurfaceFormat format;
format.setSamples(4);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setDepthBufferSize(16);
format.setStencilBufferSize(1);
return format;
}

Expand Down Expand Up @@ -159,18 +162,18 @@ View::View(const QRect &geometry)
"uniform highp vec3 lights[NUM_LIGHTS];\n"
"uniform highp vec3 eye;\n"
"varying mediump vec2 t;\n"
"varying float light;\n"
"varying highp float light;\n"
"void main(void)\n"
"{\n"
" vec3 tex = texture2D(texture, t).rgb;\n"
" vec3 normal = normalize(n);\n"
" float diffuseCoeff = 0.0;\n"
" lowp vec3 tex = texture2D(texture, t).rgb;\n"
" highp vec3 normal = normalize(n);\n"
" highp float diffuseCoeff = 0.0;\n"
" for (int i = 0; i < NUM_LIGHTS; ++i) {\n"
" vec3 toLight = lights[i] - p;\n"
" float toLightSqr = dot(toLight, toLight);\n"
" float lightDistanceInv = 1.0 / sqrt(toLightSqr);\n"
" vec3 toLightN = toLight * lightDistanceInv;\n"
" float normalDotLight = dot(toLightN, normal);\n"
" highp vec3 toLight = lights[i] - p;\n"
" highp float toLightSqr = dot(toLight, toLight);\n"
" highp float lightDistanceInv = 1.0 / sqrt(toLightSqr);\n"
" highp vec3 toLightN = toLight * lightDistanceInv;\n"
" highp float normalDotLight = dot(toLightN, normal);\n"
" if (i < numLights)\n"
" diffuseCoeff += max(normalDotLight, 0.0) / max(1.5, toLightSqr);\n"
" }\n"
Expand All @@ -184,23 +187,23 @@ View::View(const QRect &geometry)
"uniform highp vec3 lights[NUM_LIGHTS];\n"
"uniform highp vec3 eye;\n"
"varying mediump vec2 t;\n"
"varying float light;\n"
"varying highp float light;\n"
"void main(void)\n"
"{\n"
" vec3 tex = texture2D(texture, t).rgb;\n"
" vec3 normal = normalize(n);\n"
" vec3 viewN = normalize(p - eye);\n"
" float specularFactor = pow(2.0, 10.0 * tex.r);\n"
" float specular = 0.0;\n"
" float diffuseCoeff = 0.0;\n"
" lowp vec3 tex = texture2D(texture, t).rgb;\n"
" highp vec3 normal = normalize(n);\n"
" highp vec3 viewN = normalize(p - eye);\n"
" highp float specularFactor = pow(2.0, 10.0 * tex.r);\n"
" highp float specular = 0.0;\n"
" highp float diffuseCoeff = 0.0;\n"
" for (int i = 0; i < NUM_LIGHTS; ++i) {\n"
" vec3 toLight = lights[i] - p;\n"
" float toLightSqr = dot(toLight, toLight);\n"
" float lightDistanceInv = 1.0 / sqrt(toLightSqr);\n"
" vec3 toLightN = toLight * lightDistanceInv;\n"
" float normalDotLight = dot(toLightN, normal);\n"
" float reflectionDotView = max(0.0, dot(reflect(toLightN, normal), viewN));\n"
" float lightScale = min(1.0, lightDistanceInv);\n"
" highp vec3 toLight = lights[i] - p;\n"
" highp float toLightSqr = dot(toLight, toLight);\n"
" highp float lightDistanceInv = 1.0 / sqrt(toLightSqr);\n"
" highp vec3 toLightN = toLight * lightDistanceInv;\n"
" highp float normalDotLight = dot(toLightN, normal);\n"
" highp float reflectionDotView = max(0.0, dot(reflect(toLightN, normal), viewN));\n"
" highp float lightScale = min(1.0, lightDistanceInv);\n"
" if (i < numLights) {\n"
" diffuseCoeff += max(normalDotLight, 0.0) / max(1.5, toLightSqr);\n"
" specular += pow(reflectionDotView, specularFactor) * lightScale;\n"
Expand Down Expand Up @@ -1121,7 +1124,6 @@ void View::handleTouchBegin(QTouchEvent *event)
if (m_fullscreen) {
QPointF relative(primaryPos.x() * m_focus->surface()->size().width() / qreal(width()), primaryPos.y() * m_focus->surface()->size().height() / qreal(height()));
m_input->sendMousePressEvent(Qt::LeftButton, relative);
qDebug() << "sending mouse press event" << relative;
return;
}

Expand All @@ -1140,7 +1142,6 @@ void View::handleTouchBegin(QTouchEvent *event)
m_mousePos = primaryPos;
m_dragItemDelta = QPoint();
m_dragAccepted = false;
printf("acquired drag item: %d, %d\n", m_mousePos.x(), m_mousePos.y());
m_animationTimer->start();
return;
}
Expand Down Expand Up @@ -1224,6 +1225,7 @@ void View::handleCamera(QTouchEvent *event)
int touchCount = points.size();
for (int i = 0; i < touchCount; ++i) {
int id = points.at(i).id();

QPoint pos = points.at(i).pos().toPoint();
Qt::TouchPointState state = points.at(i).state();
if (state == Qt::TouchPointPressed) {
Expand Down Expand Up @@ -1334,7 +1336,6 @@ void View::handleTouchEnd(QTouchEvent *event)

if (m_dragItem) {
updateDrag(primaryPos);
printf("releasing drag item\n");
m_dragItem = 0;
m_focus = 0;
return;
Expand Down Expand Up @@ -1366,12 +1367,11 @@ void View::handleTouchEnd(QTouchEvent *event)
if (m_focusTimer->isActive()) {
startFocus();
m_fullscreenTimer->start();
} else if (m_focus && m_fullscreenTimer->isActive()) {
} else if (0 && m_focus && m_fullscreenTimer->isActive()) {
m_fullscreen = true;
m_animationTimer->setSingleShot(true);
m_animationTimer->start();
} else {
printf("sending mouse release event: %d %d\n", m_mousePos.x(), m_mousePos.y());
m_input->sendMouseReleaseEvent(Qt::LeftButton, m_mousePos);
}
}
Expand Down Expand Up @@ -1414,7 +1414,6 @@ void View::handleTouchUpdate(QTouchEvent *event)
return;
}

printf("sending mouse move event: %d %d\n", local.toPoint().x(), local.toPoint().y());
m_input->sendMouseMoveEvent(local.toPoint());
}

Expand All @@ -1431,8 +1430,6 @@ void View::keyPressEvent(QKeyEvent *event)
m_simulationTime = m_time.elapsed();
m_animationTimer->setSingleShot(false);
m_animationTimer->start();

printf("starting animation timer\n");
}
}
}
Expand All @@ -1446,10 +1443,8 @@ void View::keyReleaseEvent(QKeyEvent *event)

bool active = !qFuzzyIsNull(m_strafingVelocity) || !qFuzzyIsNull(m_walkingVelocity) || !qFuzzyIsNull(m_pitchSpeed) || !qFuzzyIsNull(m_turningSpeed) || m_jumping || m_mouseLook || m_dragItem || m_camera.pos().y() > 0;

if (!m_animationTimer->isSingleShot() && !active) {
if (!m_animationTimer->isSingleShot() && !active)
m_animationTimer->setSingleShot(true);
printf("stopping animation timer\n");
}
}
}

Expand Down

0 comments on commit 35c74c9

Please sign in to comment.