summaryrefslogtreecommitdiff
path: root/src/openglgraphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openglgraphics.cpp')
-rw-r--r--src/openglgraphics.cpp118
1 files changed, 60 insertions, 58 deletions
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index 74a309e1..28fd47f6 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -33,6 +33,8 @@
#include <SDL.h>
+#include <cmath>
+
#ifndef GL_TEXTURE_RECTANGLE_ARB
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
@@ -44,7 +46,8 @@ GLuint OpenGLGraphics::mLastImage = 0;
OpenGLGraphics::OpenGLGraphics():
mAlpha(false), mTexture(false), mColorAlpha(false),
- mSync(false)
+ mSync(false),
+ mReduceInputLag(true)
{
mFloatTexArray = new GLfloat[vertexBufSize * 4];
mIntTexArray = new GLint[vertexBufSize * 4];
@@ -63,6 +66,11 @@ void OpenGLGraphics::setSync(bool sync)
mSync = sync;
}
+void OpenGLGraphics::setReduceInputLag(bool reduceInputLag)
+{
+ mReduceInputLag = reduceInputLag;
+}
+
bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
{
logger->log("Setting video mode %dx%d %s",
@@ -70,8 +78,19 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
- mWidth = w;
- mHeight = h;
+ const double targetRatio = (double) 640 / 360; // 1.77778
+ const double requestedRatio = (double) w / h;
+
+ if (requestedRatio < targetRatio) {
+ // Screen is higher / narrower than target aspect ratio: calculate
+ // scale based on height.
+ mScale = (int) std::floor((double) h / 360);
+ } else {
+ mScale = (int) std::floor((double) w / 640);
+ }
+
+ mWidth = w / mScale;
+ mHeight = h / mScale;
mBpp = bpp;
mFullscreen = fs;
mHWAccel = hwaccel;
@@ -103,7 +122,7 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
#endif
// Setup OpenGL
- glViewport(0, 0, w, h);
+ glViewport(0, 0, mWidth * mScale, mHeight * mScale);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
int gotDoubleBuffer;
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
@@ -113,14 +132,17 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
char const *glExtensions = (char const *)glGetString(GL_EXTENSIONS);
GLint texSize;
bool rectTex = strstr(glExtensions, "GL_ARB_texture_rectangle");
- if (rectTex)
+ bool npotTex = strstr(glExtensions, "GL_ARB_texture_non_power_of_two");
+ if (rectTex && !npotTex)
{
Image::mTextureType = GL_TEXTURE_RECTANGLE_ARB;
+ Image::mPowerOfTwoTextures = false;
glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texSize);
}
else
{
Image::mTextureType = GL_TEXTURE_2D;
+ Image::mPowerOfTwoTextures = !npotTex;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
}
Image::mTextureSize = texSize;
@@ -162,8 +184,8 @@ static inline void drawQuad(Image *image,
dstX, dstY + height
};
- glVertexPointer(2, GL_FLOAT, 0, &vert);
- glTexCoordPointer(2, GL_INT, 0, &tex);
+ glVertexPointer(2, GL_INT, 0, &vert);
+ glTexCoordPointer(2, GL_FLOAT, 0, &tex);
glDrawArrays(GL_QUADS, 0, 4);
}
@@ -224,8 +246,8 @@ static inline void drawRescaledQuad(Image *image,
dstX, dstY + desiredHeight
};
- glVertexPointer(2, GL_FLOAT, 0, &vert);
- glTexCoordPointer(2, GL_INT, 0, &tex);
+ glVertexPointer(2, GL_INT, 0, &vert);
+ glTexCoordPointer(2, GL_FLOAT, 0, &tex);
glDrawArrays(GL_QUADS, 0, 4);
}
@@ -290,19 +312,6 @@ bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
int desiredWidth, int desiredHeight,
bool useColor)
{
- return drawRescaledImage(image, srcX, srcY,
- dstX, dstY,
- width, height,
- desiredWidth, desiredHeight,
- useColor, true);
-}
-
-bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
- int dstX, int dstY,
- int width, int height,
- int desiredWidth, int desiredHeight,
- bool useColor, bool smooth)
-{
if (!image)
return false;
@@ -313,11 +322,6 @@ bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
width, height, useColor);
}
- // When the desired image is smaller than the current one,
- // disable smooth effect.
- if (width > desiredWidth && height > desiredHeight)
- smooth = false;
-
srcX += image->mBounds.x;
srcY += image->mBounds.y;
@@ -332,20 +336,6 @@ bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
drawRescaledQuad(image, srcX, srcY, dstX, dstY, width, height,
desiredWidth, desiredHeight);
- if (smooth) // A basic smooth effect...
- {
- glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
- drawRescaledQuad(image, srcX, srcY, dstX - 1, dstY - 1, width, height,
- desiredWidth + 1, desiredHeight + 1);
- drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY + 1, width, height,
- desiredWidth - 1, desiredHeight - 1);
-
- drawRescaledQuad(image, srcX, srcY, dstX + 1, dstY, width, height,
- desiredWidth - 1, desiredHeight);
- drawRescaledQuad(image, srcX, srcY, dstX, dstY + 1, width, height,
- desiredWidth, desiredHeight - 1);
- }
-
if (!useColor)
{
glColor4ub(static_cast<GLubyte>(mColor.r),
@@ -633,9 +623,20 @@ void OpenGLGraphics::drawRescaledImagePattern(Image *image,
void OpenGLGraphics::updateScreen()
{
- glFlush();
- glFinish();
SDL_GL_SwapBuffers();
+
+ /*
+ * glFinish flushes all OpenGL commands and makes sure they have been
+ * executed before continuing. If we do not do this we allow the next
+ * frame to be prepared while the current one isn't even displaying yet,
+ * which can cause input lag that is especially noticable at mouse
+ * movement.
+ *
+ * The setting is optional since calling glFinish can reduce performance
+ * and increase CPU usage.
+ */
+ if (mReduceInputLag)
+ glFinish();
}
void OpenGLGraphics::_beginDraw()
@@ -646,20 +647,19 @@ void OpenGLGraphics::_beginDraw()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0.0, (double)mTarget->w, (double)mTarget->h, 0.0, -1.0, 1.0);
+ glOrtho(0.0, (double) mWidth, (double) mHeight, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_SCISSOR_TEST);
- glEnableClientState(GL_VERTEX_ARRAY);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- pushClipArea(gcn::Rectangle(0, 0, mTarget->w, mTarget->h));
+ pushClipArea(gcn::Rectangle(0, 0, mWidth, mHeight));
}
void OpenGLGraphics::_endDraw()
@@ -726,12 +726,15 @@ bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
transX += mClipStack.top().xOffset;
transY += mClipStack.top().yOffset;
+ int x = (int) (mClipStack.top().x * mScale);
+ int y = mTarget->h - (int) ((mClipStack.top().y +
+ mClipStack.top().height) * mScale);
+ int width = (int) (mClipStack.top().width * mScale);
+ int height = (int) (mClipStack.top().height * mScale);
+
glPushMatrix();
glTranslatef(transX, transY, 0);
- glScissor(mClipStack.top().x,
- mTarget->h - mClipStack.top().y - mClipStack.top().height,
- mClipStack.top().width,
- mClipStack.top().height);
+ glScissor(x, y, width, height);
return result;
}
@@ -743,11 +746,14 @@ void OpenGLGraphics::popClipArea()
if (mClipStack.empty())
return;
+ int x = (int) (mClipStack.top().x * mScale);
+ int y = mTarget->h - (int) ((mClipStack.top().y +
+ mClipStack.top().height) * mScale);
+ int width = (int) (mClipStack.top().width * mScale);
+ int height = (int) (mClipStack.top().height * mScale);
+
glPopMatrix();
- glScissor(mClipStack.top().x,
- mTarget->h - mClipStack.top().y - mClipStack.top().height,
- mClipStack.top().width,
- mClipStack.top().height);
+ glScissor(x, y, width, height);
}
void OpenGLGraphics::setColor(const gcn::Color& color)
@@ -791,10 +797,6 @@ void OpenGLGraphics::fillRectangle(const gcn::Rectangle& rect)
drawRectangle(rect, true);
}
-void OpenGLGraphics::setTargetPlane(int width, int height)
-{
-}
-
void OpenGLGraphics::setTexturingAndBlending(bool enable)
{
if (enable)