diff options
Diffstat (limited to 'src/openglgraphics.cpp')
-rw-r--r-- | src/openglgraphics.cpp | 118 |
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) |