mirror of https://github.com/bjornbytes/lovr.git
Mostly remove instanced stereo rendering;
This commit is contained in:
parent
7273811120
commit
6ff7292333
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ typedef struct {
|
|||
int msaa;
|
||||
bool depth;
|
||||
bool stencil;
|
||||
bool stereo;
|
||||
bool mipmaps;
|
||||
} CanvasFlags;
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue