mirror of https://github.com/bjornbytes/lovr.git
Refactor layers/displays;
This commit is contained in:
parent
221015677f
commit
2def650abd
|
@ -58,14 +58,14 @@ void lovrGraphicsReset() {
|
|||
int w = lovrGraphicsGetWidth();
|
||||
int h = lovrGraphicsGetHeight();
|
||||
state.transform = 0;
|
||||
state.display = 0;
|
||||
state.layer = 0;
|
||||
state.defaultShader = SHADER_DEFAULT;
|
||||
mat4_perspective(state.displays[state.display].projections, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
mat4_perspective(state.displays[state.display].projections + 16, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
state.displays[state.display].viewport[0] = 0;
|
||||
state.displays[state.display].viewport[1] = 0;
|
||||
state.displays[state.display].viewport[2] = w;
|
||||
state.displays[state.display].viewport[3] = h;
|
||||
mat4_perspective(state.layers[state.layer].projections, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
mat4_perspective(state.layers[state.layer].projections + 16, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
state.layers[state.layer].viewport[0] = 0;
|
||||
state.layers[state.layer].viewport[1] = 0;
|
||||
state.layers[state.layer].viewport[2] = w;
|
||||
state.layers[state.layer].viewport[3] = h;
|
||||
lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1. });
|
||||
lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY);
|
||||
lovrGraphicsSetColor((Color) { 1., 1., 1., 1. });
|
||||
|
@ -118,7 +118,7 @@ void lovrGraphicsPrepare(Material* material, float* pose) {
|
|||
mat4 model = state.transforms[state.transform][MATRIX_MODEL];
|
||||
lovrShaderSetMatrix(shader, "lovrModel", model, 16);
|
||||
|
||||
float* views = state.displays[state.display].views;
|
||||
float* views = state.layers[state.layer].views;
|
||||
float transforms[32];
|
||||
mat4_multiply(mat4_set(transforms + 0, views + 0), model);
|
||||
mat4_multiply(mat4_set(transforms + 16, views + 16), model);
|
||||
|
@ -371,8 +371,9 @@ void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
|
|||
}
|
||||
|
||||
if (count == 0) {
|
||||
lovrGraphicsBindFramebuffer(state.displays[state.display].framebuffer);
|
||||
int* viewport = state.displays[state.display].viewport;
|
||||
Layer layer = state.layers[state.layer];
|
||||
int* viewport = layer.viewport;
|
||||
lovrGraphicsBindFramebuffer(layer.canvas ? layer.canvas->texture.id : 0);
|
||||
lovrGraphicsSetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
} else {
|
||||
memcpy(state.canvas, canvas, count * sizeof(Canvas*));
|
||||
|
@ -1143,41 +1144,32 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
|
|||
}
|
||||
|
||||
// Internal State
|
||||
void lovrGraphicsPushDisplay(int framebuffer, float* projections, float* views, int* viewport) {
|
||||
if (++state.display >= MAX_DISPLAYS) {
|
||||
lovrThrow("Display overflow");
|
||||
void lovrGraphicsPushLayer(Layer layer) {
|
||||
if (++state.layer >= MAX_LAYERS) {
|
||||
lovrThrow("Layer overflow");
|
||||
}
|
||||
|
||||
state.displays[state.display].framebuffer = framebuffer;
|
||||
memcpy(state.displays[state.display].projections, projections, 32 * sizeof(float));
|
||||
memcpy(state.displays[state.display].views, views, 32 * sizeof(float));
|
||||
memcpy(state.displays[state.display].viewport, viewport, 4 * sizeof(int));
|
||||
|
||||
struct {
|
||||
float projections[32];
|
||||
float views[32];
|
||||
} cameraBlock;
|
||||
|
||||
memcpy(cameraBlock.projections, projections, 32 * sizeof(float));
|
||||
memcpy(cameraBlock.views, views, 32 * sizeof(float));
|
||||
memcpy(&state.layers[state.layer], &layer, sizeof(Layer));
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.cameraUBO);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 16 * sizeof(float), &cameraBlock);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 16 * sizeof(float), &layer);
|
||||
|
||||
if (state.canvasCount == 0) {
|
||||
lovrGraphicsBindFramebuffer(framebuffer);
|
||||
int* viewport = layer.viewport;
|
||||
lovrGraphicsBindFramebuffer(layer.canvas ? layer.canvas->texture.id : 0);
|
||||
lovrGraphicsSetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void lovrGraphicsPopDisplay() {
|
||||
if (--state.display < 0) {
|
||||
lovrThrow("Display underflow");
|
||||
void lovrGraphicsPopLayer() {
|
||||
if (--state.layer < 0) {
|
||||
lovrThrow("Layer underflow");
|
||||
}
|
||||
|
||||
if (state.canvasCount == 0) {
|
||||
lovrGraphicsBindFramebuffer(state.displays[state.display].framebuffer);
|
||||
int* viewport = state.displays[state.display].viewport;
|
||||
Layer layer = state.layers[state.layer];
|
||||
int* viewport = layer.viewport;
|
||||
lovrGraphicsBindFramebuffer(layer.canvas ? layer.canvas->texture.id : 0);
|
||||
lovrGraphicsSetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#pragma once
|
||||
|
||||
#define MAX_CANVASES 4
|
||||
#define MAX_DISPLAYS 4
|
||||
#define MAX_LAYERS 4
|
||||
#define MAX_TRANSFORMS 60
|
||||
#define INTERNAL_TRANSFORMS 4
|
||||
#define DEFAULT_SHADER_COUNT 4
|
||||
|
@ -76,11 +76,11 @@ typedef enum {
|
|||
} MatrixType;
|
||||
|
||||
typedef struct {
|
||||
int framebuffer;
|
||||
float projections[32];
|
||||
float views[32];
|
||||
Canvas* canvas;
|
||||
int viewport[4];
|
||||
} Display;
|
||||
} Layer;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
|
@ -127,8 +127,8 @@ typedef struct {
|
|||
bool wireframe;
|
||||
Mesh* mesh;
|
||||
uint32_t cameraUBO;
|
||||
Display displays[MAX_DISPLAYS];
|
||||
int display;
|
||||
Layer layers[MAX_LAYERS];
|
||||
int layer;
|
||||
Texture* textures[MAX_TEXTURES];
|
||||
bool stencilEnabled;
|
||||
bool stencilWriting;
|
||||
|
@ -210,8 +210,8 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
|
|||
|
||||
// Internal State
|
||||
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
|
||||
void lovrGraphicsPushDisplay(int framebuffer, float* projections, float* views, int* viewport);
|
||||
void lovrGraphicsPopDisplay();
|
||||
void lovrGraphicsPushLayer(Layer layer);
|
||||
void lovrGraphicsPopLayer();
|
||||
void lovrGraphicsSetViewport(int x, int y, int w, int h);
|
||||
void lovrGraphicsBindFramebuffer(int framebuffer);
|
||||
Texture* lovrGraphicsGetTexture(int slot);
|
||||
|
|
|
@ -313,22 +313,21 @@ static void fakeRenderTo(headsetRenderCallback callback, void* userdata) {
|
|||
int width, height;
|
||||
fakeGetDisplayDimensions(&width, &height);
|
||||
|
||||
float projections[32];
|
||||
mat4_perspective(projections, state.clipNear, state.clipFar, 67 * M_PI / 180., (float) width / height / 2.);
|
||||
mat4_set(projections + 16, projections);
|
||||
Layer layer = { .canvas = NULL, .viewport = { 0, 0, width, height } };
|
||||
|
||||
float views[32];
|
||||
mat4_identity(views);
|
||||
mat4_translate(views, 0, state.offset, 0);
|
||||
mat4_multiply(views, state.transform);
|
||||
mat4_invert(views);
|
||||
mat4_set(views + 16, views);
|
||||
mat4_perspective(layer.projections, state.clipNear, state.clipFar, 67 * M_PI / 180., (float) width / height / 2.);
|
||||
mat4_set(layer.projections + 16, layer.projections);
|
||||
|
||||
int viewport[4] = { 0, 0, width, height };
|
||||
lovrGraphicsPushDisplay(0, projections, views, viewport);
|
||||
mat4_identity(layer.views);
|
||||
mat4_translate(layer.views, 0, state.offset, 0);
|
||||
mat4_multiply(layer.views, state.transform);
|
||||
mat4_invert(layer.views);
|
||||
mat4_set(layer.views + 16, layer.views);
|
||||
|
||||
lovrGraphicsPushLayer(layer);
|
||||
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
callback(EYE_LEFT, userdata);
|
||||
lovrGraphicsPopDisplay();
|
||||
lovrGraphicsPopLayer();
|
||||
}
|
||||
|
||||
static void fakeUpdate(float dt) {
|
||||
|
|
|
@ -247,7 +247,7 @@ static void ensureCanvas() {
|
|||
int msaa = 0;
|
||||
glGetIntegerv(GL_SAMPLES, &msaa);
|
||||
state.system->GetRecommendedRenderTargetSize(&state.renderWidth, &state.renderHeight);
|
||||
state.canvas = lovrCanvasCreate(state.renderWidth, state.renderHeight, FORMAT_RGB, msaa, true, true);
|
||||
state.canvas = lovrCanvasCreate(state.renderWidth * 2, state.renderHeight, FORMAT_RGB, msaa, true, true);
|
||||
}
|
||||
|
||||
static bool openvrInit(float offset) {
|
||||
|
@ -311,7 +311,7 @@ static bool openvrInit(float offset) {
|
|||
state.vsyncToPhotons = state.system->GetFloatTrackedDeviceProperty(state.headsetIndex, ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float, NULL);
|
||||
state.isRendering = false;
|
||||
state.isMirrored = true;
|
||||
state.offset = offset;
|
||||
state.offset = lovrHeadsetGetOriginType() == ORIGIN_HEAD ? offset : 0.;
|
||||
state.canvas = NULL;
|
||||
state.clipNear = 0.1f;
|
||||
state.clipFar = 30.f;
|
||||
|
@ -672,55 +672,58 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
|
|||
|
||||
static void openvrRenderTo(headsetRenderCallback callback, void* userdata) {
|
||||
ensureCanvas();
|
||||
|
||||
float head[16], transform[16], projection[16];
|
||||
float (*matrix)[4];
|
||||
|
||||
state.isRendering = true;
|
||||
state.compositor->WaitGetPoses(state.renderPoses, 16, NULL, 0);
|
||||
|
||||
// Head transform
|
||||
// Layer setup
|
||||
Layer layer = { .canvas = state.canvas, .viewport = { 0, 0, state.renderWidth * 2, state.renderHeight } };
|
||||
float eye[16];
|
||||
float head[16];
|
||||
float (*matrix)[4];
|
||||
matrix = state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m;
|
||||
mat4_invert(mat4_fromMat34(head, matrix));
|
||||
mat4_fromMat34(head, matrix);
|
||||
|
||||
for (HeadsetEye eye = EYE_LEFT; eye <= EYE_RIGHT; eye++) {
|
||||
|
||||
// Eye transform
|
||||
EVREye vrEye = (eye == EYE_LEFT) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
||||
matrix = state.system->GetEyeToHeadTransform(vrEye).m;
|
||||
mat4_invert(mat4_fromMat34(transform, matrix));
|
||||
mat4_multiply(transform, head);
|
||||
for (HeadsetEye i = EYE_LEFT; i <= EYE_RIGHT; i++) {
|
||||
EVREye vrEye = (i == EYE_LEFT) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
||||
|
||||
// Projection
|
||||
matrix = state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m;
|
||||
mat4 projection = layer.projections + 16 * i;
|
||||
mat4_fromMat44(projection, matrix);
|
||||
|
||||
// Render
|
||||
//int viewport[4] = { 0, 0, state.canvas->texture.width, state.canvas->texture.height };
|
||||
//lovrGraphicsPushDisplay(state.canvas->framebuffer, projection, viewport);
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsMatrixTransform(MATRIX_VIEW, transform);
|
||||
lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
callback(eye, userdata);
|
||||
lovrGraphicsPop();
|
||||
//lovrGraphicsPopDisplay();
|
||||
|
||||
// OpenVR changes the OpenGL texture binding, so we reset it after rendering
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
Texture* oldTexture = lovrGraphicsGetTexture(0);
|
||||
|
||||
// Submit
|
||||
uintptr_t texture = (uintptr_t) state.canvas->texture.id;
|
||||
ETextureType textureType = ETextureType_TextureType_OpenGL;
|
||||
EColorSpace colorSpace = lovrGraphicsIsGammaCorrect() ? EColorSpace_ColorSpace_Linear : EColorSpace_ColorSpace_Gamma;
|
||||
Texture_t eyeTexture = { (void*) texture, textureType, colorSpace };
|
||||
EVRSubmitFlags flags = EVRSubmitFlags_Submit_Default;
|
||||
state.compositor->Submit(vrEye, &eyeTexture, NULL, flags);
|
||||
|
||||
// Reset to the correct texture
|
||||
glBindTexture(GL_TEXTURE_2D, oldTexture->id);
|
||||
// View
|
||||
matrix = state.system->GetEyeToHeadTransform(vrEye).m;
|
||||
mat4_fromMat34(eye, matrix);
|
||||
mat4 view = layer.views + 16 * i;
|
||||
mat4_identity(view);
|
||||
mat4_translate(view, 0, state.offset, 0);
|
||||
mat4_multiply(view, head);
|
||||
mat4_multiply(view, eye);
|
||||
mat4_invert(view);
|
||||
}
|
||||
|
||||
// Render
|
||||
lovrGraphicsPushLayer(layer);
|
||||
lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
callback(EYE_LEFT, userdata);
|
||||
lovrGraphicsPopLayer();
|
||||
|
||||
// OpenVR changes the OpenGL texture binding, so we reset it after rendering
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
Texture* oldTexture = lovrGraphicsGetTexture(0);
|
||||
|
||||
// Submit
|
||||
uintptr_t texture = (uintptr_t) state.canvas->texture.id;
|
||||
EColorSpace colorSpace = lovrGraphicsIsGammaCorrect() ? EColorSpace_ColorSpace_Linear : EColorSpace_ColorSpace_Gamma;
|
||||
Texture_t eyeTexture = { (void*) texture, ETextureType_TextureType_OpenGL, colorSpace };
|
||||
VRTextureBounds_t left = { 0, 0, state.renderWidth, state.renderHeight };
|
||||
VRTextureBounds_t right = { state.renderWidth, 0, state.renderWidth, state.renderHeight };
|
||||
state.compositor->Submit(EVREye_Eye_Left, &eyeTexture, &left, EVRSubmitFlags_Submit_Default);
|
||||
state.compositor->Submit(EVREye_Eye_Right, &eyeTexture, &right, EVRSubmitFlags_Submit_Default);
|
||||
|
||||
// Reset to the correct texture
|
||||
glBindTexture(GL_TEXTURE_2D, oldTexture->id);
|
||||
|
||||
state.isRendering = false;
|
||||
|
||||
if (state.isMirrored) {
|
||||
|
|
Loading…
Reference in New Issue