mirror of https://github.com/bjornbytes/lovr.git
Opaque Canvas;
This commit is contained in:
parent
52d4f7e520
commit
d034e8c01b
|
@ -1,67 +0,0 @@
|
|||
#include "graphics/canvas.h"
|
||||
#include "graphics/graphics.h"
|
||||
#include "core/ref.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
const Attachment* lovrCanvasGetAttachments(Canvas* canvas, uint32_t* count) {
|
||||
if (count) *count = canvas->attachmentCount;
|
||||
return canvas->attachments;
|
||||
}
|
||||
|
||||
void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, uint32_t count) {
|
||||
lovrAssert(count > 0, "A Canvas must have at least one attached Texture");
|
||||
lovrAssert(count <= MAX_CANVAS_ATTACHMENTS, "Only %d textures can be attached to a Canvas, got %d\n", MAX_CANVAS_ATTACHMENTS, count);
|
||||
|
||||
if (!canvas->needsAttach && count == canvas->attachmentCount && !memcmp(canvas->attachments, attachments, count * sizeof(Attachment))) {
|
||||
return;
|
||||
}
|
||||
|
||||
lovrGraphicsFlushCanvas(canvas);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Texture* texture = attachments[i].texture;
|
||||
uint32_t slice = attachments[i].slice;
|
||||
uint32_t level = attachments[i].level;
|
||||
uint32_t width = lovrTextureGetWidth(texture, level);
|
||||
uint32_t height = lovrTextureGetHeight(texture, level);
|
||||
uint32_t depth = lovrTextureGetDepth(texture, level);
|
||||
uint32_t mipmaps = lovrTextureGetMipmapCount(texture);
|
||||
bool hasDepthBuffer = canvas->flags.depth.enabled;
|
||||
lovrAssert(slice < depth, "Invalid attachment slice (Texture has %d, got %d)", depth, slice + 1);
|
||||
lovrAssert(level < mipmaps, "Invalid attachment mipmap level (Texture has %d, got %d)", mipmaps, level + 1);
|
||||
lovrAssert(!hasDepthBuffer || width == canvas->width, "Texture width of %d does not match Canvas width (%d)", width, canvas->width);
|
||||
lovrAssert(!hasDepthBuffer || height == canvas->height, "Texture height of %d does not match Canvas height (%d)", height, canvas->height);
|
||||
#ifndef __ANDROID__ // On multiview canvases, the multisample settings can be different
|
||||
lovrAssert(lovrTextureGetMSAA(texture) == canvas->flags.msaa, "Texture MSAA does not match Canvas MSAA");
|
||||
#endif
|
||||
lovrRetain(texture);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < canvas->attachmentCount; i++) {
|
||||
lovrRelease(Texture, canvas->attachments[i].texture);
|
||||
}
|
||||
|
||||
memcpy(canvas->attachments, attachments, count * sizeof(Attachment));
|
||||
canvas->attachmentCount = count;
|
||||
canvas->needsAttach = true;
|
||||
}
|
||||
|
||||
bool lovrCanvasIsStereo(Canvas* canvas) {
|
||||
return canvas->flags.stereo;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetWidth(Canvas* canvas) {
|
||||
return canvas->width;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetHeight(Canvas* canvas) {
|
||||
return canvas->height;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetMSAA(Canvas* canvas) {
|
||||
return canvas->flags.msaa;
|
||||
}
|
||||
|
||||
Texture* lovrCanvasGetDepthTexture(Canvas* canvas) {
|
||||
return canvas->depth.texture;
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
#include "graphics/texture.h"
|
||||
#include "graphics/opengl.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -25,29 +24,19 @@ typedef struct {
|
|||
bool mipmaps;
|
||||
} CanvasFlags;
|
||||
|
||||
typedef struct Canvas {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
CanvasFlags flags;
|
||||
Attachment attachments[MAX_CANVAS_ATTACHMENTS];
|
||||
Attachment depth;
|
||||
uint32_t attachmentCount;
|
||||
bool needsAttach;
|
||||
bool needsResolve;
|
||||
GPU_CANVAS_FIELDS
|
||||
} Canvas;
|
||||
|
||||
Canvas* lovrCanvasInit(Canvas* canvas, uint32_t width, uint32_t height, CanvasFlags flags);
|
||||
Canvas* lovrCanvasInitFromHandle(Canvas* canvas, uint32_t width, uint32_t height, CanvasFlags flags, uint32_t framebuffer, uint32_t depthBuffer, uint32_t resolveBuffer, uint32_t attachmentCount, bool immortal);
|
||||
#define lovrCanvasCreate(...) lovrCanvasInit(lovrAlloc(Canvas), __VA_ARGS__)
|
||||
#define lovrCanvasCreateFromHandle(...) lovrCanvasInitFromHandle(lovrAlloc(Canvas), __VA_ARGS__)
|
||||
typedef struct Canvas Canvas;
|
||||
Canvas* lovrCanvasCreate(uint32_t width, uint32_t height, CanvasFlags flags);
|
||||
Canvas* lovrCanvasCreateFromHandle(uint32_t width, uint32_t height, CanvasFlags flags, uint32_t framebuffer, uint32_t depthBuffer, uint32_t resolveBuffer, uint32_t attachmentCount, bool immortal);
|
||||
void lovrCanvasDestroy(void* ref);
|
||||
const Attachment* lovrCanvasGetAttachments(Canvas* canvas, uint32_t* count);
|
||||
void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, uint32_t count);
|
||||
void lovrCanvasResolve(Canvas* canvas);
|
||||
bool lovrCanvasIsStereo(Canvas* canvas);
|
||||
void lovrCanvasSetStereo(Canvas* canvas, bool stereo);
|
||||
uint32_t lovrCanvasGetWidth(Canvas* canvas);
|
||||
uint32_t lovrCanvasGetHeight(Canvas* canvas);
|
||||
void lovrCanvasSetWidth(Canvas* canvas, uint32_t width);
|
||||
void lovrCanvasSetHeight(Canvas* canvas, uint32_t height);
|
||||
uint32_t lovrCanvasGetMSAA(Canvas* canvas);
|
||||
struct Texture* lovrCanvasGetDepthTexture(Canvas* canvas);
|
||||
struct TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index);
|
||||
|
|
|
@ -168,8 +168,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;
|
||||
lovrCanvasSetWidth(state.defaultCanvas, width);
|
||||
lovrCanvasSetHeight(state.defaultCanvas, height);
|
||||
}
|
||||
|
||||
static void* lovrGraphicsMapBuffer(StreamType type, uint32_t count) {
|
||||
|
@ -303,13 +303,13 @@ void lovrGraphicsSetCamera(Camera* camera, bool clear) {
|
|||
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;
|
||||
lovrCanvasSetStereo(state.camera.canvas, false);
|
||||
} else {
|
||||
state.camera = *camera;
|
||||
|
||||
if (!state.camera.canvas) {
|
||||
state.camera.canvas = state.defaultCanvas;
|
||||
state.camera.canvas->flags.stereo = camera->stereo;
|
||||
lovrCanvasSetStereo(state.camera.canvas, camera->stereo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,21 @@ struct Texture {
|
|||
uint8_t incoherent;
|
||||
};
|
||||
|
||||
struct Canvas {
|
||||
uint32_t framebuffer;
|
||||
uint32_t resolveBuffer;
|
||||
uint32_t depthBuffer;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
CanvasFlags flags;
|
||||
Attachment attachments[MAX_CANVAS_ATTACHMENTS];
|
||||
Attachment depth;
|
||||
uint32_t attachmentCount;
|
||||
bool needsAttach;
|
||||
bool needsResolve;
|
||||
bool immortal;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
BARRIER_BLOCK,
|
||||
BARRIER_UNIFORM_TEXTURE,
|
||||
|
@ -1765,7 +1780,8 @@ void lovrTextureSetWrap(Texture* texture, TextureWrap wrap) {
|
|||
|
||||
// Canvas
|
||||
|
||||
Canvas* lovrCanvasInit(Canvas* canvas, uint32_t width, uint32_t height, CanvasFlags flags) {
|
||||
Canvas* lovrCanvasCreate(uint32_t width, uint32_t height, CanvasFlags flags) {
|
||||
Canvas* canvas = lovrAlloc(Canvas);
|
||||
if (flags.stereo && state.singlepass != MULTIVIEW) {
|
||||
width *= 2;
|
||||
}
|
||||
|
@ -1809,7 +1825,8 @@ Canvas* lovrCanvasInit(Canvas* canvas, uint32_t width, uint32_t height, CanvasFl
|
|||
return canvas;
|
||||
}
|
||||
|
||||
Canvas* lovrCanvasInitFromHandle(Canvas* canvas, uint32_t width, uint32_t height, CanvasFlags flags, uint32_t framebuffer, uint32_t depthBuffer, uint32_t resolveBuffer, uint32_t attachmentCount, bool immortal) {
|
||||
Canvas* lovrCanvasCreateFromHandle(uint32_t width, uint32_t height, CanvasFlags flags, uint32_t framebuffer, uint32_t depthBuffer, uint32_t resolveBuffer, uint32_t attachmentCount, bool immortal) {
|
||||
Canvas* canvas = lovrAlloc(Canvas);
|
||||
canvas->framebuffer = framebuffer;
|
||||
canvas->depthBuffer = depthBuffer;
|
||||
canvas->resolveBuffer = resolveBuffer;
|
||||
|
@ -1904,6 +1921,81 @@ TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index) {
|
|||
return textureData;
|
||||
}
|
||||
|
||||
const Attachment* lovrCanvasGetAttachments(Canvas* canvas, uint32_t* count) {
|
||||
if (count) *count = canvas->attachmentCount;
|
||||
return canvas->attachments;
|
||||
}
|
||||
|
||||
void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, uint32_t count) {
|
||||
lovrAssert(count > 0, "A Canvas must have at least one attached Texture");
|
||||
lovrAssert(count <= MAX_CANVAS_ATTACHMENTS, "Only %d textures can be attached to a Canvas, got %d\n", MAX_CANVAS_ATTACHMENTS, count);
|
||||
|
||||
if (!canvas->needsAttach && count == canvas->attachmentCount && !memcmp(canvas->attachments, attachments, count * sizeof(Attachment))) {
|
||||
return;
|
||||
}
|
||||
|
||||
lovrGraphicsFlushCanvas(canvas);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Texture* texture = attachments[i].texture;
|
||||
uint32_t slice = attachments[i].slice;
|
||||
uint32_t level = attachments[i].level;
|
||||
uint32_t width = lovrTextureGetWidth(texture, level);
|
||||
uint32_t height = lovrTextureGetHeight(texture, level);
|
||||
uint32_t depth = lovrTextureGetDepth(texture, level);
|
||||
uint32_t mipmaps = lovrTextureGetMipmapCount(texture);
|
||||
bool hasDepthBuffer = canvas->flags.depth.enabled;
|
||||
lovrAssert(slice < depth, "Invalid attachment slice (Texture has %d, got %d)", depth, slice + 1);
|
||||
lovrAssert(level < mipmaps, "Invalid attachment mipmap level (Texture has %d, got %d)", mipmaps, level + 1);
|
||||
lovrAssert(!hasDepthBuffer || width == canvas->width, "Texture width of %d does not match Canvas width (%d)", width, canvas->width);
|
||||
lovrAssert(!hasDepthBuffer || height == canvas->height, "Texture height of %d does not match Canvas height (%d)", height, canvas->height);
|
||||
#ifndef __ANDROID__ // On multiview canvases, the multisample settings can be different
|
||||
lovrAssert(lovrTextureGetMSAA(texture) == canvas->flags.msaa, "Texture MSAA does not match Canvas MSAA");
|
||||
#endif
|
||||
lovrRetain(texture);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < canvas->attachmentCount; i++) {
|
||||
lovrRelease(Texture, canvas->attachments[i].texture);
|
||||
}
|
||||
|
||||
memcpy(canvas->attachments, attachments, count * sizeof(Attachment));
|
||||
canvas->attachmentCount = count;
|
||||
canvas->needsAttach = true;
|
||||
}
|
||||
|
||||
bool lovrCanvasIsStereo(Canvas* canvas) {
|
||||
return canvas->flags.stereo;
|
||||
}
|
||||
|
||||
void lovrCanvasSetStereo(Canvas* canvas, bool stereo) {
|
||||
canvas->flags.stereo = stereo;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetWidth(Canvas* canvas) {
|
||||
return canvas->width;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetHeight(Canvas* canvas) {
|
||||
return canvas->height;
|
||||
}
|
||||
|
||||
void lovrCanvasSetWidth(Canvas* canvas, uint32_t width) {
|
||||
canvas->width = width;
|
||||
}
|
||||
|
||||
void lovrCanvasSetHeight(Canvas* canvas, uint32_t height) {
|
||||
canvas->height = height;
|
||||
}
|
||||
|
||||
uint32_t lovrCanvasGetMSAA(Canvas* canvas) {
|
||||
return canvas->flags.msaa;
|
||||
}
|
||||
|
||||
Texture* lovrCanvasGetDepthTexture(Canvas* canvas) {
|
||||
return canvas->depth.texture;
|
||||
}
|
||||
|
||||
// Buffer
|
||||
|
||||
Buffer* lovrBufferCreate(size_t size, void* data, BufferType type, BufferUsage usage, bool readable) {
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define GPU_CANVAS_FIELDS \
|
||||
bool immortal; \
|
||||
uint32_t framebuffer; \
|
||||
uint32_t resolveBuffer; \
|
||||
uint32_t depthBuffer;
|
||||
|
||||
#define GPU_MESH_FIELDS \
|
||||
uint32_t vao; \
|
||||
uint32_t ibo;
|
||||
|
|
Loading…
Reference in New Issue