mirror of https://github.com/bjornbytes/lovr.git
I came in like a wrecking ball;
This commit is contained in:
parent
87c1429778
commit
7795bb9276
|
@ -256,7 +256,7 @@ int l_lovrGraphicsInit(lua_State* L) {
|
|||
luax_registertype(L, "Shader", lovrShader);
|
||||
luax_registertype(L, "ShaderBlock", lovrShaderBlock);
|
||||
luax_registertype(L, "Texture", lovrTexture);
|
||||
luax_extendtype(L, "Texture", "Canvas", lovrTexture, lovrCanvas);
|
||||
luax_registertype(L, "Canvas", lovrCanvas);
|
||||
|
||||
luax_pushconf(L);
|
||||
|
||||
|
@ -436,22 +436,10 @@ int l_lovrGraphicsSetBlendMode(lua_State* L) {
|
|||
}
|
||||
|
||||
int l_lovrGraphicsGetCanvas(lua_State* L) {
|
||||
Canvas* canvas[MAX_CANVASES];
|
||||
int count;
|
||||
lovrGraphicsGetCanvas(canvas, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
luax_pushobject(L, canvas[i]);
|
||||
}
|
||||
return count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsSetCanvas(lua_State* L) {
|
||||
Canvas* canvas[MAX_CANVASES];
|
||||
int count = MIN(lua_gettop(L), MAX_CANVASES);
|
||||
for (int i = 0; i < count; i++) {
|
||||
canvas[i] = luax_checktype(L, i + 1, Canvas);
|
||||
}
|
||||
lovrGraphicsSetCanvas(canvas, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -949,37 +937,7 @@ int l_lovrGraphicsNewShaderBlock(lua_State* L) {
|
|||
}
|
||||
|
||||
int l_lovrGraphicsNewCanvas(lua_State* L) {
|
||||
int width = luaL_checkinteger(L, 1);
|
||||
int height = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, width > 0, 1, "width must be positive");
|
||||
luaL_argcheck(L, height > 0, 2, "height must be positive");
|
||||
|
||||
TextureFormat format = FORMAT_RGBA;
|
||||
CanvasFlags flags = { .msaa = 0, .depth = true, .stencil = false, .mipmaps = true };
|
||||
|
||||
if (lua_istable(L, 3)) {
|
||||
lua_getfield(L, 3, "format");
|
||||
format = luaL_checkoption(L, -1, "rgba", TextureFormats);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "msaa");
|
||||
flags.msaa = luaL_optinteger(L, -1, 0);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "depth");
|
||||
flags.depth = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "stencil");
|
||||
flags.stencil = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "mipmaps");
|
||||
flags.mipmaps = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
Canvas* canvas = lovrCanvasCreate(width, height, format, flags);
|
||||
Canvas* canvas = lovrCanvasCreate();
|
||||
luax_pushobject(L, canvas);
|
||||
lovrRelease(canvas);
|
||||
return 1;
|
||||
|
|
|
@ -1,46 +1,6 @@
|
|||
#include "api.h"
|
||||
#include "graphics/graphics.h"
|
||||
#include "graphics/canvas.h"
|
||||
|
||||
int l_lovrCanvasRenderTo(lua_State* L) {
|
||||
Canvas* canvas = luax_checktype(L, 1, Canvas);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
int nargs = lua_gettop(L) - 2;
|
||||
|
||||
Canvas* old[MAX_CANVASES];
|
||||
int count;
|
||||
lovrGraphicsGetCanvas(old, &count);
|
||||
lovrGraphicsSetCanvas(&canvas, 1);
|
||||
lua_call(L, nargs, 0);
|
||||
lovrGraphicsSetCanvas(old, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_lovrCanvasGetFormat(lua_State* L) {
|
||||
Canvas* canvas = luax_checktype(L, 1, Canvas);
|
||||
TextureFormat format = lovrCanvasGetFormat(canvas);
|
||||
lua_pushstring(L, TextureFormats[format]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrCanvasGetMSAA(lua_State* L) {
|
||||
Canvas* canvas = luax_checktype(L, 1, Canvas);
|
||||
lua_pushinteger(L, lovrCanvasGetMSAA(canvas));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrCanvasNewTextureData(lua_State* L) {
|
||||
Canvas* canvas = luax_checktype(L, 1, Canvas);
|
||||
TextureData* textureData = lovrCanvasNewTextureData(canvas);
|
||||
luax_pushobject(L, textureData);
|
||||
lovrRelease(textureData);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrCanvas[] = {
|
||||
{ "renderTo", l_lovrCanvasRenderTo },
|
||||
{ "getFormat", l_lovrCanvasGetFormat },
|
||||
{ "getMSAA", l_lovrCanvasGetMSAA },
|
||||
{ "newTextureData", l_lovrCanvasNewTextureData },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -1,25 +1,6 @@
|
|||
#include "graphics/texture.h"
|
||||
#include "data/textureData.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MAX_CANVASES 4
|
||||
|
||||
typedef struct {
|
||||
int msaa;
|
||||
bool depth;
|
||||
bool stencil;
|
||||
bool mipmaps;
|
||||
} CanvasFlags;
|
||||
|
||||
typedef struct Canvas Canvas;
|
||||
|
||||
bool lovrCanvasSupportsFormat(TextureFormat format);
|
||||
|
||||
Canvas* lovrCanvasCreate(int width, int height, TextureFormat format, CanvasFlags flags);
|
||||
Canvas* lovrCanvasCreate();
|
||||
void lovrCanvasDestroy(void* ref);
|
||||
void lovrCanvasResolve(Canvas* canvas);
|
||||
TextureFormat lovrCanvasGetFormat(Canvas* canvas);
|
||||
int lovrCanvasGetMSAA(Canvas* canvas);
|
||||
TextureData* lovrCanvasNewTextureData(Canvas* canvas);
|
||||
|
|
|
@ -34,7 +34,6 @@ void lovrGraphicsDestroy() {
|
|||
}
|
||||
lovrGraphicsSetShader(NULL);
|
||||
lovrGraphicsSetFont(NULL);
|
||||
lovrGraphicsSetCanvas(NULL, 0);
|
||||
for (int i = 0; i < MAX_DEFAULT_SHADERS; i++) {
|
||||
lovrRelease(state.defaultShaders[i]);
|
||||
}
|
||||
|
@ -142,9 +141,8 @@ void lovrGraphicsSetCamera(Camera* camera, bool clear) {
|
|||
}
|
||||
|
||||
if (clear) {
|
||||
int canvasCount = state.camera.canvas != NULL;
|
||||
Color backgroundColor = lovrGraphicsGetBackgroundColor();
|
||||
lovrGpuClear(&state.camera.canvas, canvasCount, &backgroundColor, &(float) { 1. }, &(int) { 0 });
|
||||
lovrGpuClear(state.camera.canvas, &backgroundColor, &(float) { 1. }, &(int) { 0 });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +156,6 @@ void lovrGraphicsReset() {
|
|||
lovrGraphicsSetCamera(NULL, false);
|
||||
lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1 });
|
||||
lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY);
|
||||
lovrGraphicsSetCanvas(NULL, 0);
|
||||
lovrGraphicsSetColor((Color) { 1, 1, 1, 1 });
|
||||
lovrGraphicsSetCullingEnabled(false);
|
||||
lovrGraphicsSetDefaultFilter((TextureFilter) { .mode = FILTER_TRILINEAR });
|
||||
|
@ -176,17 +173,11 @@ void lovrGraphicsReset() {
|
|||
void lovrGraphicsPushPipeline() {
|
||||
lovrAssert(++state.pipeline < MAX_PIPELINES, "Unbalanced pipeline stack (more pushes than pops?)");
|
||||
memcpy(&state.pipelines[state.pipeline], &state.pipelines[state.pipeline - 1], sizeof(Pipeline));
|
||||
for (int i = 0; i < state.pipelines[state.pipeline].canvasCount; i++) {
|
||||
lovrRetain(state.pipelines[state.pipeline].canvas[i]);
|
||||
}
|
||||
lovrRetain(state.pipelines[state.pipeline].font);
|
||||
lovrRetain(state.pipelines[state.pipeline].shader);
|
||||
}
|
||||
|
||||
void lovrGraphicsPopPipeline() {
|
||||
for (int i = 0; i < state.pipelines[state.pipeline].canvasCount; i++) {
|
||||
lovrRelease(state.pipelines[state.pipeline].canvas[i]);
|
||||
}
|
||||
lovrRelease(state.pipelines[state.pipeline].font);
|
||||
lovrRelease(state.pipelines[state.pipeline].shader);
|
||||
lovrAssert(--state.pipeline >= 0, "Unbalanced pipeline stack (more pops than pushes?)");
|
||||
|
@ -210,24 +201,6 @@ void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) {
|
|||
state.pipelines[state.pipeline].blendAlphaMode = alphaMode;
|
||||
}
|
||||
|
||||
void lovrGraphicsGetCanvas(Canvas** canvas, int* count) {
|
||||
*count = state.pipelines[state.pipeline].canvasCount;
|
||||
memcpy(canvas, state.pipelines[state.pipeline].canvas, *count);
|
||||
}
|
||||
|
||||
void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
lovrRetain(canvas[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < state.pipelines[state.pipeline].canvasCount; i++) {
|
||||
lovrRelease(state.pipelines[state.pipeline].canvas[i]);
|
||||
}
|
||||
|
||||
memcpy(state.pipelines[state.pipeline].canvas, canvas, count * sizeof(Canvas*));
|
||||
state.pipelines[state.pipeline].canvasCount = count;
|
||||
}
|
||||
|
||||
Color lovrGraphicsGetColor() {
|
||||
return state.pipelines[state.pipeline].color;
|
||||
}
|
||||
|
@ -381,11 +354,7 @@ VertexPointer lovrGraphicsGetVertexPointer(uint32_t count) {
|
|||
|
||||
void lovrGraphicsClear(Color* color, float* depth, int* stencil) {
|
||||
Pipeline* pipeline = &state.pipelines[state.pipeline];
|
||||
if (pipeline->canvasCount > 0) {
|
||||
lovrGpuClear(pipeline->canvas, pipeline->canvasCount, color, depth, stencil);
|
||||
} else {
|
||||
lovrGpuClear(&state.camera.canvas, state.camera.canvas != NULL, color, depth, stencil);
|
||||
}
|
||||
lovrGpuClear(state.camera.canvas, color, depth, stencil);
|
||||
}
|
||||
|
||||
void lovrGraphicsDraw(DrawOptions* draw) {
|
||||
|
|
|
@ -106,8 +106,6 @@ typedef struct {
|
|||
Color backgroundColor;
|
||||
BlendMode blendMode;
|
||||
BlendAlphaMode blendAlphaMode;
|
||||
Canvas* canvas[MAX_CANVASES];
|
||||
int canvasCount;
|
||||
Color color;
|
||||
bool culling;
|
||||
CompareMode depthTest;
|
||||
|
@ -192,8 +190,6 @@ Color lovrGraphicsGetBackgroundColor();
|
|||
void lovrGraphicsSetBackgroundColor(Color color);
|
||||
void lovrGraphicsGetBlendMode(BlendMode* mode, BlendAlphaMode* alphaMode);
|
||||
void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode);
|
||||
void lovrGraphicsGetCanvas(Canvas** canvas, int* count);
|
||||
void lovrGraphicsSetCanvas(Canvas** canvas, int count);
|
||||
Color lovrGraphicsGetColor();
|
||||
void lovrGraphicsSetColor(Color color);
|
||||
bool lovrGraphicsIsCullingEnabled();
|
||||
|
@ -252,7 +248,7 @@ typedef void (*gpuProc)(void);
|
|||
|
||||
void lovrGpuInit(bool srgb, bool singlepass, gpuProc (*getProcAddress)(const char*));
|
||||
void lovrGpuDestroy();
|
||||
void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth, int* stencil);
|
||||
void lovrGpuClear(Canvas* canvas, Color* color, float* depth, int* stencil);
|
||||
void lovrGpuDraw(DrawCommand* command);
|
||||
void lovrGpuCompute(Shader* shader, int x, int y, int z);
|
||||
void lovrGpuWait(uint8_t flags);
|
||||
|
|
|
@ -49,8 +49,6 @@ static struct {
|
|||
bool stencilWriting;
|
||||
Winding winding;
|
||||
bool wireframe;
|
||||
Canvas* canvas[MAX_CANVASES];
|
||||
int canvasCount;
|
||||
uint32_t framebuffer;
|
||||
uint32_t indexBuffer;
|
||||
uint32_t program;
|
||||
|
@ -111,13 +109,8 @@ struct Texture {
|
|||
};
|
||||
|
||||
struct Canvas {
|
||||
Texture texture;
|
||||
GLuint framebuffer;
|
||||
GLuint resolveFramebuffer;
|
||||
GLuint depthStencilBuffer;
|
||||
GLuint msaaTexture;
|
||||
CanvasFlags flags;
|
||||
Canvas** attachments[MAX_CANVASES];
|
||||
Ref ref;
|
||||
uint32_t framebuffer;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -286,16 +279,6 @@ static GLenum convertMeshDrawMode(MeshDrawMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool isCanvasFormatSupported(TextureFormat format) {
|
||||
switch (format) {
|
||||
case FORMAT_DXT1:
|
||||
case FORMAT_DXT3:
|
||||
case FORMAT_DXT5:
|
||||
return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
static UniformType getUniformType(GLenum type, const char* debug) {
|
||||
switch (type) {
|
||||
case GL_FLOAT:
|
||||
|
@ -448,13 +431,6 @@ static void lovrGpuCleanupIncoherentResource(void* resource, uint8_t incoherent)
|
|||
|
||||
// GPU
|
||||
|
||||
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
|
||||
if (state.framebuffer != framebuffer) {
|
||||
state.framebuffer = framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void lovrGpuBindIndexBuffer(uint32_t indexBuffer) {
|
||||
if (state.indexBuffer != indexBuffer) {
|
||||
state.indexBuffer = indexBuffer;
|
||||
|
@ -529,13 +505,6 @@ static void lovrGpuBindVertexBuffer(uint32_t vertexBuffer) {
|
|||
}
|
||||
}
|
||||
|
||||
static void lovrGpuSetViewport(float viewport[4]) {
|
||||
if (memcmp(state.viewport, viewport, 4 * sizeof(float))) {
|
||||
memcpy(state.viewport, viewport, 4 * sizeof(float));
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static void lovrGpuUseProgram(uint32_t program) {
|
||||
if (state.program != program) {
|
||||
state.program = program;
|
||||
|
@ -590,34 +559,7 @@ void lovrGpuDestroy() {
|
|||
}
|
||||
}
|
||||
|
||||
void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth, int* stencil) {
|
||||
lovrGpuBindFramebuffer(canvasCount > 0 ? canvas[0]->framebuffer : 0);
|
||||
|
||||
if (color) {
|
||||
gammaCorrectColor(color);
|
||||
float c[4] = { color->r, color->g, color->b, color->a };
|
||||
glClearBufferfv(GL_COLOR, 0, c);
|
||||
for (int i = 1; i < canvasCount; i++) {
|
||||
glClearBufferfv(GL_COLOR, i, c);
|
||||
}
|
||||
}
|
||||
|
||||
if (depth) {
|
||||
if (!state.depthWrite) {
|
||||
state.depthWrite = true;
|
||||
glDepthMask(state.depthWrite);
|
||||
}
|
||||
|
||||
glClearBufferfv(GL_DEPTH, 0, depth);
|
||||
}
|
||||
|
||||
if (stencil) {
|
||||
glClearBufferiv(GL_STENCIL, 0, stencil);
|
||||
}
|
||||
|
||||
if (canvasCount > 0) {
|
||||
lovrCanvasResolve(canvas[0]);
|
||||
}
|
||||
void lovrGpuClear(Canvas* canvas, Color* color, float* depth, int* stencil) {
|
||||
}
|
||||
|
||||
void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback callback, void* userdata) {
|
||||
|
@ -864,65 +806,14 @@ void lovrGpuDraw(DrawCommand* command) {
|
|||
|
||||
lovrShaderSetMatrices(shader, "lovrMaterialTransform", material->transform, 0, 9);
|
||||
|
||||
// Canvas
|
||||
Canvas** canvas = pipeline->canvasCount > 0 ? pipeline->canvas : &command->camera.canvas;
|
||||
int canvasCount = pipeline->canvasCount > 0 ? pipeline->canvasCount : (command->camera.canvas != NULL);
|
||||
if (canvasCount != state.canvasCount || memcmp(state.canvas, canvas, canvasCount * sizeof(Canvas*))) {
|
||||
if (state.canvasCount > 0) {
|
||||
lovrCanvasResolve(state.canvas[0]);
|
||||
}
|
||||
|
||||
state.canvasCount = canvasCount;
|
||||
|
||||
if (canvasCount > 0) {
|
||||
memcpy(state.canvas, canvas, canvasCount * sizeof(Canvas*));
|
||||
lovrGpuBindFramebuffer(canvas[0]->framebuffer);
|
||||
|
||||
GLenum buffers[MAX_CANVASES];
|
||||
for (int i = 0; i < canvasCount; i++) {
|
||||
buffers[i] = GL_COLOR_ATTACHMENT0 + i;
|
||||
if (canvas[i]->flags.msaa > 0) {
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, buffers[i], GL_RENDERBUFFER, canvas[i]->msaaTexture);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[i], GL_TEXTURE_2D, lovrTextureGetId((Texture*) canvas[i]), 0);
|
||||
}
|
||||
}
|
||||
glDrawBuffers(canvasCount, buffers);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
lovrAssert(status == GL_FRAMEBUFFER_COMPLETE, "Unable to bind framebuffer");
|
||||
} else {
|
||||
lovrGpuBindFramebuffer(0);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to synchronize if any attached textures have pending writes
|
||||
for (int i = 0; i < canvasCount; i++) {
|
||||
if ((canvas[i]->texture.incoherent >> BARRIER_CANVAS) & 1) {
|
||||
lovrGpuWait(1 << BARRIER_CANVAS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Bind attributes
|
||||
lovrMeshBind(mesh, shader);
|
||||
|
||||
bool stereo = pipeline->canvasCount == 0 && command->camera.stereo == true;
|
||||
bool stereo = false;
|
||||
int drawCount = 1 + (stereo == true && !state.singlepass);
|
||||
|
||||
// Draw (TODEW)
|
||||
for (int i = 0; i < drawCount; i++) {
|
||||
if (pipeline->canvasCount > 0) {
|
||||
int width = lovrTextureGetWidth((Texture*) pipeline->canvas[0], 0);
|
||||
int height = lovrTextureGetHeight((Texture*) pipeline->canvas[0], 0);
|
||||
lovrGpuSetViewport((float[4]) { 0, 0, width, height });
|
||||
#ifndef EMSCRIPTEN
|
||||
} else if (state.singlepass) {
|
||||
glViewportArrayv(0, 2, command->camera.viewport[0]);
|
||||
#endif
|
||||
} else {
|
||||
lovrGpuSetViewport(command->camera.viewport[i]);
|
||||
}
|
||||
|
||||
// Bind uniforms
|
||||
lovrShaderSetInts(shader, "lovrIsStereo", &(int) { stereo && state.singlepass }, 0, 1);
|
||||
|
@ -1295,125 +1186,16 @@ void lovrTextureSetWrap(Texture* texture, TextureWrap wrap) {
|
|||
|
||||
// Canvas
|
||||
|
||||
Canvas* lovrCanvasCreate(int width, int height, TextureFormat format, CanvasFlags flags) {
|
||||
lovrAssert(isCanvasFormatSupported(format), "Unsupported texture format for Canvas");
|
||||
Canvas* lovrCanvasCreate() {
|
||||
Canvas* canvas = lovrAlloc(Canvas, lovrCanvasDestroy);
|
||||
Texture* texture = lovrTextureCreate(TEXTURE_2D, NULL, 0, true, flags.mipmaps);
|
||||
|
||||
if (!canvas || !texture) {
|
||||
lovrRelease(canvas);
|
||||
lovrRelease(texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lovrTextureAllocate(texture, width, height, 1, format);
|
||||
|
||||
Ref ref = canvas->texture.ref;
|
||||
canvas->texture = *texture;
|
||||
canvas->texture.ref = ref;
|
||||
canvas->flags = flags;
|
||||
|
||||
// Framebuffer
|
||||
glGenFramebuffers(1, &canvas->framebuffer);
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
|
||||
// Color attachment
|
||||
if (flags.msaa > 0) {
|
||||
GLenum internalFormat = convertTextureFormatInternal(format, lovrGraphicsIsGammaCorrect());
|
||||
glGenRenderbuffers(1, &canvas->msaaTexture);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, canvas->msaaTexture);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, flags.msaa, internalFormat, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, canvas->msaaTexture);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, canvas->texture.id, 0);
|
||||
}
|
||||
|
||||
// Depth/Stencil
|
||||
if (flags.depth || flags.stencil) {
|
||||
GLenum depthStencilFormat = flags.stencil ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT24;
|
||||
glGenRenderbuffers(1, &canvas->depthStencilBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, canvas->depthStencilBuffer);
|
||||
if (flags.msaa > 0) {
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, flags.msaa, depthStencilFormat, width, height);
|
||||
} else {
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
|
||||
}
|
||||
|
||||
if (flags.depth) {
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, canvas->depthStencilBuffer);
|
||||
}
|
||||
|
||||
if (flags.stencil) {
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, canvas->depthStencilBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve framebuffer
|
||||
if (flags.msaa > 0) {
|
||||
glGenFramebuffers(1, &canvas->resolveFramebuffer);
|
||||
lovrGpuBindFramebuffer(canvas->resolveFramebuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, canvas->texture.id);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, canvas->texture.id, 0);
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
}
|
||||
|
||||
lovrAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Error creating Canvas");
|
||||
lovrGpuClear(&canvas, 1, &(Color) { 0, 0, 0, 0 }, &(float) { 1. }, &(int) { 0 });
|
||||
if (!canvas) return NULL;
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
void lovrCanvasDestroy(void* ref) {
|
||||
Canvas* canvas = ref;
|
||||
glDeleteFramebuffers(1, &canvas->framebuffer);
|
||||
if (canvas->resolveFramebuffer) {
|
||||
glDeleteFramebuffers(1, &canvas->resolveFramebuffer);
|
||||
}
|
||||
if (canvas->depthStencilBuffer) {
|
||||
glDeleteRenderbuffers(1, &canvas->depthStencilBuffer);
|
||||
}
|
||||
if (canvas->msaaTexture) {
|
||||
glDeleteTextures(1, &canvas->msaaTexture);
|
||||
}
|
||||
lovrTextureDestroy(ref);
|
||||
}
|
||||
|
||||
void lovrCanvasResolve(Canvas* canvas) {
|
||||
if (canvas->flags.msaa > 0) {
|
||||
int width = canvas->texture.width;
|
||||
int height = canvas->texture.height;
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, canvas->framebuffer);
|
||||
lovrGpuBindFramebuffer(canvas->resolveFramebuffer);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
if (canvas->flags.mipmaps) {
|
||||
lovrGpuBindTexture(&canvas->texture, 0);
|
||||
glGenerateMipmap(canvas->texture.target);
|
||||
}
|
||||
}
|
||||
|
||||
TextureFormat lovrCanvasGetFormat(Canvas* canvas) {
|
||||
return canvas->texture.format;
|
||||
}
|
||||
|
||||
int lovrCanvasGetMSAA(Canvas* canvas) {
|
||||
return canvas->flags.msaa;
|
||||
}
|
||||
|
||||
TextureData* lovrCanvasNewTextureData(Canvas* canvas) {
|
||||
TextureData* textureData = lovrTextureDataGetBlank(canvas->texture.width, canvas->texture.height, 0, FORMAT_RGBA);
|
||||
if (!textureData) return NULL;
|
||||
|
||||
if ((canvas->texture.incoherent >> BARRIER_TEXTURE) & 1) {
|
||||
lovrGpuWait(1 << BARRIER_TEXTURE);
|
||||
}
|
||||
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
glReadPixels(0, 0, canvas->texture.width, canvas->texture.height, GL_RGBA, GL_UNSIGNED_BYTE, textureData->blob.data);
|
||||
|
||||
return textureData;
|
||||
free(ref);
|
||||
}
|
||||
|
||||
// Shader
|
||||
|
|
|
@ -240,11 +240,7 @@ static void ensureCanvas() {
|
|||
return;
|
||||
}
|
||||
|
||||
int maxMSAA = lovrGraphicsGetLimits().textureMSAA;
|
||||
int msaa = state.msaa == -1 ? maxMSAA : MIN(state.msaa, maxMSAA);
|
||||
state.system->GetRecommendedRenderTargetSize(&state.renderWidth, &state.renderHeight);
|
||||
CanvasFlags flags = { .msaa = msaa, .depth = true, .stencil = true, .mipmaps = false };
|
||||
state.canvas = lovrCanvasCreate(state.renderWidth * 2, state.renderHeight, FORMAT_RGB, flags);
|
||||
state.canvas = lovrCanvasCreate();
|
||||
}
|
||||
|
||||
static bool openvrInit(float offset, int msaa) {
|
||||
|
@ -685,12 +681,10 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
|
|||
lovrGraphicsSetCamera(&camera, true);
|
||||
callback(userdata);
|
||||
lovrGraphicsSetCamera(NULL, false);
|
||||
lovrGraphicsSetCanvas(NULL, 0);
|
||||
lovrCanvasResolve(state.canvas);
|
||||
state.isRendering = false;
|
||||
|
||||
// Submit
|
||||
uintptr_t texture = (uintptr_t) lovrTextureGetId((Texture*) state.canvas);
|
||||
uintptr_t texture = (uintptr_t) 0; // TODO
|
||||
EColorSpace colorSpace = lovrGraphicsIsGammaCorrect() ? EColorSpace_ColorSpace_Linear : EColorSpace_ColorSpace_Gamma;
|
||||
Texture_t eyeTexture = { (void*) texture, ETextureType_TextureType_OpenGL, colorSpace };
|
||||
VRTextureBounds_t left = { 0, 0, .5, 1. };
|
||||
|
@ -703,7 +697,7 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
|
|||
lovrGraphicsPushPipeline();
|
||||
lovrGraphicsSetColor((Color) { 1, 1, 1, 1 });
|
||||
lovrGraphicsSetShader(NULL);
|
||||
lovrGraphicsFill((Texture*) state.canvas);
|
||||
// TODO
|
||||
lovrGraphicsPopPipeline();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue