diff options
author | Travis Howell | 2003-06-30 02:38:56 +0000 |
---|---|---|
committer | Travis Howell | 2003-06-30 02:38:56 +0000 |
commit | 7c8565fa65789576959e67d54e4032780dffc723 (patch) | |
tree | 10cbe5b687ae599217664b64b2939fa3fefe557a | |
parent | 4d5592cc5d9ea0f3bb3df36c1e5cf77055d4cdf8 (diff) | |
download | scummvm-rg350-7c8565fa65789576959e67d54e4032780dffc723.tar.gz scummvm-rg350-7c8565fa65789576959e67d54e4032780dffc723.tar.bz2 scummvm-rg350-7c8565fa65789576959e67d54e4032780dffc723.zip |
Add OpenGL fixes, patch #762815
svn-id: r8672
-rw-r--r-- | backends/sdl/fb2opengl.h | 85 | ||||
-rw-r--r-- | backends/sdl/sdl_gl.cpp | 78 |
2 files changed, 109 insertions, 54 deletions
diff --git a/backends/sdl/fb2opengl.h b/backends/sdl/fb2opengl.h index 51bfd47490..690773dd8b 100644 --- a/backends/sdl/fb2opengl.h +++ b/backends/sdl/fb2opengl.h @@ -96,11 +96,19 @@ class FB2GL { void FB2GL::setBilinearMode(bool bilinear) { const GLuint mode = bilinear ? GL_LINEAR : GL_NEAREST; glBindTexture(GL_TEXTURE_2D, texture1); + // No borders + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // Bilinear filter glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode); if (flags & FB2GL_NO_320) { glBindTexture(GL_TEXTURE_2D, texture2); + // No borders + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // Bilinear filter glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode); } @@ -110,6 +118,7 @@ void FB2GL::makeTextures() { glGenTextures(0,&texture1); glBindTexture(GL_TEXTURE_2D,texture1); + // No borders glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); @@ -151,14 +160,23 @@ void FB2GL::makeTextures() { void FB2GL::makeDisplayList(int xf, int yf) { - float xfix = xf / 128.0f; // 128 = 256/2 (half texture => 0.0 to 1.0) - float yfix = yf / 128.0f; - float texend; // End of 256x256 (from -1.0 to 1.0) - - if (flags & FB2GL_NO_320) - texend = 96.0f / 160.0f; // 160=320/2 (== 0.0), 256-160=96. - else - texend = 1.0f; + GLfloat xfix = xf / 128.0f; // 128 = 256/2 (half texture => 0.0 to 1.0) + GLfloat yfix = yf / 128.0f; + GLfloat texture1_end; // End of 256x256 texture (from -1.0 to 1.0) + + if (flags & FB2GL_NO_320) { + // Game screen width = 320 + // GL coordinates (-1.0 <= x <= 1.0, -1.0 <= y <= 1.0) + // X axis center: GL => 0.0, Game => 320/2 = 160 + // GL texture1 width = 256 (texture2 width = 64. 256 + 64 = 320) + // 160 = 320/2 (half width). 256 - 160 = 96 + texture1_end = 96.0f / 160.0f; // between 0.0 (center) and 1.0 + // Note: wrong value may cause black vertical line (gap + // between texture1 and texture2 in the X axis) + } + else { + texture1_end = 1.0f; + } if (glIsList(displayList)) glDeleteLists(displayList, 1); @@ -171,28 +189,28 @@ void FB2GL::makeDisplayList(int xf, int yf) { glBindTexture(GL_TEXTURE_2D, texture1); glBegin(GL_QUADS); - // upper left - glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f - yfix); // lower left + glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f - yfix); + // upper left glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, 1.0f); - // lower right - glTexCoord2f(1.0f, 0.0f); glVertex2f(texend + xfix, 1.0f); // upper right - glTexCoord2f(1.0f, 1.0f); glVertex2f(texend + xfix, -1.0f - yfix); + glTexCoord2f(1.0f, 0.0f); glVertex2f(texture1_end + xfix, 1.0f); + // lower right + glTexCoord2f(1.0f, 1.0f); glVertex2f(texture1_end + xfix, -1.0f - yfix); glEnd(); if (flags & FB2GL_NO_320) { - // 64x256 + // 64x256 (texture2) glBindTexture(GL_TEXTURE_2D, texture2); glBegin(GL_QUADS); - // upper left - glTexCoord2f(0.0f, 1.0f); glVertex2f(texend + xfix, -1.0f - yfix); // lower left - glTexCoord2f(0.0f, 0.0f); glVertex2f(texend + xfix, 1.0f); - // lower right - glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f + xfix, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex2f(texture1_end + xfix, -1.0f - yfix); + // upper left + glTexCoord2f(0.0f, 0.0f); glVertex2f(texture1_end + xfix, 1.0f); // upper right + glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f + xfix, 1.0f); + // lower right glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f + xfix, -1.0f - yfix); glEnd(); } @@ -252,14 +270,14 @@ void FB2GL::display() void FB2GL::update(void *fb, int w, int h, int pitch, int xskip, int yskip) { unsigned char *tempFrameBuffer = (unsigned char *)fb; - int x, y, scr_pitch, byte; + int x, y, scr_pitch, _byte; if (flags & FB2GL_PITCH) { scr_pitch = pitch; - byte = 0; + _byte = 0; } else { scr_pitch = w * pitch; - byte = pitch; // Bytes perl pixel (for RGBA mode) + _byte = pitch; // Bytes perl pixel (for RGBA mode) } if (flags & FB2GL_RGBA) { @@ -291,17 +309,17 @@ void FB2GL::update(void *fb, int w, int h, int pitch, int xskip, int yskip) { for (y = yskip; y < h; y++) { for (x = xskip; x < w; x++) { if (!(flags & FB2GL_NO_320)) { - RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*byte)); - RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*byte)+1); - RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*byte)+2); + RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*_byte)); + RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1); + RGBAFrameBuffer1[(y-yskip)*320*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2); } else if (x < 256) { - RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*byte)); - RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*byte)+1); - RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*byte)+2); + RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 0] = *(tempFrameBuffer+(x*_byte)); + RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1); + RGBAFrameBuffer1[(y-yskip)*256*4 + (x-xskip)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2); } else { - RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 0] = *(tempFrameBuffer+(x*byte)); - RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 1] = *(tempFrameBuffer+(x*byte)+1); - RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 2] = *(tempFrameBuffer+(x*byte)+2); + RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 0] = *(tempFrameBuffer+(x*_byte)); + RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 1] = *(tempFrameBuffer+(x*_byte)+1); + RGBAFrameBuffer2[(y-yskip)*64*4 + (x-256)*4 + 2] = *(tempFrameBuffer+(x*_byte)+2); } } tempFrameBuffer += scr_pitch; // Next row (like y++) @@ -412,7 +430,7 @@ void FB2GL::blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rect, int xskip, int for (y = ry; y < yend; y++) { for (x = rx; x < xend; x++) { - if (x < 256 && tex1_w) { + if (tex1_w && x < 256) { int pos = (x-rx+(y-ry)*tex1_w)*4; // (x + (y*pitch)) * RGBAsize SDL_GetRGB( ((Uint16 *)fb->pixels)[x+y*(pitch)], @@ -421,7 +439,7 @@ void FB2GL::blit16(SDL_Surface *fb, int num_rect, SDL_Rect *rect, int xskip, int &RGBAFrameBuffer1[pos+1], &RGBAFrameBuffer1[pos+2] ); - } else if (x >= 256 && tex2_w) { + } else if (tex2_w && x >= 256) { int rx2 = rx < 256? 256: rx; int pos = (x-rx2+(y-ry)*tex2_w)*4; // (x + (y*pitch)) * RGBAsize SDL_GetRGB( @@ -500,5 +518,4 @@ void FB2GL::setPalette(int first, int n) { } } - } diff --git a/backends/sdl/sdl_gl.cpp b/backends/sdl/sdl_gl.cpp index 1652046190..22fb1f10f2 100644 --- a/backends/sdl/sdl_gl.cpp +++ b/backends/sdl/sdl_gl.cpp @@ -56,9 +56,10 @@ protected: bool _glBilinearFilter; bool _usingOpenGL; SDL_Surface *tmpSurface; // Used for black rectangles blitting - SDL_Rect tmpBlackRect; // Black rectangle at end of the GL screen + SDL_Rect tmpBlackRect; // Bottom black border SDL_Rect _glWindow; // Only uses w and h (for window resizing) int _glBottomOfTexture; + int _glBorderHeight; // Used if using black borders SDL_Surface *_hwscreen; // hardware screen (=> _usingOpenGL == false) @@ -77,9 +78,10 @@ OSystem_SDL_OpenGL::OSystem_SDL_OpenGL() : _hwscreen(0), _scaler_proc(0) { _glScreenStart = 0; - _glBilinearFilter = true; + _glBilinearFilter = false; _usingOpenGL = false; // false => Switch to filters used in the sdl.cpp version _glBottomOfTexture = 256; // height is always 256 + _glBorderHeight = 0; // Forces _glScreenStart to always be 0 // 640x480 resolution _glWindow.w = 640; _glWindow.h = 480; @@ -167,7 +169,7 @@ void OSystem_SDL_OpenGL::load_gfx_mode() { case GFX_NORMAL: normal_mode:; - _scaleFactor = _usingOpenGL ? 2 : 1; + _scaleFactor = 1; //_usingOpenGL ? 2 : 1; _scaler_proc = Normal1x; break; default: @@ -177,9 +179,10 @@ normal_mode:; _scaler_proc = Normal1x; } - if (_mode != GFX_NORMAL) + if (_mode != GFX_NORMAL) { _usingOpenGL = false; - + } + // // Create the surface that contains the 8 bit game data // @@ -197,9 +200,21 @@ normal_mode:; _glFlags |= FB2GL_FS; _glScreenStart = 0; } + + // Note: Our GL screen is vertically stretched (yfix = 15). + // That makes visible only 320x240 of the GL screen. + // 320x240 visible in GL screen => yfix = 15 + // 320x200 visible in GL screen => yfix = 72 + int yfix = 15; + _glBorderHeight = 0; + if (_screenHeight == 200) { + // If we are not using borders, we want 320x200 visible + yfix = _glScreenStart? 15: 72; + // 20 (top) + 200 (height) + 20 (bottom) = 240 + _glBorderHeight = 20; + } // _glWindow defines the resolution - fb2gl.init(_glWindow.w, _glWindow.h, 0, _glScreenStart? 15: 70, - _glFlags); + fb2gl.init(_glWindow.w, _glWindow.h, 0, yfix, _glFlags); } else { // SDL backend @@ -337,9 +352,10 @@ void OSystem_SDL_OpenGL::update_screen() { // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { if (_usingOpenGL) { + // Top black border SDL_Rect blackrect = { 0, - _glScreenStart, + 0, // _glScreenStart, _screenWidth, _newShakePos + _glScreenStart }; @@ -416,7 +432,7 @@ void OSystem_SDL_OpenGL::update_screen() { // Bottom black border height tmpBlackRect.h = _glBottomOfTexture - _glBottomOfGameScreen; - if (!(_full_screen) && (tmpBlackRect.h > 0)) { + if (_adjustAspectRatio && tmpBlackRect.h > 0) { SDL_FillRect(tmpSurface, &tmpBlackRect, 0); fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, _glBottomOfGameScreen); @@ -562,17 +578,36 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) { if (_adjustAspectRatio) { // Don't use the whole screen (black borders) fb2gl.init(0, 0, 0, 15, _glFlags); - _glScreenStart = 20; + _glScreenStart = _glBorderHeight; + // Top black border + SDL_Rect blackrect = { + 0, + 0, // _glScreenStart, + _screenWidth, + _newShakePos + _glScreenStart + }; + + SDL_FillRect(tmpSurface, &blackrect, 0); + fb2gl.blit16(tmpSurface, 1, &blackrect, 0, 0); + + // Bottom black border + int _glBottomOfGameScreen = _screenHeight + + _glScreenStart + _currentShakePos; + + tmpBlackRect.h = _glBottomOfTexture - + _glBottomOfGameScreen; + SDL_FillRect(tmpSurface, &tmpBlackRect, 0); - fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, 0); + fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0, + _glBottomOfGameScreen); } else { // Use the whole screen - fb2gl.init(0, 0, 0, 70, _glFlags); + fb2gl.init(0, 0, 0, 72, _glFlags); _glScreenStart = 0; } - SDL_Rect full = {0, 0, _screenWidth, _screenHeight}; - fb2gl.blit16(_tmpscreen, 1, &full, 0, _glScreenStart); + SDL_Rect redraw = {0, 0, _screenWidth, _screenHeight}; + fb2gl.blit16(_tmpscreen, 1, &redraw, 0, _glScreenStart); fb2gl.display(); } else { if (_screenHeight == 200) { @@ -587,6 +622,8 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) { if (!_usingOpenGL) { _usingOpenGL = true; _mode = GFX_NORMAL; + _scaleFactor = 1; + _scaler_proc = Normal1x; hotswap_gfx_mode(); } } @@ -602,21 +639,22 @@ uint32 OSystem_SDL_OpenGL::property(int param, Property *value) { _mode = value->gfx_mode; - if (_usingOpenGL) + if (_usingOpenGL) { + _glBilinearFilter = false; _usingOpenGL = false; + } hotswap_gfx_mode(); }; - if (_usingOpenGL) { - SDL_Rect full = {0, 0, _screenWidth, _screenHeight}; - fb2gl.blit16(_tmpscreen, 1, &full, 0, _glScreenStart); +/* if (_usingOpenGL) { + SDL_Rect redraw = {0, 0, _screenWidth, _screenHeight}; + fb2gl.blit16(_tmpscreen, 1, &redraw, 0, _glScreenStart); fb2gl.display(); - } + }*/ return 1; } return OSystem_SDL_Common::property(param, value); } - |