From 6ff72923337c81bd5bff380642b30a7b937ee65b Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 3 Jun 2018 17:18:42 -0700 Subject: [PATCH] Mostly remove instanced stereo rendering; --- src/api/graphics.c | 6 +-- src/api/headset.c | 2 + src/graphics/canvas.h | 1 - src/graphics/graphics.c | 117 +++++++++++++++++++++------------------- src/graphics/graphics.h | 16 +++--- src/graphics/mesh.c | 4 +- src/graphics/mesh.h | 2 +- src/graphics/shader.c | 4 -- src/graphics/shader.h | 1 - src/headset/fake.c | 41 +++++--------- src/headset/openvr.c | 65 +++++++++------------- src/headset/webvr.c | 35 +++--------- src/resources/shaders.c | 39 +++----------- 13 files changed, 128 insertions(+), 205 deletions(-) diff --git a/src/api/graphics.c b/src/api/graphics.c index ffb2ca0b..747f1ab7 100644 --- a/src/api/graphics.c +++ b/src/api/graphics.c @@ -835,7 +835,7 @@ int l_lovrGraphicsNewCanvas(lua_State* L) { luaL_argcheck(L, height > 0, 2, "height must be positive"); TextureFormat format = FORMAT_RGBA; - CanvasFlags flags = { .msaa = 0, .depth = true, .stencil = false, .stereo = false, .mipmaps = true }; + CanvasFlags flags = { .msaa = 0, .depth = true, .stencil = false, .mipmaps = true }; if (lua_istable(L, 3)) { lua_getfield(L, 3, "format"); @@ -854,10 +854,6 @@ int l_lovrGraphicsNewCanvas(lua_State* L) { flags.stencil = lua_toboolean(L, -1); lua_pop(L, 1); - lua_getfield(L, 3, "stereo"); - flags.stereo = lua_toboolean(L, -1); - lua_pop(L, 1); - lua_getfield(L, 3, "mipmaps"); flags.mipmaps = lua_toboolean(L, -1); lua_pop(L, 1); diff --git a/src/api/headset.c b/src/api/headset.c index 16ba9940..99c6706d 100644 --- a/src/api/headset.c +++ b/src/api/headset.c @@ -21,6 +21,8 @@ static void renderHelper(void* userdata) { lua_State* L = renderData->L; #ifdef EMSCRIPTEN lua_rawgeti(L, LUA_REGISTRYINDEX, renderData->ref); +#else + lua_pushvalue(L, -1); #endif lua_call(L, 0, 0); } diff --git a/src/graphics/canvas.h b/src/graphics/canvas.h index da694ebe..d8407b8a 100644 --- a/src/graphics/canvas.h +++ b/src/graphics/canvas.h @@ -9,7 +9,6 @@ typedef struct { int msaa; bool depth; bool stencil; - bool stereo; bool mipmaps; } CanvasFlags; diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 7a04333d..0b041517 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -54,7 +54,6 @@ void lovrGraphicsDestroy() { lovrRelease(state.defaultFont); lovrRelease(state.defaultTexture); lovrRelease(state.mesh); - glDeleteBuffers(1, &state.cameraBuffer); memset(&state, 0, sizeof(GraphicsState)); } @@ -63,10 +62,8 @@ void lovrGraphicsReset() { int h = lovrGraphicsGetHeight(); state.transform = 0; state.layer = 0; - mat4_perspective(state.layers[state.layer].projections, .01f, 100.f, 67 * M_PI / 180., (float) w / h); - mat4_perspective(state.layers[state.layer].projections + 16, .01f, 100.f, 67 * M_PI / 180., (float) w / h); - mat4_identity(state.layers[state.layer].views); - mat4_identity(state.layers[state.layer].views + 16); + mat4_perspective(state.layers[state.layer].projection, .01f, 100.f, 67 * M_PI / 180., (float) w / h); + mat4_identity(state.layers[state.layer].view); lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1. }); lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY); lovrGraphicsSetColor((Color) { 1., 1., 1., 1. }); @@ -180,10 +177,6 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3); vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2); state.mesh = lovrMeshCreate(64, format, MESH_TRIANGLES, MESH_STREAM); - glGenBuffers(1, &state.cameraBuffer); - glBindBuffer(GL_UNIFORM_BUFFER, state.cameraBuffer); - glBufferData(GL_UNIFORM_BUFFER, 4 * 16 * sizeof(float), NULL, GL_DYNAMIC_DRAW); - glBindBufferBase(GL_UNIFORM_BUFFER, LOVR_SHADER_BLOCK_CAMERA, state.cameraBuffer); lovrGraphicsReset(); state.initialized = true; } @@ -1006,69 +999,66 @@ void lovrGraphicsFill(Texture* texture) { // Internal void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, int instances) { - Shader* shader = state.shader ? state.shader : state.defaultShaders[defaultShader]; - - if (!shader) { - shader = state.defaultShaders[defaultShader] = lovrShaderCreateDefault(defaultShader); - } // Layer Layer layer = state.layers[state.layer]; Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas; lovrGraphicsBindFramebuffer(canvas ? canvas->framebuffer : 0); - uint32_t width = canvas ? canvas->texture.width : lovrGraphicsGetWidth(); - uint32_t height = canvas ? canvas->texture.height : lovrGraphicsGetHeight(); - uint32_t viewport[4] = { 0, 0, width, height }; + + uint32_t viewport[4]; + if (state.canvasCount > 0) { + viewport[0] = 0; + viewport[1] = 0; + viewport[2] = state.canvas[0]->texture.width; + viewport[3] = state.canvas[0]->texture.height; + } else { + viewport[0] = layer.viewport[0]; + viewport[1] = layer.viewport[1]; + viewport[2] = layer.viewport[2]; + viewport[3] = layer.viewport[3]; + } if (memcmp(state.viewport, viewport, 4 * sizeof(uint32_t))) { memcpy(state.viewport, viewport, 4 * sizeof(uint32_t)); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); } - if (memcmp(state.cameraData, &layer, 4 * 16 * sizeof(float))) { - memcpy(state.cameraData, &layer, 4 * 16 * sizeof(float)); - glBindBuffer(GL_UNIFORM_BUFFER, state.cameraBuffer); - glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 16 * sizeof(float), &layer); - } - // Transforms if (transform) { lovrGraphicsPush(); lovrGraphicsMatrixTransform(transform); } + Shader* shader = state.shader ? state.shader : state.defaultShaders[defaultShader]; + + if (!shader) { + shader = state.defaultShaders[defaultShader] = lovrShaderCreateDefault(defaultShader); + } + + lovrShaderSetMatrix(shader, "lovrProjection", layer.projection, 16); + lovrShaderSetMatrix(shader, "lovrView", layer.view, 16); + mat4 model = state.transforms[state.transform]; lovrShaderSetMatrix(shader, "lovrModel", model, 16); - float transforms[32]; - mat4_multiply(mat4_set(transforms + 0, layer.views + 0), model); - mat4_multiply(mat4_set(transforms + 16, layer.views + 16), model); - lovrShaderSetMatrix(shader, "lovrTransforms", transforms, 32); + float modelView[16]; + mat4_multiply(mat4_set(modelView, layer.view), model); + lovrShaderSetMatrix(shader, "lovrTransform", modelView, 16); - if (lovrShaderGetUniform(shader, "lovrNormalMatrices")) { - if (mat4_invert(transforms)) { - mat4_transpose(transforms); + if (lovrShaderGetUniform(shader, "lovrNormalMatrix")) { + if (mat4_invert(modelView)) { + mat4_transpose(modelView); } else { - mat4_identity(transforms); + mat4_identity(modelView); } - if (mat4_invert(transforms + 16)) { - mat4_transpose(transforms + 16); - } else { - mat4_identity(transforms + 16); - } - - float normalMatrix[18] = { - transforms[0], transforms[1], transforms[2], - transforms[4], transforms[5], transforms[6], - transforms[8], transforms[9], transforms[10], - - transforms[16], transforms[17], transforms[18], - transforms[20], transforms[21], transforms[22], - transforms[24], transforms[25], transforms[26] + float normalMatrix[9] = { + modelView[0], modelView[1], modelView[2], + modelView[4], modelView[5], modelView[6], + modelView[8], modelView[9], modelView[10], }; - lovrShaderSetMatrix(shader, "lovrNormalMatrices", normalMatrix, 18); + lovrShaderSetMatrix(shader, "lovrNormalMatrix", normalMatrix, 9); } // Color @@ -1080,10 +1070,6 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i // Point size lovrShaderSetFloat(shader, "lovrPointSize", &state.pointSize, 1); - // Stereo - int stereo = canvas ? canvas->flags.stereo : false; - lovrShaderSetInt(shader, "lovrIsStereo", &stereo, 1); - // Pose float* pose = lovrMeshGetPose(mesh); if (pose) { @@ -1124,17 +1110,25 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i lovrGraphicsBindVertexArray(mesh->vao); lovrMeshUnmapVertices(mesh); lovrMeshUnmapIndices(mesh); - lovrMeshBind(mesh, shader, stereo); + lovrMeshBind(mesh, shader); size_t start = mesh->rangeStart; if (mesh->indexCount > 0) { size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->indexCount; GLenum indexType = mesh->indexSize == sizeof(uint16_t) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; size_t offset = start * mesh->indexSize; - glDrawElementsInstanced(mesh->drawMode, count, indexType, (GLvoid*) offset, instances * (1 + stereo)); + if (instances > 1) { + glDrawElementsInstanced(mesh->drawMode, count, indexType, (GLvoid*) offset, instances); + } else { + glDrawElements(mesh->drawMode, count, indexType, (GLvoid*) offset); + } } else { size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->count; - glDrawArraysInstanced(mesh->drawMode, start, count, instances * (1 + stereo)); + if (instances > 1) { + glDrawArraysInstanced(mesh->drawMode, start, count, instances); + } else { + glDrawArrays(mesh->drawMode, start, count); + } } if (transform) { @@ -1144,12 +1138,13 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i state.stats.drawCalls++; } -void lovrGraphicsPushLayer(Layer layer) { +void lovrGraphicsPushLayer(Canvas* canvas) { if (++state.layer >= MAX_LAYERS) { lovrThrow("Layer overflow"); } - memcpy(&state.layers[state.layer], &layer, sizeof(Layer)); + memcpy(&state.layers[state.layer], &state.layers[state.layer - 1], sizeof(Layer)); + state.layers[state.layer].canvas = canvas; } void lovrGraphicsPopLayer() { @@ -1160,6 +1155,18 @@ void lovrGraphicsPopLayer() { lovrAssert(--state.layer >= 0, "Layer underflow"); } +void lovrGraphicsSetCamera(mat4 projection, mat4 view) { + mat4_set(state.layers[state.layer].projection, projection); + mat4_set(state.layers[state.layer].view, view); +} + +void lovrGraphicsSetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + state.layers[state.layer].viewport[0] = x; + state.layers[state.layer].viewport[1] = y; + state.layers[state.layer].viewport[2] = width; + state.layers[state.layer].viewport[3] = height; +} + Texture* lovrGraphicsGetTexture(int slot) { return state.textures[slot]; } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 6a34a0e6..632411d2 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -71,9 +71,10 @@ typedef enum { } StencilAction; typedef struct { - float projections[32]; - float views[32]; + float projection[16]; + float view[16]; Canvas* canvas; + int viewport[4]; } Layer; typedef struct { @@ -98,6 +99,8 @@ typedef struct { Texture* defaultTexture; float transforms[MAX_TRANSFORMS + INTERNAL_TRANSFORMS][16]; int transform; + Layer layers[MAX_LAYERS]; + int layer; Color backgroundColor; BlendMode blendMode; BlendAlphaMode blendAlphaMode; @@ -119,10 +122,6 @@ typedef struct { Winding winding; bool wireframe; Mesh* mesh; - uint32_t cameraBuffer; - float cameraData[4][16]; - Layer layers[MAX_LAYERS]; - int layer; Texture* textures[MAX_TEXTURES]; bool stencilEnabled; bool stencilWriting; @@ -131,7 +130,6 @@ typedef struct { uint32_t viewport[4]; uint32_t vertexArray; uint32_t vertexBuffer; - uint32_t uniformBuffer; uint32_t indexBuffer; GraphicsStats stats; } GraphicsState; @@ -207,8 +205,10 @@ void lovrGraphicsFill(Texture* texture); // Internal void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader shader, int instances); VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity); -void lovrGraphicsPushLayer(Layer layer); +void lovrGraphicsPushLayer(Canvas* canvas); void lovrGraphicsPopLayer(); +void lovrGraphicsSetCamera(mat4 projection, mat4 view); +void lovrGraphicsSetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height); Texture* lovrGraphicsGetTexture(int slot); void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot); Material* lovrGraphicsGetDefaultMaterial(); diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index da8fa8a9..f351bb62 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -73,7 +73,7 @@ void lovrMeshDetachAttribute(Mesh* mesh, const char* name) { map_remove(&mesh->attachments, name); } -void lovrMeshBind(Mesh* mesh, Shader* shader, bool stereo) { +void lovrMeshBind(Mesh* mesh, Shader* shader) { const char* key; map_iter_t iter = map_iter(&mesh->attachments); @@ -108,7 +108,7 @@ void lovrMeshBind(Mesh* mesh, Shader* shader, bool stereo) { } if (previous.divisor != current.divisor) { - glVertexAttribDivisor(i, current.divisor * (1 + stereo)); + glVertexAttribDivisor(i, current.divisor); } if (previous.mesh != current.mesh || previous.attributeIndex != current.attributeIndex) { diff --git a/src/graphics/mesh.h b/src/graphics/mesh.h index 1c98e3dc..eeb037db 100644 --- a/src/graphics/mesh.h +++ b/src/graphics/mesh.h @@ -70,7 +70,7 @@ Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, void lovrMeshDestroy(void* ref); void lovrMeshAttachAttribute(Mesh* mesh, Mesh* other, const char* name, int divisor); void lovrMeshDetachAttribute(Mesh* mesh, const char* name); -void lovrMeshBind(Mesh* mesh, Shader* shader, bool stereo); +void lovrMeshBind(Mesh* mesh, Shader* shader); VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh); MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh); void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); diff --git a/src/graphics/shader.c b/src/graphics/shader.c index e694a918..9e94af1f 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -260,10 +260,6 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) { map_set(&shader->attributes, name, glGetAttribLocation(program, name)); } - // Uniform block binding - uint32_t cameraBlockIndex = glGetUniformBlockIndex(program, "lovrCamera"); - glUniformBlockBinding(program, cameraBlockIndex, LOVR_SHADER_BLOCK_CAMERA); - return shader; } diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 5d59a1e8..4d6408c1 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -14,7 +14,6 @@ #define LOVR_SHADER_TANGENT 4 #define LOVR_SHADER_BONES 5 #define LOVR_SHADER_BONE_WEIGHTS 6 -#define LOVR_SHADER_BLOCK_CAMERA 0 #define LOVR_MAX_UNIFORM_LENGTH 256 #define LOVR_MAX_ATTRIBUTE_LENGTH 256 diff --git a/src/headset/fake.c b/src/headset/fake.c index 52b1d4bc..8be1954f 100644 --- a/src/headset/fake.c +++ b/src/headset/fake.c @@ -203,6 +203,7 @@ static void fakeGetDisplayDimensions(int* width, int* height) { GLFWwindow* window = glfwGetCurrentContext(); if (window) { glfwGetFramebufferSize(window, width, height); + *width /= 2; } } @@ -299,39 +300,23 @@ static void fakeRenderTo(void (*callback)(void*), void* userdata) { int width, height; fakeGetDisplayDimensions(&width, &height); - if (!state.canvas) { - lovrGraphicsBindFramebuffer(0); - int msaa = 0; - glGetIntegerv(GL_SAMPLES, &msaa); - CanvasFlags flags = { .msaa = msaa, .depth = true, .stencil = true, .stereo = true, .mipmaps = false }; - state.canvas = lovrCanvasCreate(width * 2, height, FORMAT_RGB, flags); - } + float projection[16]; + mat4_perspective(projection, state.clipNear, state.clipFar, 67 * M_PI / 180., (float) width / height); - Layer layer = { .canvas = state.canvas }; - mat4_perspective(layer.projections, state.clipNear, state.clipFar, 67 * M_PI / 180., (float) width / height / 2.); - mat4_set(layer.projections + 16, layer.projections); - 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); + float view[16]; + mat4_identity(view); + mat4_translate(view, 0, state.offset, 0); + mat4_multiply(view, state.transform); + mat4_invert(view); - lovrGraphicsPushLayer(layer); + lovrGraphicsPushLayer(NULL); lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0); + lovrGraphicsSetCamera(projection, view); + lovrGraphicsSetViewport(0, 0, width, height); + callback(userdata); + lovrGraphicsSetViewport(width, 0, width, height); callback(userdata); lovrGraphicsPopLayer(); - - if (state.mirrored) { - Color oldColor = lovrGraphicsGetColor(); - lovrGraphicsSetColor((Color) { 1, 1, 1, 1 }); - Shader* lastShader = lovrGraphicsGetShader(); - lovrRetain(lastShader); - lovrGraphicsSetShader(NULL); - lovrGraphicsFill(&state.canvas->texture); - lovrGraphicsSetShader(lastShader); - lovrRelease(lastShader); - lovrGraphicsSetColor(oldColor); - } } static void fakeUpdate(float dt) { diff --git a/src/headset/openvr.c b/src/headset/openvr.c index d78239ad..5ef1316f 100644 --- a/src/headset/openvr.c +++ b/src/headset/openvr.c @@ -252,7 +252,7 @@ static void ensureCanvas() { int msaa = 0; glGetIntegerv(GL_SAMPLES, &msaa); state.system->GetRecommendedRenderTargetSize(&state.renderWidth, &state.renderHeight); - CanvasFlags flags = { .msaa = msaa, .depth = true, .stencil = true, .stereo = true, .mipmaps = false }; + CanvasFlags flags = { .msaa = msaa, .depth = true, .stencil = true, .mipmaps = false }; state.canvas = lovrCanvasCreate(state.renderWidth * 2, state.renderHeight, FORMAT_RGB, flags); } @@ -664,59 +664,44 @@ static ModelData* openvrControllerNewModelData(Controller* controller) { } static void openvrRenderTo(void (*callback)(void*), void* userdata) { + float head[16], eye[16], projection[16], view[16]; + ensureCanvas(); state.isRendering = true; state.compositor->WaitGetPoses(state.renderPoses, 16, NULL, 0); + mat4_fromMat34(head, state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m); - // Layer setup - Layer layer = { .canvas = state.canvas }; - float eye[16]; - float head[16]; - float (*matrix)[4]; - matrix = state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m; - mat4_fromMat34(head, matrix); + lovrGraphicsPushLayer(state.canvas); + lovrGraphicsSetViewport(0, 0, state.renderWidth, state.renderHeight); for (HeadsetEye i = EYE_LEFT; i <= EYE_RIGHT; i++) { + + // Camera 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); - - // View - matrix = state.system->GetEyeToHeadTransform(vrEye).m; - mat4_fromMat34(eye, matrix); - mat4 view = layer.views + 16 * i; + mat4_fromMat44(projection, state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m); mat4_identity(view); mat4_translate(view, 0, state.offset, 0); mat4_multiply(view, head); - mat4_multiply(view, eye); + mat4_multiply(view, mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m)); mat4_invert(view); + lovrGraphicsSetCamera(projection, view); + + // Render + lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0); + callback(userdata); + lovrCanvasResolve(state.canvas); + + // Submit + glActiveTexture(GL_TEXTURE0); + Texture* oldTexture = lovrGraphicsGetTexture(0); + 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 }; + state.compositor->Submit(vrEye, &eyeTexture, NULL, EVRSubmitFlags_Submit_Default); + glBindTexture(GL_TEXTURE_2D, oldTexture->id); } - // Render - lovrGraphicsPushLayer(layer); - lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0); - callback(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, .5, 1. }; - VRTextureBounds_t right = { .5, 0, 1., 1. }; - 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) { diff --git a/src/headset/webvr.c b/src/headset/webvr.c index 3b58e0c5..426eaa3e 100644 --- a/src/headset/webvr.c +++ b/src/headset/webvr.c @@ -32,7 +32,6 @@ extern void webvrSetRenderCallback(void (*callback)(float*, float*, float*, floa extern void webvrUpdate(float dt); typedef struct { - Canvas* canvas; vec_controller_t controllers; void (*renderCallback)(void*); } HeadsetState; @@ -88,34 +87,17 @@ static void onMountChanged(bool mounted) { } static void onFrame(float* leftView, float* rightView, float* leftProjection, float* rightProjection, void* userdata) { - if (!state.canvas) { - int32_t width, height; - webvrGetDisplayDimensions(&width, &height); - CanvasFlags flags = { .msaa = 0, .depth = true, .stencil = true, .stereo = true, .mipmaps = false }; - state.canvas = lovrCanvasCreate(width, height, FORMAT_RGB, flags); - } - - Layer layer = { .canvas = state.canvas }; - - memcpy(layer.views, leftView, 16 * sizeof(float)); - memcpy(layer.views + 16, rightView, 16 * sizeof(float)); - memcpy(layer.projections, leftProjection, 16 * sizeof(float)); - memcpy(layer.projections + 16, rightProjection, 16 * sizeof(float)); - - lovrGraphicsPushLayer(layer); + int width, height; + webvrGetDisplayDimensions(&width, &height); + lovrGraphicsPushLayer(NULL); lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0); + lovrGraphicsSetCamera(leftProjection, leftView); + lovrGraphicsSetViewport(0, 0, width, height); + state.renderCallback(userdata); + lovrGraphicsSetCamera(rightProjection, rightView); + lovrGraphicsSetViewport(width, 0, width, height); state.renderCallback(userdata); lovrGraphicsPopLayer(); - - Color oldColor = lovrGraphicsGetColor(); - lovrGraphicsSetColor((Color) { 1, 1, 1, 1 }); - Shader* lastShader = lovrGraphicsGetShader(); - lovrRetain(lastShader); - lovrGraphicsSetShader(NULL); - lovrGraphicsFill(&state.canvas->texture); - lovrGraphicsSetShader(lastShader); - lovrRelease(lastShader); - lovrGraphicsSetColor(oldColor); } static bool webvrDriverInit(float offset) { @@ -131,7 +113,6 @@ static bool webvrDriverInit(float offset) { static void webvrDriverDestroy() { webvrDestroy(); - lovrRelease(state.canvas); vec_deinit(&state.controllers); memset(&state, 0, sizeof(HeadsetState)); } diff --git a/src/resources/shaders.c b/src/resources/shaders.c index 82a45167..bce957a7 100644 --- a/src/resources/shaders.c +++ b/src/resources/shaders.c @@ -24,18 +24,11 @@ const char* lovrShaderVertexPrefix = "" #ifdef EMSCRIPTEN "#version 300 es \n" "precision mediump float; \n" -"out float lovrClipDistance; \n" #else "#version 150 \n" #endif "#define MAX_BONES 48 \n" -"#define lovrInstanceID gl_InstanceID / (1 + lovrIsStereo) \n" -"#define lovrTransform lovrTransforms[lovrEye] \n" -"#define lovrNormalMatrix lovrNormalMatrices[lovrEye] \n" -"#define lovrView lovrViews[lovrEye] \n" -"#define lovrProjection lovrProjections[lovrEye] \n" -"float lovrEyeOffset[2] = float[2](-.5, .5); \n" -"vec4 lovrClipPlane[2] = vec4[2](vec4(-1, 0, 0, 1), vec4(1, 0, 0, 1)); \n" +"in int lovrEye; \n" "in vec3 lovrPosition; \n" "in vec3 lovrNormal; \n" "in vec2 lovrTexCoord; \n" @@ -45,15 +38,11 @@ const char* lovrShaderVertexPrefix = "" "in vec4 lovrBoneWeights; \n" "out vec2 texCoord; \n" "out vec4 vertexColor; \n" -"flat out int lovrEye; \n" -"uniform int lovrIsStereo; \n" -"layout(std140) uniform lovrCamera { \n" -" mat4 lovrProjections[2]; \n" -" mat4 lovrViews[2]; \n" -"}; \n" "uniform mat4 lovrModel; \n" -"uniform mat4 lovrTransforms[2]; \n" -"uniform mat3 lovrNormalMatrices[2]; \n" +"uniform mat4 lovrView; \n" +"uniform mat4 lovrProjection; \n" +"uniform mat4 lovrTransform; \n" +"uniform mat3 lovrNormalMatrix; \n" "uniform float lovrPointSize; \n" "uniform mat4 lovrPose[MAX_BONES]; \n" "#line 0 \n"; @@ -62,14 +51,12 @@ const char* lovrShaderFragmentPrefix = "" #ifdef EMSCRIPTEN "#version 300 es \n" "precision mediump float; \n" -"in float lovrClipDistance; \n" #else "#version 150 \n" "in vec4 gl_FragCoord; \n" #endif "in vec2 texCoord; \n" "in vec4 vertexColor; \n" -"flat in int lovrEye; \n" "out vec4 lovrCanvas[gl_MaxDrawBuffers]; \n" "uniform float lovrMetalness; \n" "uniform float lovrRoughness; \n" @@ -89,31 +76,17 @@ const char* lovrShaderVertexSuffix = "" "void main() { \n" " texCoord = lovrTexCoord; \n" " vertexColor = lovrVertexColor; \n" -" lovrEye = gl_InstanceID & 1; \n" " mat4 pose = \n" " lovrPose[lovrBones[0]] * lovrBoneWeights[0] + \n" " lovrPose[lovrBones[1]] * lovrBoneWeights[1] + \n" " lovrPose[lovrBones[2]] * lovrBoneWeights[2] + \n" " lovrPose[lovrBones[3]] * lovrBoneWeights[3]; \n" " gl_PointSize = lovrPointSize; \n" -" vec4 projected = position(lovrProjection, lovrTransform, pose * vec4(lovrPosition, 1.0)); \n" -#ifndef EMSCRIPTEN -" gl_ClipDistance[0] = float(lovrIsStereo) * dot(projected, lovrClipPlane[lovrEye]); \n" -#else -" lovrClipDistance = float(lovrIsStereo) * dot(projected, lovrClipPlane[lovrEye]); \n" -#endif -" projected.x *= 1. - (float(lovrIsStereo) * .5); \n" -" projected.x += float(lovrIsStereo) * lovrEyeOffset[lovrEye] * projected.w; \n" -" gl_Position = projected; \n" +" gl_Position = position(lovrProjection, lovrTransform, pose * vec4(lovrPosition, 1.0)); \n" "}"; const char* lovrShaderFragmentSuffix = "" "void main() { \n" -#ifdef EMSCRIPTEN -" if (lovrClipDistance < 0.) { \n" -" discard; \n" -" } \n" -#endif "#ifdef MULTICANVAS \n" " colors(lovrColor, lovrDiffuseTexture, texCoord); \n" "#else \n"