mirror of
https://github.com/aap/librw.git
synced 2024-11-28 06:35:41 +00:00
framebuffer read lock; gl raster to image
This commit is contained in:
parent
baa8666a03
commit
9260bddc66
@ -579,7 +579,7 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
|
|||||||
if(lockMode & Raster::LOCKREAD)
|
if(lockMode & Raster::LOCKREAD)
|
||||||
flags |= D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE;
|
flags |= D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE;
|
||||||
IDirect3DTexture9 *tex = (IDirect3DTexture9*)natras->texture;
|
IDirect3DTexture9 *tex = (IDirect3DTexture9*)natras->texture;
|
||||||
IDirect3DSurface9 *surf;
|
IDirect3DSurface9 *surf, *rt;
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
|
|
||||||
switch(raster->type){
|
switch(raster->type){
|
||||||
@ -592,6 +592,26 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Raster::CAMERATEXTURE:
|
||||||
|
case Raster::CAMERA: {
|
||||||
|
if(lockMode & Raster::PRIVATELOCK_WRITE)
|
||||||
|
assert(0 && "can't lock framebuffer for writing");
|
||||||
|
if(raster->type == Raster::CAMERA)
|
||||||
|
rt = d3d9Globals.defaultRenderTarget;
|
||||||
|
else
|
||||||
|
tex->GetSurfaceLevel(level, &rt);
|
||||||
|
D3DSURFACE_DESC desc;
|
||||||
|
rt->GetDesc(&desc);
|
||||||
|
HRESULT res = d3ddevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &rt, nil);
|
||||||
|
if(res != D3D_OK)
|
||||||
|
return nil;
|
||||||
|
d3ddevice->GetRenderTargetData(rt, surf);
|
||||||
|
natras->lockedSurf = surf;
|
||||||
|
res = surf->LockRect(&lr, 0, flags);
|
||||||
|
assert(res == D3D_OK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "can't lock this raster type (yet)");
|
assert(0 && "can't lock this raster type (yet)");
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ driverOpen(void *o, int32, int32)
|
|||||||
engine->driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
|
engine->driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
|
||||||
engine->driver[PLATFORM_GL3]->imageFindRasterFormat = imageFindRasterFormat;
|
engine->driver[PLATFORM_GL3]->imageFindRasterFormat = imageFindRasterFormat;
|
||||||
engine->driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
|
engine->driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
|
||||||
|
engine->driver[PLATFORM_GL3]->rasterToImage = rasterToImage;
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
@ -25,43 +25,8 @@
|
|||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace gl3 {
|
namespace gl3 {
|
||||||
struct DisplayMode
|
|
||||||
{
|
|
||||||
#ifdef LIBRW_SDL2
|
|
||||||
SDL_DisplayMode mode;
|
|
||||||
#else
|
|
||||||
GLFWvidmode mode;
|
|
||||||
#endif
|
|
||||||
int32 depth;
|
|
||||||
uint32 flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GlGlobals
|
GlGlobals glGlobals;
|
||||||
{
|
|
||||||
#ifdef LIBRW_SDL2
|
|
||||||
SDL_Window **pWindow;
|
|
||||||
SDL_Window *window;
|
|
||||||
SDL_GLContext glcontext;
|
|
||||||
#else
|
|
||||||
GLFWwindow **pWindow;
|
|
||||||
GLFWwindow *window;
|
|
||||||
|
|
||||||
GLFWmonitor *monitor;
|
|
||||||
int numMonitors;
|
|
||||||
int currentMonitor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DisplayMode *modes;
|
|
||||||
int numModes;
|
|
||||||
int currentMode;
|
|
||||||
int presentWidth, presentHeight;
|
|
||||||
int presentOffX, presentOffY;
|
|
||||||
|
|
||||||
// for opening the window
|
|
||||||
int winWidth, winHeight;
|
|
||||||
const char *winTitle;
|
|
||||||
uint32 numSamples;
|
|
||||||
} glGlobals;
|
|
||||||
|
|
||||||
Gl3Caps gl3Caps;
|
Gl3Caps gl3Caps;
|
||||||
// terrible hack for GLES
|
// terrible hack for GLES
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "rwgl3.h"
|
#include "rwgl3.h"
|
||||||
#include "rwgl3shader.h"
|
#include "rwgl3shader.h"
|
||||||
|
#include "rwgl3impl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID ID_DRIVER
|
#define PLUGIN_ID ID_DRIVER
|
||||||
|
|
||||||
@ -215,6 +216,14 @@ rasterCreateCamera(Raster *raster)
|
|||||||
|
|
||||||
// TODO: set/check width, height, depth, format?
|
// TODO: set/check width, height, depth, format?
|
||||||
|
|
||||||
|
// used for locking right now
|
||||||
|
raster->format = Raster::C888;
|
||||||
|
natras->internalFormat = GL_RGB8;
|
||||||
|
natras->format = GL_RGB;
|
||||||
|
natras->type = GL_UNSIGNED_BYTE;
|
||||||
|
natras->hasAlpha = 0;
|
||||||
|
natras->bpp = 3;
|
||||||
|
|
||||||
natras->autogenMipmap = 0;
|
natras->autogenMipmap = 0;
|
||||||
|
|
||||||
natras->texid = 0;
|
natras->texid = 0;
|
||||||
@ -437,7 +446,7 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
|
|||||||
|
|
||||||
assert(raster->privateFlags == 0);
|
assert(raster->privateFlags == 0);
|
||||||
|
|
||||||
switch(raster->type & 0xF00){
|
switch(raster->type){
|
||||||
case Raster::NORMAL:
|
case Raster::NORMAL:
|
||||||
case Raster::TEXTURE:
|
case Raster::TEXTURE:
|
||||||
case Raster::CAMERATEXTURE:
|
case Raster::CAMERATEXTURE:
|
||||||
@ -489,6 +498,23 @@ assert(natras->format == GL_RGBA);
|
|||||||
raster->privateFlags = lockMode;
|
raster->privateFlags = lockMode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Raster::CAMERA:
|
||||||
|
if(lockMode & Raster::PRIVATELOCK_WRITE)
|
||||||
|
assert(0 && "can't lock framebuffer for writing");
|
||||||
|
raster->width = glGlobals.presentWidth;
|
||||||
|
raster->height = glGlobals.presentHeight;
|
||||||
|
raster->stride = raster->width*natras->bpp;
|
||||||
|
assert(natras->bpp == 3);
|
||||||
|
allocSz = raster->height*raster->stride;
|
||||||
|
px = (uint8*)rwMalloc(allocSz, MEMDUR_EVENT | ID_DRIVER);
|
||||||
|
assert(raster->pixels == nil);
|
||||||
|
raster->pixels = px;
|
||||||
|
glReadBuffer(GL_BACK);
|
||||||
|
glReadPixels(0, 0, raster->width, raster->height, GL_RGB, GL_UNSIGNED_BYTE, px);
|
||||||
|
|
||||||
|
raster->privateFlags = lockMode;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "cannot lock this type of raster yet");
|
assert(0 && "cannot lock this type of raster yet");
|
||||||
return nil;
|
return nil;
|
||||||
@ -508,27 +534,37 @@ rasterUnlock(Raster *raster, int32 level)
|
|||||||
|
|
||||||
assert(raster->pixels);
|
assert(raster->pixels);
|
||||||
|
|
||||||
if(raster->privateFlags & Raster::LOCKWRITE){
|
switch(raster->type){
|
||||||
uint32 prev = bindTexture(natras->texid);
|
case Raster::NORMAL:
|
||||||
if(natras->isCompressed){
|
case Raster::TEXTURE:
|
||||||
glCompressedTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat,
|
case Raster::CAMERATEXTURE:
|
||||||
raster->width, raster->height, 0,
|
if(raster->privateFlags & Raster::LOCKWRITE){
|
||||||
getLevelSize(raster, level),
|
uint32 prev = bindTexture(natras->texid);
|
||||||
raster->pixels);
|
if(natras->isCompressed){
|
||||||
if(natras->backingStore){
|
glCompressedTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat,
|
||||||
assert(level < natras->backingStore->numlevels);
|
raster->width, raster->height, 0,
|
||||||
memcpy(natras->backingStore->levels[level].data, raster->pixels,
|
getLevelSize(raster, level),
|
||||||
natras->backingStore->levels[level].size);
|
raster->pixels);
|
||||||
|
if(natras->backingStore){
|
||||||
|
assert(level < natras->backingStore->numlevels);
|
||||||
|
memcpy(natras->backingStore->levels[level].data, raster->pixels,
|
||||||
|
natras->backingStore->levels[level].size);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat,
|
||||||
|
raster->width, raster->height,
|
||||||
|
0, natras->format, natras->type, raster->pixels);
|
||||||
}
|
}
|
||||||
}else{
|
if(level == 0 && natras->autogenMipmap)
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat,
|
bindTexture(prev);
|
||||||
raster->width, raster->height,
|
|
||||||
0, natras->format, natras->type, raster->pixels);
|
|
||||||
}
|
}
|
||||||
if(level == 0 && natras->autogenMipmap)
|
break;
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
bindTexture(prev);
|
case Raster::CAMERA:
|
||||||
|
// TODO: write?
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rwFree(raster->pixels);
|
rwFree(raster->pixels);
|
||||||
@ -695,6 +731,83 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image*
|
||||||
|
rasterToImage(Raster *raster)
|
||||||
|
{
|
||||||
|
int32 depth;
|
||||||
|
Image *image;
|
||||||
|
|
||||||
|
bool unlock = false;
|
||||||
|
if(raster->pixels == nil){
|
||||||
|
raster->lock(0, Raster::LOCKREAD);
|
||||||
|
unlock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gl3Raster *natras = GETGL3RASTEREXT(raster);
|
||||||
|
if(natras->isCompressed){
|
||||||
|
// TODO
|
||||||
|
RWERROR((ERR_INVRASTER));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*conv)(uint8 *out, uint8 *in) = nil;
|
||||||
|
switch(raster->format & 0xF00){
|
||||||
|
case Raster::C1555:
|
||||||
|
depth = 16;
|
||||||
|
conv = conv_ARGB1555_from_RGBA5551;
|
||||||
|
break;
|
||||||
|
case Raster::C8888:
|
||||||
|
depth = 32;
|
||||||
|
conv = conv_RGBA8888_from_RGBA8888;
|
||||||
|
break;
|
||||||
|
case Raster::C888:
|
||||||
|
depth = 24;
|
||||||
|
conv = conv_RGB888_from_RGB888;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case Raster::C555:
|
||||||
|
case Raster::C565:
|
||||||
|
case Raster::C4444:
|
||||||
|
case Raster::LUM8:
|
||||||
|
RWERROR((ERR_INVRASTER));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raster->format & Raster::PAL4 ||
|
||||||
|
raster->format & Raster::PAL8){
|
||||||
|
RWERROR((ERR_INVRASTER));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 *in, *out;
|
||||||
|
image = Image::create(raster->width, raster->height, depth);
|
||||||
|
image->allocate();
|
||||||
|
|
||||||
|
uint8 *imgpixels = image->pixels + (image->height-1)*image->stride;
|
||||||
|
uint8 *pixels = raster->pixels;
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
assert(image->width == raster->width);
|
||||||
|
assert(image->height == raster->height);
|
||||||
|
for(y = 0; y < image->height; y++){
|
||||||
|
uint8 *imgrow = imgpixels;
|
||||||
|
uint8 *rasrow = pixels;
|
||||||
|
for(x = 0; x < image->width; x++){
|
||||||
|
conv(imgrow, rasrow);
|
||||||
|
imgrow += image->bpp;
|
||||||
|
rasrow += natras->bpp;
|
||||||
|
}
|
||||||
|
imgpixels -= image->stride;
|
||||||
|
pixels += raster->stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unlock)
|
||||||
|
raster->unlock(0);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
createNativeRaster(void *object, int32 offset, int32)
|
createNativeRaster(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,46 @@ void im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flag
|
|||||||
void im3DRenderPrimitive(PrimitiveType primType);
|
void im3DRenderPrimitive(PrimitiveType primType);
|
||||||
void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices);
|
void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices);
|
||||||
void im3DEnd(void);
|
void im3DEnd(void);
|
||||||
|
|
||||||
|
struct DisplayMode
|
||||||
|
{
|
||||||
|
#ifdef LIBRW_SDL2
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
#else
|
||||||
|
GLFWvidmode mode;
|
||||||
|
#endif
|
||||||
|
int32 depth;
|
||||||
|
uint32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GlGlobals
|
||||||
|
{
|
||||||
|
#ifdef LIBRW_SDL2
|
||||||
|
SDL_Window **pWindow;
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_GLContext glcontext;
|
||||||
|
#else
|
||||||
|
GLFWwindow **pWindow;
|
||||||
|
GLFWwindow *window;
|
||||||
|
|
||||||
|
GLFWmonitor *monitor;
|
||||||
|
int numMonitors;
|
||||||
|
int currentMonitor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DisplayMode *modes;
|
||||||
|
int numModes;
|
||||||
|
int currentMode;
|
||||||
|
int presentWidth, presentHeight;
|
||||||
|
int presentOffX, presentOffY;
|
||||||
|
|
||||||
|
// for opening the window
|
||||||
|
int winWidth, winHeight;
|
||||||
|
const char *winTitle;
|
||||||
|
uint32 numSamples;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GlGlobals glGlobals;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Raster *rasterCreate(Raster *raster);
|
Raster *rasterCreate(Raster *raster);
|
||||||
@ -30,6 +70,7 @@ int32 rasterNumLevels(Raster*);
|
|||||||
bool32 imageFindRasterFormat(Image *img, int32 type,
|
bool32 imageFindRasterFormat(Image *img, int32 type,
|
||||||
int32 *width, int32 *height, int32 *depth, int32 *format);
|
int32 *width, int32 *height, int32 *depth, int32 *format);
|
||||||
bool32 rasterFromImage(Raster *raster, Image *image);
|
bool32 rasterFromImage(Raster *raster, Image *image);
|
||||||
|
Image *rasterToImage(Raster *raster);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,18 @@ conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in)
|
|||||||
out[1] = g>>2 | r<<3;
|
out[1] = g>>2 | r<<3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
conv_ARGB1555_from_RGBA5551(uint8 *out, uint8 *in)
|
||||||
|
{
|
||||||
|
uint32 r, g, b, a;
|
||||||
|
a = in[0] & 1;
|
||||||
|
b = (in[0]>>1) & 0x1F;
|
||||||
|
g = (in[1]&7)<<2 | ((in[0]>>6)&3);
|
||||||
|
r = (in[1]>>3) & 0x1F;
|
||||||
|
out[0] = b | g<<5;
|
||||||
|
out[1] = g>>3 | r<<2 | a<<7;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in)
|
conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +324,7 @@ void conv_BGR888_from_RGB888(uint8 *out, uint8 *in);
|
|||||||
void conv_ARGB1555_from_ARGB1555(uint8 *out, uint8 *in);
|
void conv_ARGB1555_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
void conv_ARGB1555_from_RGB555(uint8 *out, uint8 *in);
|
void conv_ARGB1555_from_RGB555(uint8 *out, uint8 *in);
|
||||||
void conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in);
|
void conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
|
void conv_ARGB1555_from_RGBA5551(uint8 *out, uint8 *in);
|
||||||
void conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in);
|
void conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
void conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in);
|
void conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
inline void conv_8_from_8(uint8 *out, uint8 *in) { *out = *in; }
|
inline void conv_8_from_8(uint8 *out, uint8 *in) { *out = *in; }
|
||||||
|
Loading…
Reference in New Issue
Block a user