lovr.graphics.get/setViewPose; lovr.graphics.get/setProjection;

This commit is contained in:
bjorn 2020-09-24 19:03:37 -07:00
parent 61abb6f02b
commit f1447fd69a
13 changed files with 230 additions and 130 deletions

View File

@ -44,7 +44,7 @@ if(EMSCRIPTEN)
"-Os "
"-s USE_WEBGL2=1 "
"-s FORCE_FILESYSTEM=1 "
"-s \"EXPORTED_FUNCTIONS=['_main','_lovrDestroy','_webxr_attach','_webxr_detach','_lovrCanvasCreateFromHandle','_lovrCanvasDestroy','_lovrGraphicsSetCamera']\" "
"-s \"EXPORTED_FUNCTIONS=['_main','_lovrDestroy','_webxr_attach','_webxr_detach','_lovrCanvasCreateFromHandle','_lovrCanvasDestroy','_lovrGraphicsSetBackbuffer','_lovrGraphicsSetViewMatrix','_lovrGraphicsSetProjection']\" "
"-s \"EXTRA_EXPORTED_RUNTIME_METHODS=['getValue','setValue']\" "
"--js-library \"${CMAKE_CURRENT_SOURCE_DIR}/src/resources/webxr.js\" "
"--shell-file \"${CMAKE_CURRENT_SOURCE_DIR}/src/resources/lovr.html\""

View File

@ -47,7 +47,7 @@ SUFFIX_android = .so
CFLAGS_web += -DLOVR_WEBGL
LDFLAGS_web += -s USE_WEBGL2
LDFLAGS_web += -s FORCE_FILESYSTEM
LDFLAGS_web += -s EXPORTED_FUNCTIONS="['_main','_lovrDestroy','_webxr_attach','_webxr_detach','_lovrCanvasCreateFromHandle','_lovrCanvasDestroy','_lovrGraphicsSetCamera']"
LDFLAGS_web += -s EXPORTED_FUNCTIONS="['_main','_lovrDestroy','_webxr_attach','_webxr_detach','_lovrCanvasCreateFromHandle','_lovrCanvasDestroy','_lovrGraphicsSetBackbuffer','_lovrGraphicsSetViewMatrix','_lovrGraphicsSetProjection']"
LDFLAGS_@(WEBXR)_web += --js-library $(ROOT)/src/resources/webxr.js
LDFLAGS_web += --shell-file $(ROOT)/src/resources/lovr.html
CFLAGS_@(THREAD)_web += -s USE_PTHREADS=1

View File

@ -407,6 +407,96 @@ static int l_lovrGraphicsHasWindow(lua_State *L) {
return 1;
}
static int l_lovrGraphicsGetViewPose(lua_State* L) {
uint32_t view = luaL_checkinteger(L, 1) - 1;
lovrAssert(view < 2, "Invalid view index %d", view + 1);
if (lua_gettop(L) > 1) {
float* matrix = luax_checkvector(L, 2, V_MAT4, NULL);
bool invert = lua_toboolean(L, 3);
lovrGraphicsGetViewMatrix(view, matrix);
if (!invert) mat4_invert(matrix);
lua_settop(L, 2);
return 1;
} else {
float matrix[16], angle, ax, ay, az;
lovrGraphicsGetViewMatrix(view, matrix);
mat4_invert(matrix);
mat4_getAngleAxis(matrix, &angle, &ax, &ay, &az);
lua_pushnumber(L, matrix[12]);
lua_pushnumber(L, matrix[13]);
lua_pushnumber(L, matrix[14]);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
return 7;
}
}
static int l_lovrGraphicsSetViewPose(lua_State* L) {
uint32_t view = luaL_checkinteger(L, 1) - 1;
lovrAssert(view < 2, "Invalid view index %d", view + 1);
VectorType t;
float* m = luax_tovector(L, 2, &t);
if (m && t == V_MAT4) {
float matrix[16];
mat4_init(matrix, m);
bool inverted = lua_toboolean(L, 3);
if (!inverted) mat4_invert(matrix);
lovrGraphicsSetViewMatrix(view, matrix);
} else {
int index = 2;
float position[4], orientation[4], matrix[16];
index = luax_readvec3(L, index, position, "vec3, number, or mat4");
index = luax_readquat(L, index, orientation, NULL);
mat4_fromQuat(matrix, orientation);
memcpy(matrix + 12, position, 3 * sizeof(float));
mat4_invert(matrix);
lovrGraphicsSetViewMatrix(view, matrix);
}
return 0;
}
static int l_lovrGraphicsGetProjection(lua_State* L) {
uint32_t view = luaL_checkinteger(L, 1) - 1;
lovrAssert(view < 2, "Invalid view index %d", view + 1);
if (lua_gettop(L) > 1) {
float* matrix = luax_checkvector(L, 2, V_MAT4, NULL);
lovrGraphicsGetProjection(view, matrix);
lua_settop(L, 2);
return 1;
} else {
float matrix[16], left, right, up, down;
lovrGraphicsGetProjection(view, matrix);
mat4_getFov(matrix, &left, &right, &up, &down);
lua_pushnumber(L, left);
lua_pushnumber(L, right);
lua_pushnumber(L, up);
lua_pushnumber(L, down);
return 4;
}
}
static int l_lovrGraphicsSetProjection(lua_State* L) {
uint32_t view = luaL_checkinteger(L, 1) - 1;
lovrAssert(view < 2, "Invalid view index %d", view + 1);
if (lua_type(L, 2) == LUA_TNUMBER) {
float left = luax_checkfloat(L, 2);
float right = luax_checkfloat(L, 3);
float up = luax_checkfloat(L, 4);
float down = luax_checkfloat(L, 5);
float clipNear = luax_optfloat(L, 6, .1f);
float clipFar = luax_optfloat(L, 7, 100.f);
float matrix[16];
mat4_fov(matrix, left, right, up, down, clipNear, clipFar);
lovrGraphicsSetProjection(view, matrix);
} else {
float* m = luax_checkvector(L, 2, V_MAT4, "mat4 or number");
lovrGraphicsSetProjection(view, m);
}
return 0;
}
static int l_lovrGraphicsTick(lua_State* L) {
const char* label = luaL_checkstring(L, 1);
lovrGraphicsTick(label);
@ -757,13 +847,6 @@ static int l_lovrGraphicsTransform(lua_State* L) {
return 0;
}
static int l_lovrGraphicsSetProjection(lua_State* L) {
float transform[16];
luax_readmat4(L, 1, transform, 3);
lovrGraphicsSetProjection(transform);
return 0;
}
// Rendering
static int l_lovrGraphicsClear(lua_State* L) {
@ -1655,6 +1738,10 @@ static const luaL_Reg lovrGraphics[] = {
{ "getDimensions", l_lovrGraphicsGetDimensions },
{ "getPixelDensity", l_lovrGraphicsGetPixelDensity },
{ "hasWindow", l_lovrGraphicsHasWindow },
{ "getViewPose", l_lovrGraphicsGetViewPose },
{ "setViewPose", l_lovrGraphicsSetViewPose },
{ "getProjection", l_lovrGraphicsGetProjection },
{ "setProjection", l_lovrGraphicsSetProjection },
{ "tick", l_lovrGraphicsTick },
{ "tock", l_lovrGraphicsTock },
{ "getFeatures", l_lovrGraphicsGetFeatures },
@ -1704,7 +1791,6 @@ static const luaL_Reg lovrGraphics[] = {
{ "rotate", l_lovrGraphicsRotate },
{ "scale", l_lovrGraphicsScale },
{ "transform", l_lovrGraphicsTransform },
{ "setProjection", l_lovrGraphicsSetProjection },
// Rendering
{ "clear", l_lovrGraphicsClear },

View File

@ -95,7 +95,7 @@ static struct {
bool debug;
int width;
int height;
Camera camera;
Canvas* backbuffer;
FrameData frameData;
bool frameDataDirty;
Canvas* defaultCanvas;
@ -232,6 +232,7 @@ void lovrGraphicsCreateWindow(WindowFlags* flags) {
lovrGpuInit(lovrPlatformGetProcAddress, state.debug);
state.defaultCanvas = lovrCanvasCreateFromHandle(state.width, state.height, (CanvasFlags) { .stereo = false }, 0, 0, 0, 1, true);
state.backbuffer = state.defaultCanvas;
for (int i = 0; i < MAX_STREAMS; i++) {
state.buffers[i] = lovrBufferCreate(bufferCount[i] * bufferStride[i], NULL, bufferType[i], USAGE_STREAM, false);
@ -289,42 +290,48 @@ float lovrGraphicsGetPixelDensity() {
}
}
const Camera* lovrGraphicsGetCamera() {
return &state.camera;
}
void lovrGraphicsSetCamera(Camera* camera, bool clear) {
void lovrGraphicsSetBackbuffer(Canvas* canvas, bool stereo, bool clear) {
lovrGraphicsFlush();
if (state.camera.canvas && (!camera || camera->canvas != state.camera.canvas)) {
lovrCanvasResolve(state.camera.canvas);
if (!canvas) {
canvas = state.defaultCanvas;
lovrCanvasSetStereo(canvas, stereo);
}
if (!camera) {
memset(&state.camera, 0, sizeof(Camera));
mat4_identity(state.camera.viewMatrix[0]);
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;
lovrCanvasSetStereo(state.camera.canvas, false);
} else {
state.camera = *camera;
if (!state.camera.canvas) {
state.camera.canvas = state.defaultCanvas;
lovrCanvasSetStereo(state.camera.canvas, camera->stereo);
}
if (canvas != state.backbuffer) {
lovrCanvasResolve(state.backbuffer);
state.backbuffer = canvas;
}
memcpy(&state.frameData, &state.camera.viewMatrix[0][0], sizeof(FrameData));
state.frameDataDirty = true;
if (clear) {
lovrGpuClear(state.camera.canvas, &state.linearBackgroundColor, &(float) { 1. }, &(int) { 0 });
lovrGpuClear(state.backbuffer, &state.linearBackgroundColor, &(float) { 1. }, &(int) { 0 });
}
}
void lovrGraphicsGetViewMatrix(uint32_t index, float* viewMatrix) {
lovrAssert(index < 2, "Invalid view index %d", index);
mat4_init(viewMatrix, state.frameData.viewMatrix[index]);
}
void lovrGraphicsSetViewMatrix(uint32_t index, float* viewMatrix) {
lovrAssert(index < 2, "Invalid view index %d", index);
lovrGraphicsFlush();
mat4_init(state.frameData.viewMatrix[index], viewMatrix);
state.frameDataDirty = true;
}
void lovrGraphicsGetProjection(uint32_t index, float* projection) {
lovrAssert(index < 2, "Invalid view index %d", index);
mat4_init(projection, state.frameData.projection[index]);
}
void lovrGraphicsSetProjection(uint32_t index, float* projection) {
lovrAssert(index < 2, "Invalid view index %d", index);
lovrGraphicsFlush();
mat4_init(state.frameData.projection[index], projection);
state.frameDataDirty = true;
}
Buffer* lovrGraphicsGetIdentityBuffer() {
return state.identityBuffer;
}
@ -333,7 +340,13 @@ Buffer* lovrGraphicsGetIdentityBuffer() {
void lovrGraphicsReset() {
state.transform = 0;
lovrGraphicsSetCamera(NULL, false);
float viewMatrix[16], projection[16];
mat4_identity(viewMatrix);
mat4_perspective(projection, .01f, 100.f, 67.f * (float) M_PI / 180.f, (float) state.width / state.height);
lovrGraphicsSetViewMatrix(0, viewMatrix);
lovrGraphicsSetViewMatrix(1, viewMatrix);
lovrGraphicsSetProjection(0, projection);
lovrGraphicsSetProjection(1, projection);
lovrGraphicsSetAlphaSampling(false);
lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1 });
lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY);
@ -548,22 +561,13 @@ void lovrGraphicsMatrixTransform(mat4 transform) {
mat4_multiply(state.transforms[state.transform], transform);
}
void lovrGraphicsSetProjection(mat4 projection) {
lovrGraphicsFlush();
mat4_set(state.camera.projection[0], projection);
mat4_set(state.camera.projection[1], projection);
mat4_set(state.frameData.projection[0], projection);
mat4_set(state.frameData.projection[1], projection);
state.frameDataDirty = true;
}
// Rendering
static void lovrGraphicsBatch(BatchRequest* req) {
// Resolve objects
Mesh* mesh = req->mesh ? req->mesh : (req->instanced ? state.instancedMesh : state.mesh);
Canvas* canvas = state.canvas ? state.canvas : state.camera.canvas;
Canvas* canvas = state.canvas ? state.canvas : state.backbuffer;
bool stereo = lovrCanvasIsStereo(canvas);
Shader* shader = state.shader ? state.shader : (state.defaultShaders[req->shader][stereo] ? state.defaultShaders[req->shader][stereo] : (state.defaultShaders[req->shader][stereo] = lovrShaderCreateDefault(req->shader, NULL, 0, stereo)));
Pipeline* pipeline = req->pipeline ? req->pipeline : &state.pipeline;
@ -796,12 +800,12 @@ void lovrGraphicsClear(Color* color, float* depth, int* stencil) {
if (color) gammaCorrect(color);
#endif
if (color || depth || stencil) lovrGraphicsFlush();
lovrGpuClear(state.canvas ? state.canvas : state.camera.canvas, color, depth, stencil);
lovrGpuClear(state.canvas ? state.canvas : state.backbuffer, color, depth, stencil);
}
void lovrGraphicsDiscard(bool color, bool depth, bool stencil) {
if (color || depth || stencil) lovrGraphicsFlush();
lovrGpuDiscard(state.canvas ? state.canvas : state.camera.canvas, color, depth, stencil);
lovrGpuDiscard(state.canvas ? state.canvas : state.backbuffer, color, depth, stencil);
}
void lovrGraphicsPoints(uint32_t count, float** vertices) {

View File

@ -69,13 +69,6 @@ typedef enum {
WINDING_COUNTERCLOCKWISE
} Winding;
typedef struct {
bool stereo;
struct Canvas* canvas;
float viewMatrix[2][16];
float projection[2][16];
} Camera;
typedef struct {
float lineWidth;
unsigned alphaSampling : 1;
@ -99,8 +92,11 @@ void lovrGraphicsCreateWindow(WindowFlags* flags);
int lovrGraphicsGetWidth(void);
int lovrGraphicsGetHeight(void);
float lovrGraphicsGetPixelDensity(void);
const Camera* lovrGraphicsGetCamera(void);
void lovrGraphicsSetCamera(Camera* camera, bool clear);
void lovrGraphicsSetBackbuffer(struct Canvas* canvas, bool stereo, bool clear);
void lovrGraphicsGetViewMatrix(uint32_t index, float* viewMatrix);
void lovrGraphicsSetViewMatrix(uint32_t index, float* viewMatrix);
void lovrGraphicsGetProjection(uint32_t index, float* projection);
void lovrGraphicsSetProjection(uint32_t index, float* projection);
struct Buffer* lovrGraphicsGetIdentityBuffer(void);
#define lovrGraphicsTick lovrGpuTick
#define lovrGraphicsTock lovrGpuTock
@ -151,7 +147,6 @@ void lovrGraphicsTranslate(vec3 translation);
void lovrGraphicsRotate(quat rotation);
void lovrGraphicsScale(vec3 scale);
void lovrGraphicsMatrixTransform(mat4 transform);
void lovrGraphicsSetProjection(mat4 projection);
// Rendering
void lovrGraphicsFlush(void);

View File

@ -181,17 +181,20 @@ static bool desktop_animate(Device device, struct Model* model) {
}
static void desktop_renderTo(void (*callback)(void*), void* userdata) {
float left, right, up, down;
float projection[16], left, right, up, down;
desktop_getViewAngles(0, &left, &right, &up, &down);
Camera camera = { .canvas = NULL, .viewMatrix = { MAT4_IDENTITY }, .stereo = true };
mat4_fov(camera.projection[0], left, right, up, down, state.clipNear, state.clipFar);
mat4_multiply(camera.viewMatrix[0], state.headTransform);
mat4_invert(camera.viewMatrix[0]);
mat4_set(camera.projection[1], camera.projection[0]);
mat4_set(camera.viewMatrix[1], camera.viewMatrix[0]);
lovrGraphicsSetCamera(&camera, true);
mat4_fov(projection, left, right, up, down, state.clipNear, state.clipFar);
float viewMatrix[16];
mat4_invert(mat4_init(viewMatrix, state.headTransform));
lovrGraphicsSetProjection(0, projection);
lovrGraphicsSetProjection(1, projection);
lovrGraphicsSetViewMatrix(0, viewMatrix);
lovrGraphicsSetViewMatrix(1, viewMatrix);
lovrGraphicsSetBackbuffer(NULL, true, true);
callback(userdata);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
}
static void desktop_update(float dt) {

View File

@ -368,8 +368,6 @@ static void oculus_renderTo(void (*callback)(void*), void* userdata) {
}
}
Camera camera = { .canvas = state.canvas };
for (int eye = 0; eye < 2; eye++) {
float orient[] = {
EyeRenderPose[eye].Orientation.x,
@ -382,14 +380,17 @@ static void oculus_renderTo(void (*callback)(void*), void* userdata) {
EyeRenderPose[eye].Position.y,
EyeRenderPose[eye].Position.z
};
mat4 transform = camera.viewMatrix[eye];
mat4_fromQuat(transform, orient);
transform[12] = -(transform[0] * pos[0] + transform[4] * pos[1] + transform[8] * pos[2]);
transform[13] = -(transform[1] * pos[0] + transform[5] * pos[1] + transform[9] * pos[2]);
transform[14] = -(transform[2] * pos[0] + transform[6] * pos[1] + transform[10] * pos[2]);
float view[16];
mat4_fromQuat(view, orient);
view[12] = -(view[0] * pos[0] + view[4] * pos[1] + view[8] * pos[2]);
view[13] = -(view[1] * pos[0] + view[5] * pos[1] + view[9] * pos[2]);
view[14] = -(view[2] * pos[0] + view[6] * pos[1] + view[10] * pos[2]);
lovrGraphicsSetViewMatrix(eye, view);
float projection[16];
ovrMatrix4f projection = ovrMatrix4f_Projection(state.desc.DefaultEyeFov[eye], state.clipNear, state.clipFar, ovrProjection_ClipRangeOpenGL);
mat4_fromMat44(camera.projection[eye], projection.M);
mat4_fromMat44(projection, projection.M);
lovrGraphicsSetProjection(eye, projection);
}
ovr_WaitToBeginFrame(state.session, state.frameIndex);
@ -402,9 +403,9 @@ static void oculus_renderTo(void (*callback)(void*), void* userdata) {
Texture* texture = lookupTexture(curTexId);
lovrCanvasSetAttachments(state.canvas, &(Attachment) { texture, 0, 0 }, 1);
lovrGraphicsSetCamera(&camera, true);
lovrGraphicsSetBackbuffer(state.canvas, true, true);
callback(userdata);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
ovr_CommitTextureSwapChain(state.session, state.chain);

View File

@ -772,23 +772,23 @@ static void openvr_renderTo(void (*callback)(void*), void* userdata) {
lovrPlatformSetSwapInterval(0);
}
Camera camera = { .canvas = state.canvas };
float head[16];
mat4_fromMat34(head, state.renderPoses[k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m);
for (int i = 0; i < 2; i++) {
float eye[16];
float matrix[16], eye[16];
EVREye vrEye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
mat4_fromMat44(camera.projection[i], state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m);
mat4_init(camera.viewMatrix[i], head);
mat4_multiply(camera.viewMatrix[i], mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
mat4_invert(camera.viewMatrix[i]);
mat4_init(matrix, head);
mat4_multiply(matrix, mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
mat4_invert(matrix);
lovrGraphicsSetViewMatrix(i, matrix);
mat4_fromMat44(matrix, state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m);
lovrGraphicsSetProjection(i, matrix);
}
lovrGraphicsSetCamera(&camera, true);
lovrGraphicsSetBackbuffer(state.canvas, true, true);
callback(userdata);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
// Submit
const Attachment* attachments = lovrCanvasGetAttachments(state.canvas, NULL);

View File

@ -796,17 +796,22 @@ static void openxr_renderTo(void (*callback)(void*), void* userdata) {
getViews(views, &count);
for (int eye = 0; eye < 2; eye++) {
float viewMatrix[16];
XrView* view = &views[eye];
mat4_fromQuat(viewMatrix, &view->pose.orientation.x);
memcpy(viewMatrix, &view->pose.position.x, 3 * sizeof(float));
mat4_invert(viewMatrix);
lovrGraphicsSetViewMatrix(eye, viewMatrix);
float projection[16];
XrFovf* fov = &view->fov;
mat4_fov(camera.projection[eye], -fov->angleLeft, fov->angleRight, fov->angleUp, -fov->angleDown, state.clipNear, state.clipFar);
mat4_fromQuat(camera.viewMatrix[eye], &view->pose.orientation.x);
memcpy(camera.viewMatrix[eye] + 12, &view->pose.position.x, 3 * sizeof(float));
mat4_invert(camera.viewMatrix[eye]);
mat4_fov(projection, -fov->angleLeft, fov->angleRight, fov->angleUp, -fov->angleDown, state.clipNear, state.clipFar);
lovrGraphicsSetProjection(eye, projection);
}
lovrGraphicsSetCamera(&camera, true);
lovrGraphicsSetBackbuffer(state.canvases[state.imageIndex], true, true);
callback(userdata);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
endInfo.layerCount = 1;
state.layerViews[0].pose = views[0].pose;

View File

@ -575,20 +575,22 @@ JNIEXPORT void JNICALL Java_org_lovr_app_Activity_lovrPicoDrawEye(JNIEnv* jni, j
arr_push(&state.canvases, ((NativeCanvas) { .id = framebuffer, .instance = canvas }));
}
Camera camera;
camera.stereo = false;
camera.canvas = canvas;
for (uint32_t i = 0; i < 2; i++) {
mat4_fov(camera.projection[i], state.fov, state.fov, state.fov, state.fov, state.clipNear, state.clipFar);
mat4_identity(camera.viewMatrix[i]);
mat4_translate(camera.viewMatrix[i], state.headPosition[0], state.headPosition[1] + state.offset, state.headPosition[2]);
mat4_rotateQuat(camera.viewMatrix[i], state.headOrientation);
mat4_translate(camera.viewMatrix[i], state.ipd * (eye == 0 ? -.5f : .5f), 0.f, 0.f);
mat4_invert(camera.viewMatrix[i]);
float view[16];
mat4_identity(view);
mat4_translate(view, state.headPosition[0], state.headPosition[1] + state.offset, state.headPosition[2]);
mat4_rotateQuat(view, state.headOrientation);
mat4_translate(view, state.ipd * (eye == 0 ? -.5f : .5f), 0.f, 0.f);
mat4_invert(view);
lovrGraphicsSetViewMatrix(i, view);
float projection[16];
mat4_fov(projection, state.fov, state.fov, state.fov, state.fov, state.clipNear, state.clipFar);
lovrGraphicsSetProjection(i, projection);
}
lovrGpuResetState();
lovrGraphicsSetCamera(&camera, true);
lovrGraphicsSetBackbuffer(canvas, false, true);
state.renderCallback(state.renderUserdata);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
}

View File

@ -640,22 +640,25 @@ static void vrapi_renderTo(void (*callback)(void*), void* userdata) {
ovrTracking2 tracking = vrapi_GetPredictedTracking2(state.session, state.displayTime);
// Set up camera
Camera camera;
camera.canvas = state.canvases[state.swapchainIndex];
// Camera
for (uint32_t i = 0; i < 2; i++) {
mat4_init(camera.viewMatrix[i], &tracking.Eye[i].ViewMatrix.M[0][0]);
mat4_init(camera.projection[i], &tracking.Eye[i].ProjectionMatrix.M[0][0]);
mat4_transpose(camera.projection[i]);
mat4_transpose(camera.viewMatrix[i]);
camera.viewMatrix[i][13] -= state.offset;
float view[16];
mat4_init(view, &tracking.Eye[i].ViewMatrix.M[0][0]);
mat4_transpose(view);
view[13] -= state.offset;
lovrGraphicsSetViewMatrix(i, view);
float projection[16];
mat4_init(projection, &tracking.Eye[i].ProjectionMatrix.M[0][0]);
mat4_transpose(projection);
lovrGraphicsSetProjection(i, projection);
}
// Render
lovrGraphicsSetCamera(&camera, true);
lovrGraphicsSetBackbuffer(state.canvases[state.swapchainIndex], true, true);
callback(userdata);
lovrGraphicsDiscard(false, true, true);
lovrGraphicsSetCamera(NULL, false);
lovrGraphicsSetBackbuffer(NULL, false, false);
// Submit a layer to VrApi
ovrLayerProjection2 layer = vrapi_DefaultLayerProjection2();

View File

@ -253,6 +253,10 @@ function lovr.errhand(message, traceback)
lovr.headset.renderTo(render)
end
if lovr.graphics.hasWindow() then
lovr.graphics.setViewPose(1)
local width, height = lovr.graphics.getDimensions()
local projection = mat4():perspective(.1, 100, math.rad(67), width / height)
lovr.graphics.setProjection(1, projection)
lovr.graphics.clear()
render()
end

View File

@ -87,12 +87,6 @@ var webxr = {
state.canvas = Module['_lovrCanvasCreateFromHandle'](width, height, flags, state.fbo, 0, 0, 1, true);
Module.stackRestore(flags);
// Camera
var sizeof_Camera = 264;
state.camera = Module._malloc(sizeof_Camera);
HEAPU8[state.camera + 0] = 1; // state.camera.stereo = true
HEAPU32[(state.camera + 4) >> 2] = state.canvas; // state.camera.canvas = state.canvas
state.hands = [];
state.lastButtonState = [];
session.addEventListener('inputsourceschange', function(event) {
@ -118,7 +112,6 @@ var webxr = {
session.addEventListener('end', function() {
Module._free(state.boundsGeometry|0);
Module._free(state.camera|0);
if (state.canvas) {
Module['_lovrCanvasDestroy'](state.canvas);
@ -366,15 +359,19 @@ var webxr = {
webxr_renderTo: function(callback, userdata) {
var views = state.viewer.views;
var matrices = (state.camera + 8) >> 2;
HEAPF32.set(views[0].transform.inverse.matrix, matrices + 0);
HEAPF32.set(views[1].transform.inverse.matrix, matrices + 16);
HEAPF32.set(views[0].projectionMatrix, matrices + 32);
HEAPF32.set(views[1].projectionMatrix, matrices + 48);
Module['_lovrGraphicsSetCamera'](state.camera, true);
var matrix = Module.stackAlloc(16 * 4);
HEAPF32.set(views[0].transform.inverse.matrix, matrix >> 2);
Module['lovrGraphicsSetViewMatrix'](0, matrix);
HEAPF32.set(views[1].transform.inverse.matrix, matrix >> 2);
Module['lovrGraphicsSetViewMatrix'](1, matrix);
HEAPF32.set(views[0].projectionMatrix, matrix >> 2);
Module['_lovrGraphicsSetProjection'](0, matrix);
HEAPF32.set(views[1].projectionMatrix, matrix >> 2);
Module['_lovrGraphicsSetProjection'](1, matrix);
Module.stackRestore();
Module['_lovrGraphicsSetBackbuffer'](state.canvas, true, true);
Module['dynCall_vi'](callback, userdata);
Module['_lovrGraphicsSetCamera'](0, false);
Module['_lovrGraphicsSetBackbuffer'](0, false, false);
},
webxr_update: function(dt) {