mirror of https://github.com/bjornbytes/lovr.git
Add defaultCanvas;
Having a normal Canvas object that represents the backbuffer reduces some indirection where we have to last-minute check if a Canvas is set. It also means that all of the draw-related info that was _sometimes_ on the Canvas is now _always_ on the Canvas, which reduces the amount of redundant information we need to provide for a draw call. There may be some issues related to changing the width/height/stereo of the default Canvas.
This commit is contained in:
parent
111872904a
commit
7e067da8e7
|
@ -94,6 +94,7 @@ static struct {
|
|||
int width;
|
||||
int height;
|
||||
Camera camera;
|
||||
Canvas* defaultCanvas;
|
||||
Shader* defaultShaders[MAX_DEFAULT_SHADERS];
|
||||
Material* defaultMaterial;
|
||||
Font* defaultFont;
|
||||
|
@ -158,6 +159,8 @@ static void onCloseWindow(void) {
|
|||
static void onResizeWindow(int width, int height) {
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
state.defaultCanvas->width = width;
|
||||
state.defaultCanvas->height = height;
|
||||
}
|
||||
|
||||
static void* lovrGraphicsMapBuffer(StreamType type, uint32_t count) {
|
||||
|
@ -194,6 +197,7 @@ void lovrGraphicsDestroy() {
|
|||
lovrRelease(Buffer, state.identityBuffer);
|
||||
lovrRelease(Material, state.defaultMaterial);
|
||||
lovrRelease(Font, state.defaultFont);
|
||||
lovrRelease(Canvas, state.defaultCanvas);
|
||||
lovrGpuDestroy();
|
||||
memset(&state, 0, sizeof(state));
|
||||
}
|
||||
|
@ -212,6 +216,8 @@ void lovrGraphicsCreateWindow(WindowFlags* flags) {
|
|||
lovrPlatformGetFramebufferSize(&state.width, &state.height);
|
||||
lovrGpuInit(lovrGetProcAddress);
|
||||
|
||||
state.defaultCanvas = lovrCanvasCreateFromHandle(state.width, state.height, (CanvasFlags) { .stereo = false }, 0, 0, 0, 1, true);
|
||||
|
||||
for (int i = 0; i < MAX_STREAMS; i++) {
|
||||
state.buffers[i] = lovrBufferCreate(bufferCount[i] * bufferStride[i], NULL, bufferType[i], USAGE_STREAM, false);
|
||||
}
|
||||
|
@ -281,8 +287,15 @@ void lovrGraphicsSetCamera(Camera* camera, bool clear) {
|
|||
mat4_identity(state.camera.viewMatrix[1]);
|
||||
mat4_perspective(state.camera.projection[0], .01f, 100.f, 67.f * (float) M_PI / 180.f, (float) state.width / state.height);
|
||||
mat4_perspective(state.camera.projection[1], .01f, 100.f, 67.f * (float) M_PI / 180.f, (float) state.width / state.height);
|
||||
state.camera.canvas = state.defaultCanvas;
|
||||
state.camera.canvas->flags.stereo = false;
|
||||
} else {
|
||||
state.camera = *camera;
|
||||
|
||||
if (!state.camera.canvas) {
|
||||
state.camera.canvas = state.defaultCanvas;
|
||||
state.camera.canvas->flags.stereo = camera->stereo;
|
||||
}
|
||||
}
|
||||
|
||||
if (clear) {
|
||||
|
@ -724,10 +737,7 @@ void lovrGraphicsFlush() {
|
|||
.drawMode = batch->drawMode,
|
||||
.instances = instances,
|
||||
.rangeStart = rangeStart,
|
||||
.rangeCount = rangeCount,
|
||||
.width = batch->canvas ? lovrCanvasGetWidth(batch->canvas) : state.width,
|
||||
.height = batch->canvas ? lovrCanvasGetHeight(batch->canvas) : state.height,
|
||||
.stereo = batch->canvas ? lovrCanvasIsStereo(batch->canvas) : state.camera.stereo
|
||||
.rangeCount = rangeCount
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,9 +215,6 @@ typedef struct {
|
|||
uint32_t instances;
|
||||
uint32_t rangeStart;
|
||||
uint32_t rangeCount;
|
||||
uint32_t width : 15;
|
||||
uint32_t height : 15;
|
||||
bool stereo : 1;
|
||||
} DrawCommand;
|
||||
|
||||
void lovrGpuInit(getProcAddressProc getProcAddress);
|
||||
|
|
|
@ -614,14 +614,14 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int baseDivisor) {
|
|||
}
|
||||
|
||||
static void lovrGpuBindCanvas(Canvas* canvas, bool willDraw) {
|
||||
if (canvas) {
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
canvas->needsResolve = willDraw;
|
||||
} else {
|
||||
lovrGpuBindFramebuffer(0);
|
||||
lovrGpuBindFramebuffer(canvas->framebuffer);
|
||||
|
||||
if (canvas->framebuffer == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
canvas->needsResolve = willDraw;
|
||||
|
||||
if (!canvas->needsAttach) {
|
||||
return;
|
||||
}
|
||||
|
@ -1135,7 +1135,7 @@ void lovrGpuDiscard(Canvas* canvas, bool color, bool depth, bool stencil) {
|
|||
int count = 0;
|
||||
|
||||
if (color) {
|
||||
int n = canvas ? canvas->attachmentCount : 1;
|
||||
int n = MAX(canvas->attachmentCount, 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
attachments[count++] = GL_COLOR_ATTACHMENT0 + i;
|
||||
}
|
||||
|
@ -1155,14 +1155,14 @@ void lovrGpuDiscard(Canvas* canvas, bool color, bool depth, bool stencil) {
|
|||
|
||||
void lovrGpuDraw(DrawCommand* draw) {
|
||||
lovrAssert(state.singlepass != MULTIVIEW || draw->shader->multiview == draw->canvas->flags.stereo, "Shader and Canvas multiview settings must match!");
|
||||
uint32_t viewportCount = (draw->stereo && state.singlepass != MULTIVIEW) ? 2 : 1;
|
||||
uint32_t viewportCount = (draw->canvas->flags.stereo && state.singlepass != MULTIVIEW) ? 2 : 1;
|
||||
uint32_t drawCount = state.singlepass == NONE ? viewportCount : 1;
|
||||
uint32_t instanceMultiplier = state.singlepass == INSTANCED_STEREO ? viewportCount : 1;
|
||||
uint32_t viewportsPerDraw = instanceMultiplier;
|
||||
uint32_t instances = MAX(draw->instances, 1) * instanceMultiplier;
|
||||
|
||||
float w = state.singlepass == MULTIVIEW ? draw->width : draw->width / (float) viewportCount;
|
||||
float h = draw->height;
|
||||
float w = state.singlepass == MULTIVIEW ? draw->canvas->width : draw->canvas->width / (float) viewportCount;
|
||||
float h = draw->canvas->height;
|
||||
float viewports[2][4] = { { 0.f, 0.f, w, h }, { w, 0.f, w, h } };
|
||||
lovrShaderSetInts(draw->shader, "lovrViewportCount", &(int) { viewportCount }, 0, 1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue