mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
little work on gl3 rasters
This commit is contained in:
parent
f1c9112f27
commit
eb49dd007c
14
premake5.lua
14
premake5.lua
@ -2,7 +2,7 @@ newoption {
|
|||||||
trigger = "glewdir",
|
trigger = "glewdir",
|
||||||
value = "PATH",
|
value = "PATH",
|
||||||
description = "Directory of GLEW",
|
description = "Directory of GLEW",
|
||||||
default = "C:/Users/aap/src/glew-2.1.0",
|
default = "../glew-2.1.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
newoption {
|
newoption {
|
||||||
@ -20,14 +20,21 @@ newoption {
|
|||||||
trigger = "glfwdir",
|
trigger = "glfwdir",
|
||||||
value = "PATH",
|
value = "PATH",
|
||||||
description = "Directory of glfw",
|
description = "Directory of glfw",
|
||||||
default = "C:/Users/aap/src/glfw-3.2.1.bin.WIN64",
|
default = "../glfw-3.3.2.bin.WIN64",
|
||||||
|
}
|
||||||
|
|
||||||
|
newoption {
|
||||||
|
trigger = "glfwdir32",
|
||||||
|
value = "PATH",
|
||||||
|
description = "Directory of glfw",
|
||||||
|
default = "../glfw-3.3.2.bin.WIN32",
|
||||||
}
|
}
|
||||||
|
|
||||||
newoption {
|
newoption {
|
||||||
trigger = "sdl2dir",
|
trigger = "sdl2dir",
|
||||||
value = "PATH",
|
value = "PATH",
|
||||||
description = "Directory of sdl2",
|
description = "Directory of sdl2",
|
||||||
default = "C:/Users/aap/src/SDL2-2.0.8",
|
default = "../SDL2-2.0.8",
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace "librw"
|
workspace "librw"
|
||||||
@ -138,6 +145,7 @@ function findlibs()
|
|||||||
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
|
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
|
||||||
filter { "platforms:win-x86-gl3" }
|
filter { "platforms:win-x86-gl3" }
|
||||||
libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") }
|
libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") }
|
||||||
|
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-vc2015") }
|
||||||
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
|
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
|
||||||
filter { "platforms:win*gl3" }
|
filter { "platforms:win*gl3" }
|
||||||
links { "opengl32" }
|
links { "opengl32" }
|
||||||
|
@ -495,6 +495,8 @@ rasterCreateTexture(Raster *raster)
|
|||||||
assert(natras->texture && "couldn't create d3d texture");
|
assert(natras->texture && "couldn't create d3d texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rasterCreateCameraTexture(Raster *raster)
|
rasterCreateCameraTexture(Raster *raster)
|
||||||
{
|
{
|
||||||
@ -506,7 +508,6 @@ rasterCreateCameraTexture(Raster *raster)
|
|||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
levels = Raster::calculateNumLevels(raster->width, raster->height);
|
levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||||
|
|
||||||
#ifdef RW_D3D9
|
|
||||||
IDirect3DTexture9 *tex;
|
IDirect3DTexture9 *tex;
|
||||||
d3ddevice->CreateTexture(raster->width, raster->height,
|
d3ddevice->CreateTexture(raster->width, raster->height,
|
||||||
raster->format & Raster::MIPMAP ? levels : 1,
|
raster->format & Raster::MIPMAP ? levels : 1,
|
||||||
@ -514,9 +515,6 @@ rasterCreateCameraTexture(Raster *raster)
|
|||||||
(D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil);
|
(D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil);
|
||||||
natras->texture = tex;
|
natras->texture = tex;
|
||||||
addVidmemRaster(raster);
|
addVidmemRaster(raster);
|
||||||
#else
|
|
||||||
natras->texture = nil;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -529,10 +527,8 @@ rasterCreateCamera(Raster *raster)
|
|||||||
raster->stride = 0;
|
raster->stride = 0;
|
||||||
raster->pixels = nil;
|
raster->pixels = nil;
|
||||||
|
|
||||||
#ifdef RW_D3D9
|
|
||||||
natras->format = d3d9Globals.present.BackBufferFormat;
|
natras->format = d3d9Globals.present.BackBufferFormat;
|
||||||
raster->depth = findFormatDepth(natras->format);
|
raster->depth = findFormatDepth(natras->format);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -545,11 +541,10 @@ rasterCreateZbuffer(Raster *raster)
|
|||||||
raster->stride = 0;
|
raster->stride = 0;
|
||||||
raster->pixels = nil;
|
raster->pixels = nil;
|
||||||
|
|
||||||
#ifdef RW_D3D9
|
|
||||||
natras->format = d3d9Globals.present.AutoDepthStencilFormat;
|
natras->format = d3d9Globals.present.AutoDepthStencilFormat;
|
||||||
raster->depth = findFormatDepth(natras->format);
|
raster->depth = findFormatDepth(natras->format);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
@ -574,6 +569,7 @@ rasterCreate(Raster *raster)
|
|||||||
rasterCreateTexture(raster);
|
rasterCreateTexture(raster);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
case Raster::CAMERATEXTURE:
|
case Raster::CAMERATEXTURE:
|
||||||
if(raster->flags & Raster::DONTALLOCATE)
|
if(raster->flags & Raster::DONTALLOCATE)
|
||||||
return;
|
return;
|
||||||
@ -586,6 +582,7 @@ rasterCreate(Raster *raster)
|
|||||||
case Raster::CAMERA:
|
case Raster::CAMERA:
|
||||||
rasterCreateCamera(raster);
|
rasterCreateCamera(raster);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@ struct RwStateCache {
|
|||||||
static RwStateCache rwStateCache;
|
static RwStateCache rwStateCache;
|
||||||
|
|
||||||
static int32 activeTexture;
|
static int32 activeTexture;
|
||||||
|
static uint32 boundTexture[MAXNUMSTAGES];
|
||||||
|
|
||||||
static uint32 blendMap[] = {
|
static uint32 blendMap[] = {
|
||||||
GL_ZERO, // actually invalid
|
GL_ZERO, // actually invalid
|
||||||
@ -198,10 +199,17 @@ setActiveTexture(int32 n)
|
|||||||
{
|
{
|
||||||
if(activeTexture != n){
|
if(activeTexture != n){
|
||||||
activeTexture = n;
|
activeTexture = n;
|
||||||
glActiveTexture(n);
|
glActiveTexture(GL_TEXTURE0+n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bindTexture(uint32 texid)
|
||||||
|
{
|
||||||
|
boundTexture[activeTexture] = texid;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texid);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: support mipmaps
|
// TODO: support mipmaps
|
||||||
static GLint filterConvMap_NoMIP[] = {
|
static GLint filterConvMap_NoMIP[] = {
|
||||||
0, GL_NEAREST, GL_LINEAR,
|
0, GL_NEAREST, GL_LINEAR,
|
||||||
@ -272,11 +280,11 @@ setRasterStageOnly(uint32 stage, Raster *raster)
|
|||||||
bool32 alpha;
|
bool32 alpha;
|
||||||
if(raster != rwStateCache.texstage[stage].raster){
|
if(raster != rwStateCache.texstage[stage].raster){
|
||||||
rwStateCache.texstage[stage].raster = raster;
|
rwStateCache.texstage[stage].raster = raster;
|
||||||
setActiveTexture(GL_TEXTURE0+stage);
|
setActiveTexture(stage);
|
||||||
if(raster){
|
if(raster){
|
||||||
assert(raster->platform == PLATFORM_GL3);
|
assert(raster->platform == PLATFORM_GL3);
|
||||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
bindTexture(natras->texid);
|
||||||
|
|
||||||
rwStateCache.texstage[stage].filter = (rw::Texture::FilterMode)natras->filterMode;
|
rwStateCache.texstage[stage].filter = (rw::Texture::FilterMode)natras->filterMode;
|
||||||
rwStateCache.texstage[stage].addressingU = (rw::Texture::Addressing)natras->addressU;
|
rwStateCache.texstage[stage].addressingU = (rw::Texture::Addressing)natras->addressU;
|
||||||
@ -284,7 +292,7 @@ setRasterStageOnly(uint32 stage, Raster *raster)
|
|||||||
|
|
||||||
alpha = natras->hasAlpha;
|
alpha = natras->hasAlpha;
|
||||||
}else{
|
}else{
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
bindTexture(whitetex);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
@ -310,11 +318,11 @@ setRasterStage(uint32 stage, Raster *raster)
|
|||||||
bool32 alpha;
|
bool32 alpha;
|
||||||
if(raster != rwStateCache.texstage[stage].raster){
|
if(raster != rwStateCache.texstage[stage].raster){
|
||||||
rwStateCache.texstage[stage].raster = raster;
|
rwStateCache.texstage[stage].raster = raster;
|
||||||
setActiveTexture(GL_TEXTURE0+stage);
|
setActiveTexture(stage);
|
||||||
if(raster){
|
if(raster){
|
||||||
assert(raster->platform == PLATFORM_GL3);
|
assert(raster->platform == PLATFORM_GL3);
|
||||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
bindTexture(natras->texid);
|
||||||
uint32 filter = rwStateCache.texstage[stage].filter;
|
uint32 filter = rwStateCache.texstage[stage].filter;
|
||||||
uint32 addrU = rwStateCache.texstage[stage].addressingU;
|
uint32 addrU = rwStateCache.texstage[stage].addressingU;
|
||||||
uint32 addrV = rwStateCache.texstage[stage].addressingV;
|
uint32 addrV = rwStateCache.texstage[stage].addressingV;
|
||||||
@ -333,7 +341,7 @@ setRasterStage(uint32 stage, Raster *raster)
|
|||||||
}
|
}
|
||||||
alpha = natras->hasAlpha;
|
alpha = natras->hasAlpha;
|
||||||
}else{
|
}else{
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
bindTexture(whitetex);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
@ -549,10 +557,12 @@ resetRenderState(void)
|
|||||||
rwStateCache.cullmode = CULLNONE;
|
rwStateCache.cullmode = CULLNONE;
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
activeTexture = -1;
|
||||||
for(int i = 0; i < MAXNUMSTAGES; i++){
|
for(int i = 0; i < MAXNUMSTAGES; i++){
|
||||||
glActiveTexture(GL_TEXTURE0+i);
|
setActiveTexture(i);
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
bindTexture(whitetex);
|
||||||
}
|
}
|
||||||
|
setActiveTexture(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -665,7 +675,26 @@ showRaster(Raster *raster)
|
|||||||
static bool32
|
static bool32
|
||||||
rasterRenderFast(Raster *raster, int32 x, int32 y)
|
rasterRenderFast(Raster *raster, int32 x, int32 y)
|
||||||
{
|
{
|
||||||
// use glCopyTexSubImage2D
|
Raster *src = raster;
|
||||||
|
Raster *dst = Raster::getCurrentContext();
|
||||||
|
Gl3Raster *natdst = PLUGINOFFSET(Gl3Raster, dst, nativeRasterOffset);
|
||||||
|
Gl3Raster *natsrc = PLUGINOFFSET(Gl3Raster, src, nativeRasterOffset);
|
||||||
|
|
||||||
|
switch(dst->type){
|
||||||
|
case Raster::NORMAL:
|
||||||
|
case Raster::TEXTURE:
|
||||||
|
case Raster::CAMERATEXTURE:
|
||||||
|
switch(src->type){
|
||||||
|
case Raster::CAMERA:
|
||||||
|
setActiveTexture(0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, natdst->texid);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, (dst->height-src->height)-y,
|
||||||
|
0, 0, src->width, src->height);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, boundTexture[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,7 +1085,6 @@ deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
|||||||
{
|
{
|
||||||
GLFWmonitor **monitors;
|
GLFWmonitor **monitors;
|
||||||
VideoMode *rwmode;
|
VideoMode *rwmode;
|
||||||
int num;
|
|
||||||
|
|
||||||
switch(req){
|
switch(req){
|
||||||
case DEVICEOPEN:
|
case DEVICEOPEN:
|
||||||
|
@ -20,40 +20,9 @@ namespace gl3 {
|
|||||||
|
|
||||||
int32 nativeRasterOffset;
|
int32 nativeRasterOffset;
|
||||||
|
|
||||||
void
|
static void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreateTexture(Raster *raster)
|
||||||
{
|
{
|
||||||
// Dummy to use as subraster
|
|
||||||
if(raster->width == 0 || raster->height == 0){
|
|
||||||
raster->flags |= Raster::DONTALLOCATE;
|
|
||||||
raster->stride = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(raster->type){
|
|
||||||
case Raster::CAMERA:
|
|
||||||
// TODO: set/check width, height, depth, format?
|
|
||||||
raster->flags |= Raster::DONTALLOCATE;
|
|
||||||
raster->originalWidth = raster->width;
|
|
||||||
raster->originalHeight = raster->height;
|
|
||||||
raster->stride = 0;
|
|
||||||
raster->pixels = nil;
|
|
||||||
break;
|
|
||||||
case Raster::ZBUFFER:
|
|
||||||
// TODO: set/check width, height, depth, format?
|
|
||||||
raster->flags |= Raster::DONTALLOCATE;
|
|
||||||
break;
|
|
||||||
case Raster::NORMAL:
|
|
||||||
case Raster::TEXTURE:
|
|
||||||
// continue below
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0 && "unsupported format");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(raster->flags & Raster::DONTALLOCATE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef RW_OPENGL
|
#ifdef RW_OPENGL
|
||||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
switch(raster->format & 0xF00){
|
switch(raster->format & 0xF00){
|
||||||
@ -93,6 +62,114 @@ rasterCreate(Raster *raster)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
|
||||||
|
// This is totally fake right now, can't render to it. Only used to copy into from FB
|
||||||
|
// For rendering the idea would probably be to render to the backbuffer and copy it here afterwards.
|
||||||
|
// alternatively just use FBOs but that probably needs some more infrastructure.
|
||||||
|
static void
|
||||||
|
rasterCreateCameraTexture(Raster *raster)
|
||||||
|
{
|
||||||
|
if(raster->format & (Raster::PAL4 | Raster::PAL8))
|
||||||
|
// TODO: give some error
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: figure out what the backbuffer is and use that as a default
|
||||||
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
|
switch(raster->format & 0xF00){
|
||||||
|
case Raster::C8888:
|
||||||
|
default:
|
||||||
|
natras->internalFormat = GL_RGBA;
|
||||||
|
natras->format = GL_RGBA;
|
||||||
|
natras->type = GL_UNSIGNED_BYTE;
|
||||||
|
natras->hasAlpha = 1;
|
||||||
|
break;
|
||||||
|
case Raster::C888:
|
||||||
|
natras->internalFormat = GL_RGB;
|
||||||
|
natras->format = GL_RGB;
|
||||||
|
natras->type = GL_UNSIGNED_BYTE;
|
||||||
|
natras->hasAlpha = 0;
|
||||||
|
break;
|
||||||
|
case Raster::C1555:
|
||||||
|
// TODO: check if this is correct
|
||||||
|
natras->internalFormat = GL_RGBA;
|
||||||
|
natras->format = GL_RGBA;
|
||||||
|
natras->type = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||||
|
natras->hasAlpha = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(1, &natras->texid);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
||||||
|
raster->width, raster->height,
|
||||||
|
0, natras->format, natras->type, nil);
|
||||||
|
natras->filterMode = 0;
|
||||||
|
natras->addressU = 0;
|
||||||
|
natras->addressV = 0;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rasterCreateCamera(Raster *raster)
|
||||||
|
{
|
||||||
|
// TODO: set/check width, height, depth, format?
|
||||||
|
raster->flags |= Raster::DONTALLOCATE;
|
||||||
|
raster->originalWidth = raster->width;
|
||||||
|
raster->originalHeight = raster->height;
|
||||||
|
raster->stride = 0;
|
||||||
|
raster->pixels = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rasterCreateZbuffer(Raster *raster)
|
||||||
|
{
|
||||||
|
// TODO: set/check width, height, depth, format?
|
||||||
|
raster->flags |= Raster::DONTALLOCATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
rasterCreate(Raster *raster)
|
||||||
|
{
|
||||||
|
switch(raster->type){
|
||||||
|
case Raster::NORMAL:
|
||||||
|
case Raster::TEXTURE:
|
||||||
|
// Dummy to use as subraster
|
||||||
|
// ^ what did i do there?
|
||||||
|
if(raster->width == 0 || raster->height == 0){
|
||||||
|
raster->flags |= Raster::DONTALLOCATE;
|
||||||
|
raster->stride = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raster->flags & Raster::DONTALLOCATE)
|
||||||
|
return;
|
||||||
|
rasterCreateTexture(raster);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
case Raster::CAMERATEXTURE:
|
||||||
|
if(raster->flags & Raster::DONTALLOCATE)
|
||||||
|
return;
|
||||||
|
rasterCreateCameraTexture(raster);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Raster::ZBUFFER:
|
||||||
|
rasterCreateZbuffer(raster);
|
||||||
|
break;
|
||||||
|
case Raster::CAMERA:
|
||||||
|
rasterCreateCamera(raster);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0 && "unsupported format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8*
|
uint8*
|
||||||
rasterLock(Raster*, int32 level, int32 lockMode)
|
rasterLock(Raster*, int32 level, int32 lockMode)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user