Clean up viewports;

This commit is contained in:
bjorn 2018-08-28 21:16:19 -07:00
parent 26f411f43f
commit 8bb45f4de4
4 changed files with 44 additions and 25 deletions

View File

@ -29,5 +29,6 @@ void lovrCanvasDestroy(void* ref);
const Attachment* lovrCanvasGetAttachments(Canvas* canvas, int* count);
void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, int count);
void lovrCanvasBind(Canvas* canvas);
bool lovrCanvasIsStereo(Canvas* canvas);
uint32_t lovrCanvasGetWidth(Canvas* canvas);
uint32_t lovrCanvasGetHeight(Canvas* canvas);

View File

@ -402,11 +402,27 @@ void lovrGraphicsDraw(DrawOptions* draw) {
}
}
Canvas* canvas = state.pipelines[state.pipeline].canvas ? state.pipelines[state.pipeline].canvas : state.camera.canvas;
int width, height;
if (!canvas) {
lovrGraphicsGetDimensions(&width, &height);
} else {
width = lovrCanvasGetWidth(canvas);
height = lovrCanvasGetHeight(canvas);
}
bool stereo = !draw->forceMono && (!canvas || lovrCanvasIsStereo(canvas));
int viewportCount = 1 + !!stereo;
float w = stereo ? ((float) width / 2) : width;
float h = height;
DrawCommand command = {
.mesh = mesh,
.canvas = canvas,
.shader = shader,
.material = material,
.camera = state.camera,
.viewports = { { 0, 0, w, h }, { w, 0, w, h } },
.viewportCount = viewportCount,
.pipeline = state.pipelines[state.pipeline],
.instances = draw->instances
};
@ -792,6 +808,7 @@ void lovrGraphicsFill(Texture* texture) {
lovrGraphicsPushPipeline();
lovrGraphicsSetDepthTest(COMPARE_NONE, false);
lovrGraphicsDraw(&(DrawOptions) {
.forceMono = true,
.shader = SHADER_FILL,
.textures[TEXTURE_DIFFUSE] = texture,
.mode = MESH_TRIANGLE_STRIP,

View File

@ -138,15 +138,19 @@ typedef struct {
Material* material;
Texture* textures[MAX_MATERIAL_TEXTURES];
mat4 transform;
bool forceMono;
int instances;
} DrawOptions;
typedef struct {
Mesh* mesh;
Canvas* canvas;
Shader* shader;
Material* material;
Camera camera;
float transform[16];
float viewports[2][4];
int viewportCount;
Pipeline pipeline;
int instances;
} DrawCommand;

View File

@ -535,6 +535,18 @@ static void lovrGpuUseProgram(uint32_t program) {
}
}
static void lovrGpuSetViewports(float viewports[][4], int viewportCount, int index) {
#ifdef GL_ARB_viewport_array
if (state.supportsSinglepass) {
glViewportArrayv(0, viewportCount, viewports);
} else {
#endif
glViewport(viewports[index][0], viewports[index][1], viewports[index][2], viewports[index][3]);
#ifdef GL_ARB_viewport_array
}
#endif
}
void lovrGpuInit(bool srgb, bool singlepass, gpuProc (*getProcAddress)(const char*)) {
#ifndef EMSCRIPTEN
gladLoadGLLoader((GLADloadproc) getProcAddress);
@ -638,8 +650,9 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
void lovrGpuDraw(DrawCommand* command) {
Mesh* mesh = command->mesh;
Material* material = command->material;
Canvas* canvas = command->canvas;
Shader* shader = command->shader;
Material* material = command->material;
Pipeline* pipeline = &command->pipeline;
int instances = command->instances;
@ -854,36 +867,16 @@ void lovrGpuDraw(DrawCommand* command) {
lovrMeshBind(mesh, shader);
// Canvas
Canvas* canvas = pipeline->canvas ? pipeline->canvas : command->camera.canvas;
bool stereo = !canvas || canvas->flags.stereo;
int width, height;
if (canvas) {
width = canvas->width;
height = canvas->height;
} else {
lovrGraphicsGetDimensions(&width, &height);
}
width >>= stereo == true;
float viewports[2][4] = { { 0, 0, width, height }, { width, 0, width, height } };
int drawCount = 1 + (stereo && !state.singlepass);
lovrCanvasBind(canvas);
// Draw (TODEW)
int drawCount = state.supportsSinglepass ? 1 : command->viewportCount;
for (int i = 0; i < drawCount; i++) {
#ifdef GL_ARB_viewport_array
if (stereo && state.singlepass) {
glViewportArrayv(0, 2, viewports[0]);
} else {
#endif
glViewport(viewports[i][0], viewports[i][1], viewports[i][2], viewports[i][3]);
#ifdef GL_ARB_viewport_array
}
#endif
lovrGpuSetViewports(command->viewports, command->viewportCount, i);
// Bind uniforms
lovrShaderSetInts(shader, "lovrIsStereo", &(int) { stereo && state.singlepass }, 0, 1);
lovrShaderSetInts(shader, "_lovrEye", &i, 0, 1);
int eye = (command->viewportCount > 1 && state.singlepass) ? -1 : i;
lovrShaderSetInts(shader, "lovrEye", &eye, 0, 1);
lovrShaderBind(shader);
uint32_t rangeStart, rangeCount;
@ -1361,6 +1354,10 @@ void lovrCanvasBind(Canvas* canvas) {
canvas->dirty = false;
}
bool lovrCanvasIsStereo(Canvas* canvas) {
return canvas->flags.stereo;
}
uint32_t lovrCanvasGetWidth(Canvas* canvas) {
return canvas->width;
}