mirror of https://github.com/bjornbytes/lovr.git
Add flag to make Canvas depth texture readable;
- DepthFormat is now just TextureFormat. - Canvas:getDepthTexture instead of Canvas:getDepthFormat.
This commit is contained in:
parent
56fa853b09
commit
cfac548e7b
|
@ -80,7 +80,6 @@ extern const char* CompareModes[];
|
|||
extern const char* ControllerAxes[];
|
||||
extern const char* ControllerButtons[];
|
||||
extern const char* ControllerHands[];
|
||||
extern const char* DepthFormats[];
|
||||
extern const char* DrawModes[];
|
||||
extern const char* EventTypes[];
|
||||
extern const char* FilterModes[];
|
||||
|
|
|
@ -63,13 +63,6 @@ const char* CompareModes[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
const char* DepthFormats[] = {
|
||||
[DEPTH_D16] = "d16",
|
||||
[DEPTH_D32F] = "d32f",
|
||||
[DEPTH_D24S8] = "d24s8",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* DrawModes[] = {
|
||||
[DRAW_MODE_FILL] = "fill",
|
||||
[DRAW_MODE_LINE] = "line",
|
||||
|
@ -154,6 +147,9 @@ const char* TextureFormats[] = {
|
|||
[FORMAT_RGB5A1] = "rgb5a1",
|
||||
[FORMAT_RGB10A2] = "rgb5a2",
|
||||
[FORMAT_RG11B10F] = "rg11b10f",
|
||||
[FORMAT_D16] = "d16",
|
||||
[FORMAT_D32F] = "d32f",
|
||||
[FORMAT_D24S8] = "d24s8",
|
||||
[FORMAT_DXT1] = "dxt1",
|
||||
[FORMAT_DXT3] = "dxt3",
|
||||
[FORMAT_DXT5] = "dxt5",
|
||||
|
@ -950,7 +946,13 @@ int l_lovrGraphicsNewCanvas(lua_State* L) {
|
|||
index = 3;
|
||||
}
|
||||
|
||||
CanvasFlags flags = { .depth = DEPTH_D16, .stereo = true, .msaa = 0, .mipmaps = true };
|
||||
CanvasFlags flags = {
|
||||
.depth = { .enabled = true, .readable = false, .format = FORMAT_D16 },
|
||||
.stereo = true,
|
||||
.msaa = 0,
|
||||
.mipmaps = true
|
||||
};
|
||||
|
||||
TextureFormat format = FORMAT_RGBA;
|
||||
bool anonymous = attachmentCount == 0;
|
||||
|
||||
|
@ -958,8 +960,18 @@ int l_lovrGraphicsNewCanvas(lua_State* L) {
|
|||
lua_getfield(L, index, "depth");
|
||||
switch (lua_type(L, -1)) {
|
||||
case LUA_TNIL: break;
|
||||
case LUA_TBOOLEAN: flags.depth = lua_toboolean(L, -1) ? DEPTH_D16 : DEPTH_NONE; break;
|
||||
default: flags.depth = luaL_checkoption(L, -1, NULL, DepthFormats);
|
||||
case LUA_TBOOLEAN: flags.depth.enabled = lua_toboolean(L, -1); break;
|
||||
case LUA_TSTRING: flags.depth.format = luaL_checkoption(L, -1, NULL, TextureFormats); break;
|
||||
case LUA_TTABLE:
|
||||
lua_getfield(L, -1, "readable");
|
||||
flags.depth.readable = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "format");
|
||||
flags.depth.format = luaL_checkoption(L, -1, NULL, TextureFormats);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
default: lovrThrow("Expected boolean, string, or table for Canvas depth flag");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
|
|
@ -121,10 +121,10 @@ int l_lovrCanvasGetDimensions(lua_State* L) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
int l_lovrCanvasGetDepthFormat(lua_State* L) {
|
||||
int l_lovrCanvasGetDepthTexture(lua_State* L) {
|
||||
Canvas* canvas = luax_checktype(L, 1, Canvas);
|
||||
DepthFormat format = lovrCanvasGetDepthFormat(canvas);
|
||||
lua_pushstring(L, DepthFormats[format]);
|
||||
Texture* texture = lovrCanvasGetDepthTexture(canvas);
|
||||
luax_pushobject(L, texture);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ const luaL_Reg lovrCanvas[] = {
|
|||
{ "getWidth", l_lovrCanvasGetWidth },
|
||||
{ "getHeight", l_lovrCanvasGetHeight },
|
||||
{ "getDimensions", l_lovrCanvasGetDimensions },
|
||||
{ "getDepthFormat", l_lovrCanvasGetDepthFormat },
|
||||
{ "getDepthTexture", l_lovrCanvasGetDepthTexture },
|
||||
{ "getMSAA", l_lovrCanvasGetMSAA },
|
||||
{ "isStereo", l_lovrCanvasIsStereo },
|
||||
{ NULL, NULL }
|
||||
|
|
|
@ -132,6 +132,9 @@ TextureData* lovrTextureDataCreate(int width, int height, uint8_t value, Texture
|
|||
case FORMAT_RGB5A1: pixelSize = 2; break;
|
||||
case FORMAT_RGB10A2: pixelSize = 4; break;
|
||||
case FORMAT_RG11B10F: pixelSize = 4; break;
|
||||
case FORMAT_D16: pixelSize = 2; break;
|
||||
case FORMAT_D32F: pixelSize = 4; break;
|
||||
case FORMAT_D24S8: pixelSize = 4; break;
|
||||
|
||||
case FORMAT_DXT1:
|
||||
case FORMAT_DXT3:
|
||||
|
|
|
@ -19,6 +19,9 @@ typedef enum {
|
|||
FORMAT_RGB5A1,
|
||||
FORMAT_RGB10A2,
|
||||
FORMAT_RG11B10F,
|
||||
FORMAT_D16,
|
||||
FORMAT_D32F,
|
||||
FORMAT_D24S8,
|
||||
FORMAT_DXT1,
|
||||
FORMAT_DXT3,
|
||||
FORMAT_DXT5
|
||||
|
|
|
@ -4,13 +4,6 @@
|
|||
|
||||
#define MAX_CANVAS_ATTACHMENTS 4
|
||||
|
||||
typedef enum {
|
||||
DEPTH_D16,
|
||||
DEPTH_D32F,
|
||||
DEPTH_D24S8,
|
||||
DEPTH_NONE
|
||||
} DepthFormat;
|
||||
|
||||
typedef struct {
|
||||
Texture* texture;
|
||||
int slice;
|
||||
|
@ -18,7 +11,11 @@ typedef struct {
|
|||
} Attachment;
|
||||
|
||||
typedef struct {
|
||||
DepthFormat depth;
|
||||
struct {
|
||||
bool enabled;
|
||||
bool readable;
|
||||
TextureFormat format;
|
||||
} depth;
|
||||
bool stereo;
|
||||
int msaa;
|
||||
bool mipmaps;
|
||||
|
@ -36,5 +33,5 @@ bool lovrCanvasIsStereo(Canvas* canvas);
|
|||
int lovrCanvasGetWidth(Canvas* canvas);
|
||||
int lovrCanvasGetHeight(Canvas* canvas);
|
||||
int lovrCanvasGetMSAA(Canvas* canvas);
|
||||
DepthFormat lovrCanvasGetDepthFormat(Canvas* canvas);
|
||||
Texture* lovrCanvasGetDepthTexture(Canvas* canvas);
|
||||
TextureData* lovrCanvasNewTextureData(Canvas* canvas, int index);
|
||||
|
|
|
@ -128,9 +128,10 @@ struct Canvas {
|
|||
int height;
|
||||
CanvasFlags flags;
|
||||
uint32_t framebuffer;
|
||||
uint32_t depthBuffer;
|
||||
uint32_t resolveBuffer;
|
||||
uint32_t depthBuffer;
|
||||
Attachment attachments[MAX_CANVAS_ATTACHMENTS];
|
||||
Attachment depth;
|
||||
int count;
|
||||
bool needsAttach;
|
||||
bool needsResolve;
|
||||
|
@ -224,6 +225,9 @@ static GLenum convertTextureFormat(TextureFormat format) {
|
|||
case FORMAT_RGB5A1: return GL_RGBA;
|
||||
case FORMAT_RGB10A2: return GL_RGBA;
|
||||
case FORMAT_RG11B10F: return GL_RGB;
|
||||
case FORMAT_D16: return GL_DEPTH_COMPONENT;
|
||||
case FORMAT_D32F: return GL_DEPTH_COMPONENT;
|
||||
case FORMAT_D24S8: return GL_DEPTH_STENCIL;
|
||||
case FORMAT_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
case FORMAT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
case FORMAT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
|
@ -244,6 +248,9 @@ static GLenum convertTextureFormatInternal(TextureFormat format, bool srgb) {
|
|||
case FORMAT_RGB5A1: return GL_RGB5_A1;
|
||||
case FORMAT_RGB10A2: return GL_RGB10_A2;
|
||||
case FORMAT_RG11B10F: return GL_R11F_G11F_B10F;
|
||||
case FORMAT_D16: return GL_DEPTH_COMPONENT16;
|
||||
case FORMAT_D32F: return GL_DEPTH_COMPONENT32F;
|
||||
case FORMAT_D24S8: return GL_DEPTH24_STENCIL8;
|
||||
case FORMAT_DXT1: return srgb ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
case FORMAT_DXT3: return srgb ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
case FORMAT_DXT5: return srgb ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
|
@ -264,6 +271,9 @@ static GLenum convertTextureFormatType(TextureFormat format) {
|
|||
case FORMAT_RGB5A1: return GL_UNSIGNED_SHORT_5_5_5_1;
|
||||
case FORMAT_RGB10A2: return GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
case FORMAT_RG11B10F: return GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||
case FORMAT_D16: return GL_UNSIGNED_SHORT;
|
||||
case FORMAT_D32F: return GL_UNSIGNED_INT;
|
||||
case FORMAT_D24S8: return GL_UNSIGNED_INT_24_8;
|
||||
case FORMAT_DXT1:
|
||||
case FORMAT_DXT3:
|
||||
case FORMAT_DXT5:
|
||||
|
@ -272,15 +282,6 @@ static GLenum convertTextureFormatType(TextureFormat format) {
|
|||
}
|
||||
}
|
||||
|
||||
static GLenum convertDepthFormat(DepthFormat format) {
|
||||
switch (format) {
|
||||
case DEPTH_D16: return GL_DEPTH_COMPONENT16; break;
|
||||
case DEPTH_D32F: return GL_DEPTH_COMPONENT32F; break;
|
||||
case DEPTH_D24S8: return GL_DEPTH24_STENCIL8; break;
|
||||
default: lovrThrow("Unreachable"); return GL_DEPTH_COMPONENT16;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isTextureFormatCompressed(TextureFormat format) {
|
||||
switch (format) {
|
||||
case FORMAT_DXT1: case FORMAT_DXT3: case FORMAT_DXT5: return true;
|
||||
|
@ -288,6 +289,13 @@ static bool isTextureFormatCompressed(TextureFormat format) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool isTextureFormatDepth(TextureFormat format) {
|
||||
switch (format) {
|
||||
case FORMAT_D16: case FORMAT_D32F: case FORMAT_D24S8: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum convertBufferUsage(BufferUsage usage) {
|
||||
switch (usage) {
|
||||
case USAGE_STATIC: return GL_STATIC_DRAW;
|
||||
|
@ -1201,13 +1209,20 @@ Canvas* lovrCanvasCreate(int width, int height, CanvasFlags flags) {
|
|||
glGenFramebuffers(1, &canvas->framebuffer);
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
|
||||
if (flags.depth != DEPTH_NONE) {
|
||||
GLenum attachment = flags.depth == DEPTH_D24S8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
GLenum format = convertDepthFormat(flags.depth);
|
||||
glGenRenderbuffers(1, &canvas->depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, canvas->depthBuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, canvas->flags.msaa, format, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, canvas->depthBuffer);
|
||||
if (flags.depth.enabled) {
|
||||
lovrAssert(isTextureFormatDepth(flags.depth.format), "Canvas depth buffer can't use a color TextureFormat");
|
||||
GLenum attachment = flags.depth.format == FORMAT_D24S8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
if (flags.depth.readable) {
|
||||
canvas->depth.texture = lovrTextureCreate(TEXTURE_2D, NULL, 0, false, flags.mipmaps, flags.msaa);
|
||||
lovrTextureAllocate(canvas->depth.texture, width, height, 1, flags.depth.format);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, canvas->depth.texture->id, 0);
|
||||
} else {
|
||||
GLenum format = convertTextureFormatInternal(flags.depth.format, false);
|
||||
glGenRenderbuffers(1, &canvas->depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, canvas->depthBuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, canvas->flags.msaa, format, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, canvas->depthBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.msaa) {
|
||||
|
@ -1225,6 +1240,7 @@ void lovrCanvasDestroy(void* ref) {
|
|||
for (int i = 0; i < canvas->count; i++) {
|
||||
lovrRelease(canvas->attachments[i].texture);
|
||||
}
|
||||
lovrRelease(canvas->depth.texture);
|
||||
free(ref);
|
||||
}
|
||||
|
||||
|
@ -1245,8 +1261,9 @@ void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, int count
|
|||
Texture* texture = attachments[i].texture;
|
||||
int width = lovrTextureGetWidth(texture, attachments[i].level);
|
||||
int height = lovrTextureGetHeight(texture, attachments[i].level);
|
||||
lovrAssert(!canvas->depthBuffer || width == canvas->width, "Texture width of %d does not match Canvas width (%d)", width, canvas->width);
|
||||
lovrAssert(!canvas->depthBuffer || height == canvas->height, "Texture height of %d does not match Canvas height (%d)", height, canvas->height);
|
||||
bool hasDepth = canvas->flags.depth.enabled;
|
||||
lovrAssert(!hasDepth || width == canvas->width, "Texture width of %d does not match Canvas width (%d)", width, canvas->width);
|
||||
lovrAssert(!hasDepth || height == canvas->height, "Texture height of %d does not match Canvas height (%d)", height, canvas->height);
|
||||
lovrAssert(texture->msaa == canvas->flags.msaa, "Texture MSAA does not match Canvas MSAA");
|
||||
lovrRetain(texture);
|
||||
}
|
||||
|
@ -1377,8 +1394,8 @@ int lovrCanvasGetMSAA(Canvas* canvas) {
|
|||
return canvas->flags.msaa;
|
||||
}
|
||||
|
||||
DepthFormat lovrCanvasGetDepthFormat(Canvas* canvas) {
|
||||
return canvas->flags.depth;
|
||||
Texture* lovrCanvasGetDepthTexture(Canvas* canvas) {
|
||||
return canvas->depth.texture;
|
||||
}
|
||||
|
||||
TextureData* lovrCanvasNewTextureData(Canvas* canvas, int index) {
|
||||
|
|
|
@ -227,7 +227,7 @@ static void ensureCanvas() {
|
|||
|
||||
uint32_t width, height;
|
||||
state.system->GetRecommendedRenderTargetSize(&width, &height);
|
||||
CanvasFlags flags = { .depth = DEPTH_D24S8, .stereo = true, .msaa = state.msaa };
|
||||
CanvasFlags flags = { .depth = { true, false, FORMAT_D24S8 }, .stereo = true, .msaa = state.msaa };
|
||||
state.canvas = lovrCanvasCreate(width * 2, height, flags);
|
||||
Texture* texture = lovrTextureCreate(TEXTURE_2D, NULL, 0, true, false, state.msaa);
|
||||
lovrTextureAllocate(texture, width * 2, height, 1, FORMAT_RGBA);
|
||||
|
|
Loading…
Reference in New Issue