mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-04 17:29:11 +00:00
WATCHMAKER: Implement "blitting" by keeping track of blits to the back buffer
This commit is contained in:
parent
babafef502
commit
4457ede6f9
@ -156,6 +156,92 @@ bool gClipToBlitterViewport(int *sposx, int *sposy, int *sdimx, int *sdimy,
|
||||
return true;
|
||||
}
|
||||
|
||||
void enter2Dmode(WGame &game) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
checkGlError("Exiting enter2Dmode");
|
||||
}
|
||||
|
||||
void exit2Dmode() {
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGlError("exit2Dmode");
|
||||
}
|
||||
|
||||
void renderTexture(WGame &game, gTexture &bitmap, Rect srcRect, Rect dstRect) {
|
||||
checkGlError("Entering renderTexture");
|
||||
glClearColor(0,0,1,0);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
bitmap.texture->bind();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, 0.0);
|
||||
|
||||
float bottomSrc = ((float)srcRect.bottom) / bitmap.RealDimY;
|
||||
float topSrc = ((float)srcRect.top) / bitmap.RealDimY;
|
||||
float leftSrc = ((float)srcRect.left) / bitmap.RealDimX;
|
||||
float rightSrc = ((float)srcRect.right) / bitmap.RealDimX;
|
||||
|
||||
Rect viewport = game._renderer->_viewport;
|
||||
float bottomDst = 1.0 - ((dstRect.bottom == 0 ? 0 : ((double)dstRect.bottom) / viewport.height()) * 2.0);
|
||||
float topDst = 1.0 - ((dstRect.top == 0 ? 0 : ((double)dstRect.top) / viewport.height()) * 2.0);
|
||||
float leftDst = ((dstRect.left == 0 ? 0 : ((double)dstRect.left) / viewport.width()) * 2.0) - 1.0;
|
||||
float rightDst = ((dstRect.right == 0 ? 0 : ((double)dstRect.right) / viewport.width()) * 2.0) - 1.0;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glTexCoord2f(leftSrc, bottomSrc); // Bottom Left
|
||||
glVertex3f(leftDst, bottomDst, 0.0f);
|
||||
|
||||
glTexCoord2f(rightSrc, bottomSrc); // Bottom Right
|
||||
glVertex3f(rightDst, bottomDst, 0.0f);
|
||||
|
||||
glTexCoord2f(rightSrc, topSrc); // Top Right
|
||||
glVertex3f(rightDst, topDst, 0.0f);
|
||||
|
||||
glTexCoord2f(leftSrc, topSrc); // Top Left
|
||||
glVertex3f(leftDst, topDst, 0.0f);
|
||||
|
||||
glEnd();
|
||||
glFlush();
|
||||
checkGlError("Exiting renderTexture");
|
||||
}
|
||||
|
||||
void gTexture::render(WGame &game, Rect src, Rect dst) {
|
||||
// Render self
|
||||
if (texture) {
|
||||
renderTexture(game, *this, src, dst);
|
||||
}
|
||||
for (int i = 0; i < _blitsOnTop.size(); i++) {
|
||||
_blitsOnTop[i].texture->render(game, _blitsOnTop[i].src, _blitsOnTop[i].dst);
|
||||
}
|
||||
}
|
||||
|
||||
void rBlitScreenBuffer(WGame &game) { // Should probably go to opengl_2d
|
||||
checkGlError("Entering rBlitScreenBuffer");
|
||||
enter2Dmode(game);
|
||||
gBitmapList[BACK_BUFFER].render(game, game._renderer->_viewport, game._renderer->_viewport);
|
||||
exit2Dmode();
|
||||
checkGlError("Exiting rBlitScreenBuffer");
|
||||
}
|
||||
|
||||
void rClear(int dst, int dposx, int dposy, int sdimx, int sdimy, unsigned char r, unsigned char g, unsigned char b) {
|
||||
warning("STUBBED: rClear(%d, %d, %d, %d, %d", dst, dposx, dposy, sdimx, sdimy);
|
||||
gBitmapList[dst].clear();
|
||||
}
|
||||
|
||||
//************************************************************************************************************************
|
||||
void rBlitter(WGame &game, int dst, int src, int dposx, int dposy,
|
||||
int sposx, int sposy, int sdimx, int sdimy) {
|
||||
@ -163,6 +249,9 @@ void rBlitter(WGame &game, int dst, int src, int dposx, int dposy,
|
||||
warning("TODO: Stubbed rBlitter(%s, %d, %d, %d, %d, %d, %d, %d, %d)", gBitmapList[src].name.c_str(), dst, src, dposx, dposy, sposx, sposy, sdimx, sdimy);
|
||||
auto &bitmap = gBitmapList[src];
|
||||
|
||||
assert(dst == 0);
|
||||
auto &dstBitmap = gBitmapList[dst];
|
||||
|
||||
checkGlError("rBlitter Start");
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
@ -179,38 +268,19 @@ void rBlitter(WGame &game, int dst, int src, int dposx, int dposy,
|
||||
}
|
||||
|
||||
if ((dposx >= dwWidth) || (dposy >= dwHeight) || (sposx >= dwWidth) || (sposy >= dwHeight) ||
|
||||
((dposx + sdimx) <= 0) || ((dposy + sdimy) <= 0) || ((sposx + sdimx) <= 0) || ((sposy + sdimy) <= 0))
|
||||
((dposx + sdimx) <= 0) || ((dposy + sdimy) <= 0) || ((sposx + sdimx) <= 0) || ((sposy + sdimy) <= 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst == 0) {
|
||||
#if 0
|
||||
if (!gClipToBlitterViewport(&sposx, &sposy, &sdimx, &sdimy, &dposx, &dposy)) {
|
||||
// DebugLogFile("gClipToBlitterViewport report an error");
|
||||
error("gClipToBlitterViewport report an error");
|
||||
return;
|
||||
}
|
||||
d = gScreenBuffer.lpDDSurface;
|
||||
#endif
|
||||
rUpdateExtends(dposx, dposy, dposx + sdimx, dposy + sdimy);
|
||||
#if 0
|
||||
/* //Update extends
|
||||
if (dposx<gBlitterExtends.left)
|
||||
gBlitterExtends.left=dposx;
|
||||
if (dposy<gBlitterExtends.top)
|
||||
gBlitterExtends.top=dposy;
|
||||
if ((dposx+sdimx)>gBlitterExtends.right)
|
||||
gBlitterExtends.right=dposx+sdimx;
|
||||
if ((dposy+sdimy)>gBlitterExtends.bottom)
|
||||
gBlitterExtends.bottom=dposy+sdimy;*/
|
||||
} else
|
||||
d = gBitmapList[dst].lpDDSurface;
|
||||
|
||||
if (src == 0) {
|
||||
DebugLogFile("rBlitter error: src is an invalid surface");
|
||||
return;
|
||||
} else
|
||||
s = gBitmapList[src].lpDDSurface;
|
||||
#endif
|
||||
rUpdateExtends(dposx, dposy, dposx + sdimx, dposy + sdimy);
|
||||
}
|
||||
|
||||
if ((sdimx == 0) && (sdimy == 0)) {
|
||||
sdimx = gBitmapList[src].DimX;
|
||||
sdimy = gBitmapList[src].DimY;
|
||||
@ -237,47 +307,7 @@ void rBlitter(WGame &game, int dst, int src, int dposx, int dposy,
|
||||
// DebugLogWindow("gBlitter: blit not needed: dimx:%d dimy:%d", ( sr.top-sr.bottom ),( sr.left-sr.right ));
|
||||
return;
|
||||
}
|
||||
glClearColor(0,0,1,0);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
bitmap.texture->bind();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, -1.0);
|
||||
//glTranslatef((2.0 / dposx) - 1.0, (2.0 / dposy) - 1.0, 0.0f);
|
||||
|
||||
//glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
|
||||
float bottomSrc = ((float)srcRect.bottom) / bitmap.RealDimY;
|
||||
float topSrc = ((float)srcRect.top) / bitmap.RealDimY;
|
||||
float leftSrc = ((float)srcRect.left) / bitmap.RealDimX;
|
||||
float rightSrc = ((float)srcRect.right) / bitmap.RealDimX;
|
||||
|
||||
Rect viewport = game._renderer->_viewport;
|
||||
float bottomDst = 1.0 - ((dstRect.bottom == 0 ? 0 : ((double)dstRect.bottom) / viewport.height()) * 2.0);
|
||||
float topDst = 1.0 - ((dstRect.top == 0 ? 0 : ((double)dstRect.top) / viewport.height()) * 2.0);
|
||||
float leftDst = ((dstRect.left == 0 ? 0 : ((double)dstRect.left) / viewport.width()) * 2.0) - 1.0;
|
||||
float rightDst = ((dstRect.right == 0 ? 0 : ((double)dstRect.right) / viewport.width()) * 2.0) - 1.0;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
glTexCoord2f(leftSrc, bottomSrc); // Bottom Left
|
||||
glVertex3f(leftDst, bottomDst, 0.0f);
|
||||
|
||||
glTexCoord2f(rightSrc, bottomSrc); // Bottom Right
|
||||
glVertex3f(rightDst, bottomDst, 0.0f);
|
||||
|
||||
glTexCoord2f(rightSrc, topSrc); // Top Right
|
||||
glVertex3f(rightDst, topDst, 0.0f);
|
||||
|
||||
glTexCoord2f(leftSrc, topSrc); // Top Left
|
||||
glVertex3f(leftDst, topDst, 0.0f);
|
||||
|
||||
glEnd();
|
||||
glFlush();
|
||||
dstBitmap.blitInto(&bitmap, srcRect, dstRect);
|
||||
}
|
||||
checkGlError("rBlitter End");
|
||||
|
||||
|
@ -601,10 +601,12 @@ public:
|
||||
checkGlError("glCompressedTexImage");
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texFormat, data.getWidth(), data.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.getData());
|
||||
checkGlError("glTexImage2D");
|
||||
}
|
||||
}
|
||||
void bind() override {
|
||||
glBindTexture(GL_TEXTURE_2D, _texId);
|
||||
checkGlError("OpenGLTexture::bind");
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -22,14 +22,17 @@
|
||||
#ifndef WATCHMAKER_TEXTURE_H
|
||||
#define WATCHMAKER_TEXTURE_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "watchmaker/3d/dds_header.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "watchmaker/rect.h"
|
||||
#include "watchmaker/surface.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
class WGame;
|
||||
// Texture structs
|
||||
struct gTexture {
|
||||
Common::String name;
|
||||
@ -45,8 +48,21 @@ struct gTexture {
|
||||
return texture == nullptr;
|
||||
}
|
||||
void clear() {
|
||||
error("TODO: Clear texture");
|
||||
// TODO: This will only work for the back-surface
|
||||
warning("Clearing %d", _blitsOnTop.size());
|
||||
_blitsOnTop.clear();
|
||||
}
|
||||
void render(WGame &game, Rect src, Rect dst);
|
||||
void blitInto(gTexture *texture, Rect src, Rect dst) {
|
||||
_blitsOnTop.push_back({texture, src, dst});
|
||||
}
|
||||
private:
|
||||
struct Blit {
|
||||
gTexture *texture;
|
||||
Rect src;
|
||||
Rect dst;
|
||||
};
|
||||
Common::Array<Blit> _blitsOnTop;
|
||||
};
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
@ -223,7 +223,7 @@ void Regen(WGame &game) {
|
||||
// DebugLogWindow( "Aggiorna video %d,%d %d,%d", ext.x1, ext.y1, ext.x2-ext.x1, ext.y2-ext.y1 );
|
||||
#endif
|
||||
rUpdateExtends(ext.x1, ext.y1, ext.x2, ext.y2);
|
||||
rBlitScreenBuffer();
|
||||
rBlitScreenBuffer(game);
|
||||
rResetExtends();
|
||||
|
||||
// 5 - Copy PaintRect to OldPaintRect
|
||||
|
@ -90,6 +90,7 @@ bool checkGlError(const char *when) {
|
||||
}
|
||||
|
||||
bool rClearBuffers(char flags) {
|
||||
checkGlError("Entering rClearBuffers");
|
||||
bool clearStencil = rGetStencilBitDepth() != 0;
|
||||
bool clearDepth = flags & rCLEARZBUFFER;
|
||||
bool clearBack = flags & rCLEARBACKBUFFER;
|
||||
@ -144,12 +145,12 @@ void rGetScreenInfos(unsigned int *width, unsigned int *height, unsigned int *bp
|
||||
}
|
||||
|
||||
gTexture *gLoadTexture(char *TextName, unsigned int LoaderFlags) {
|
||||
warning("STUBBED gLoadTexture");
|
||||
error("STUBBED gLoadTexture");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool rGrabVideo(const char *path, char flags) {
|
||||
warning("STUBBED: rGrabVideo");
|
||||
error("STUBBED: rGrabVideo");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ void rReleaseAllBitmaps(unsigned int NotFlags) {
|
||||
}
|
||||
|
||||
void rReleaseBitmap(int i) {
|
||||
warning("STUBBED: rReleaseBitmap");
|
||||
error("STUBBED: rReleaseBitmap");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -169,35 +170,26 @@ void rReleaseAllTextures(unsigned int NotFlags) {
|
||||
}
|
||||
|
||||
void rSetBitmapName(unsigned int id, const char *s) {
|
||||
warning("STUBBED: rSetBitmapName");
|
||||
error("STUBBED: rSetBitmapName");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 rGetMovieFrame(MaterialPtr mat) {
|
||||
warning("STUBBED: rGetMovieFrame");
|
||||
error("STUBBED: rGetMovieFrame");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void rPrintText(const char *s, unsigned int dst, unsigned int src, unsigned short *FontTable, unsigned short x, unsigned short y) {
|
||||
warning("STUBBED: rPrintText");
|
||||
error("STUBBED: rPrintText");
|
||||
return;
|
||||
}
|
||||
|
||||
void rGetTextDim(const char *s, unsigned short *FontTable, int *x, int *y) {
|
||||
warning("STUBBED: rGetTextDim");
|
||||
error("STUBBED: rGetTextDim");
|
||||
return;
|
||||
}
|
||||
|
||||
void rClear(int dst, int dposx, int dposy, int sdimx, int sdimy, unsigned char r, unsigned char g, unsigned char b) {
|
||||
//warning("STUBBED: rClear(%d, %d, %d, %d, %d", dst, dposx, dposy, sdimx, sdimy);
|
||||
}
|
||||
|
||||
|
||||
void rBlitScreenBuffer(void) { // Should probably go to opengl_2d
|
||||
//warning("STUBBED: rBlitScreenBuffer");
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // USE_OPENGL_GAME
|
||||
|
@ -211,7 +211,7 @@ int DebugQuick(signed int StdPx, signed int StdPy, const cha
|
||||
bool rGetStencilBitDepth();
|
||||
|
||||
//Misc functions
|
||||
void rBlitScreenBuffer();
|
||||
void rBlitScreenBuffer(WGame &game);
|
||||
void rPrintText(const char *s, unsigned int dst, unsigned int src, unsigned short *FontTable, unsigned short x, unsigned short y);
|
||||
void rBlitter(WGame &game, int dst, int src, int dposx, int dposy, int sposx, int sposy, int sdimx, int sdimy);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user