mirror of https://github.com/bjornbytes/lovr.git
Clean up drawing;
This commit is contained in:
parent
322c0bdef7
commit
e6e8e137c0
|
@ -57,7 +57,10 @@ int l_lovrMeshDrawInstanced(lua_State* L) {
|
||||||
int instances = luaL_checkinteger(L, 2);
|
int instances = luaL_checkinteger(L, 2);
|
||||||
float transform[16];
|
float transform[16];
|
||||||
luax_readtransform(L, 3, transform, 1);
|
luax_readtransform(L, 3, transform, 1);
|
||||||
lovrGraphicsDraw(mesh, transform, SHADER_DEFAULT, instances);
|
lovrGraphicsPush();
|
||||||
|
lovrGraphicsMatrixTransform(transform);
|
||||||
|
lovrGraphicsDraw(mesh, SHADER_DEFAULT, instances);
|
||||||
|
lovrGraphicsPop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,43 @@
|
||||||
|
#include "graphics/canvas.h"
|
||||||
|
#include "graphics/material.h"
|
||||||
#include "graphics/mesh.h"
|
#include "graphics/mesh.h"
|
||||||
#include "graphics/shader.h"
|
#include "graphics/shader.h"
|
||||||
#include "graphics/texture.h"
|
#include "graphics/texture.h"
|
||||||
|
#include "math/math.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_CANVASES 4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int shaderSwitches;
|
int shaderSwitches;
|
||||||
int drawCalls;
|
int drawCalls;
|
||||||
} GpuStats;
|
} GpuStats;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
float projection[16];
|
||||||
|
float view[16];
|
||||||
|
uint32_t viewport[4];
|
||||||
|
Canvas* canvas[MAX_CANVASES];
|
||||||
|
int canvasCount;
|
||||||
|
bool user;
|
||||||
|
} Layer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Layer layer;
|
||||||
Mesh* mesh;
|
Mesh* mesh;
|
||||||
|
mat4 transform;
|
||||||
|
Material* material;
|
||||||
|
Color color;
|
||||||
|
float pointSize;
|
||||||
Shader* shader;
|
Shader* shader;
|
||||||
int instances;
|
int instances;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
eventually:
|
eventually:
|
||||||
|
|
||||||
Canvas* canvas;
|
|
||||||
uint32_t viewport[4];
|
|
||||||
mat4 view;
|
|
||||||
mat4 projection;
|
|
||||||
mat4 model;
|
|
||||||
|
|
||||||
Color color;
|
|
||||||
float pointSize;
|
|
||||||
|
|
||||||
Material* material;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CompareMode test;
|
CompareMode test;
|
||||||
bool write;
|
bool write;
|
||||||
|
|
|
@ -93,14 +93,13 @@ void lovrGraphicsReset() {
|
||||||
|
|
||||||
void lovrGraphicsClear(bool clearColor, bool clearDepth, bool clearStencil, Color color, float depth, int stencil) {
|
void lovrGraphicsClear(bool clearColor, bool clearDepth, bool clearStencil, Color color, float depth, int stencil) {
|
||||||
Layer layer = state.layers[state.layer];
|
Layer layer = state.layers[state.layer];
|
||||||
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
|
gpuBindFramebuffer(layer.canvasCount > 0 ? lovrCanvasGetId(layer.canvas[0]) : 0);
|
||||||
gpuBindFramebuffer(canvas ? lovrCanvasGetId(canvas) : 0);
|
|
||||||
|
|
||||||
if (clearColor) {
|
if (clearColor) {
|
||||||
gammaCorrectColor(&color);
|
gammaCorrectColor(&color);
|
||||||
float c[4] = { color.r, color.g, color.b, color.a };
|
float c[4] = { color.r, color.g, color.b, color.a };
|
||||||
glClearBufferfv(GL_COLOR, 0, c);
|
glClearBufferfv(GL_COLOR, 0, c);
|
||||||
for (int i = 1; i < state.canvasCount; i++) {
|
for (int i = 1; i < layer.canvasCount; i++) {
|
||||||
glClearBufferfv(GL_COLOR, i, c);
|
glClearBufferfv(GL_COLOR, i, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,46 +262,21 @@ void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsGetCanvas(Canvas** canvas, int* count) {
|
void lovrGraphicsGetCanvas(Canvas** canvas, int* count) {
|
||||||
*count = state.canvasCount;
|
Layer layer = state.layers[state.layer];
|
||||||
memcpy(canvas, state.canvas, state.canvasCount * sizeof(Canvas*));
|
if (layer.user) {
|
||||||
|
*count = layer.canvasCount;
|
||||||
|
memcpy(canvas, layer.canvas, layer.canvasCount * sizeof(Canvas*));
|
||||||
|
} else {
|
||||||
|
*count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
|
void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
|
||||||
if (count == state.canvasCount && !memcmp(state.canvas, canvas, count * sizeof(Canvas*))) {
|
if (state.layers[state.layer].user) {
|
||||||
return;
|
lovrGraphicsPopLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrAssert(count <= MAX_CANVASES, "Attempt to simultaneously render to %d canvases (the maximum is %d)", count, MAX_CANVASES);
|
lovrGraphicsPushLayer(canvas, count, true);
|
||||||
|
|
||||||
if (state.canvasCount > 0) {
|
|
||||||
lovrCanvasResolve(state.canvas[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
lovrRetain(canvas[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < state.canvasCount; i++) {
|
|
||||||
lovrRelease(state.canvas[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
memcpy(state.canvas, canvas, count * sizeof(Canvas*));
|
|
||||||
gpuBindFramebuffer(lovrCanvasGetId(canvas[0]));
|
|
||||||
|
|
||||||
GLenum buffers[MAX_CANVASES];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
buffers[i] = GL_COLOR_ATTACHMENT0 + i;
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[i], GL_TEXTURE_2D, lovrTextureGetId((Texture*) canvas[i]), 0);
|
|
||||||
}
|
|
||||||
glDrawBuffers(count, buffers);
|
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
||||||
lovrAssert(status != GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "All multicanvas canvases must have the same dimensions");
|
|
||||||
lovrAssert(status == GL_FRAMEBUFFER_COMPLETE, "Unable to bind framebuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
state.canvasCount = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Color lovrGraphicsGetColor() {
|
Color lovrGraphicsGetColor() {
|
||||||
|
@ -542,7 +516,7 @@ void lovrGraphicsPoints(uint32_t count) {
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||||
lovrMeshSetMaterial(state.mesh, NULL);
|
lovrMeshSetMaterial(state.mesh, NULL);
|
||||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsLine(uint32_t count) {
|
void lovrGraphicsLine(uint32_t count) {
|
||||||
|
@ -550,7 +524,7 @@ void lovrGraphicsLine(uint32_t count) {
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||||
lovrMeshSetMaterial(state.mesh, NULL);
|
lovrMeshSetMaterial(state.mesh, NULL);
|
||||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
||||||
|
@ -582,7 +556,7 @@ void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
||||||
|
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, 3);
|
lovrMeshSetDrawRange(state.mesh, 0, 3);
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
||||||
|
@ -613,7 +587,10 @@ void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
lovrGraphicsPush();
|
||||||
|
lovrGraphicsMatrixTransform(transform);
|
||||||
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
|
lovrGraphicsPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
||||||
|
@ -695,7 +672,10 @@ void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
lovrGraphicsPush();
|
||||||
|
lovrGraphicsMatrixTransform(transform);
|
||||||
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
|
lovrGraphicsPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 transform, float theta1, float theta2, int segments) {
|
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 transform, float theta1, float theta2, int segments) {
|
||||||
|
@ -742,7 +722,10 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 tr
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshSetDrawMode(state.mesh, mode == DRAW_MODE_LINE ? (arcMode == ARC_MODE_OPEN ? MESH_LINE_STRIP : MESH_LINE_LOOP) : MESH_TRIANGLE_FAN);
|
lovrMeshSetDrawMode(state.mesh, mode == DRAW_MODE_LINE ? (arcMode == ARC_MODE_OPEN ? MESH_LINE_STRIP : MESH_LINE_LOOP) : MESH_TRIANGLE_FAN);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
lovrGraphicsPush();
|
||||||
|
lovrGraphicsMatrixTransform(transform);
|
||||||
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
|
lovrGraphicsPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsCircle(DrawMode mode, Material* material, mat4 transform, int segments) {
|
void lovrGraphicsCircle(DrawMode mode, Material* material, mat4 transform, int segments) {
|
||||||
|
@ -842,7 +825,7 @@ void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, floa
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, indexCount);
|
lovrMeshSetDrawRange(state.mesh, 0, indexCount);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
||||||
|
@ -887,7 +870,10 @@ void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
||||||
lovrMeshSetDrawMode(state.mesh, GL_TRIANGLES);
|
lovrMeshSetDrawMode(state.mesh, GL_TRIANGLES);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, segments * segments * 6);
|
lovrMeshSetDrawRange(state.mesh, 0, segments * segments * 6);
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
lovrGraphicsPush();
|
||||||
|
lovrGraphicsMatrixTransform(transform);
|
||||||
|
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||||
|
lovrGraphicsPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float az) {
|
void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float az) {
|
||||||
|
@ -912,7 +898,7 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, shader, 1);
|
lovrGraphicsDraw(state.mesh, shader, 1);
|
||||||
lovrMaterialSetTexture(material, materialTexture, NULL);
|
lovrMaterialSetTexture(material, materialTexture, NULL);
|
||||||
lovrGraphicsSetWinding(winding);
|
lovrGraphicsSetWinding(winding);
|
||||||
}
|
}
|
||||||
|
@ -940,7 +926,7 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, vertexCount);
|
lovrMeshSetDrawRange(state.mesh, 0, vertexCount);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FONT, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_FONT, 1);
|
||||||
lovrGraphicsSetDepthTest(mode, write);
|
lovrGraphicsSetDepthTest(mode, write);
|
||||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||||
lovrGraphicsPop();
|
lovrGraphicsPop();
|
||||||
|
@ -1000,70 +986,19 @@ void lovrGraphicsFill(Texture* texture) {
|
||||||
lovrMeshSetMaterial(state.mesh, material);
|
lovrMeshSetMaterial(state.mesh, material);
|
||||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FILL, 1);
|
lovrGraphicsDraw(state.mesh, SHADER_FILL, 1);
|
||||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||||
lovrGraphicsSetDepthTest(mode, write);
|
lovrGraphicsSetDepthTest(mode, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, int instances) {
|
void lovrGraphicsDraw(Mesh* mesh, DefaultShader defaultShader, int instances) {
|
||||||
|
|
||||||
// Layer
|
|
||||||
Layer layer = state.layers[state.layer];
|
|
||||||
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
|
|
||||||
gpuBindFramebuffer(canvas ? lovrCanvasGetId(canvas) : 0);
|
|
||||||
gpuSetViewport(state.canvasCount > 0 ?
|
|
||||||
(uint32_t[4]) { 0, 0, lovrTextureGetWidth((Texture*) state.canvas[0]), lovrTextureGetHeight((Texture*) state.canvas[0]) } :
|
|
||||||
layer.viewport
|
|
||||||
);
|
|
||||||
|
|
||||||
// Transforms
|
|
||||||
if (transform) {
|
|
||||||
lovrGraphicsPush();
|
|
||||||
lovrGraphicsMatrixTransform(transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader* shader = state.shader ? state.shader : state.defaultShaders[defaultShader];
|
Shader* shader = state.shader ? state.shader : state.defaultShaders[defaultShader];
|
||||||
|
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
shader = state.defaultShaders[defaultShader] = lovrShaderCreateDefault(defaultShader);
|
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 modelView[16];
|
|
||||||
mat4_multiply(mat4_set(modelView, layer.view), model);
|
|
||||||
lovrShaderSetMatrix(shader, "lovrTransform", modelView, 16);
|
|
||||||
|
|
||||||
if (lovrShaderHasUniform(shader, "lovrNormalMatrix")) {
|
|
||||||
if (mat4_invert(modelView)) {
|
|
||||||
mat4_transpose(modelView);
|
|
||||||
} else {
|
|
||||||
mat4_identity(modelView);
|
|
||||||
}
|
|
||||||
|
|
||||||
float normalMatrix[9] = {
|
|
||||||
modelView[0], modelView[1], modelView[2],
|
|
||||||
modelView[4], modelView[5], modelView[6],
|
|
||||||
modelView[8], modelView[9], modelView[10],
|
|
||||||
};
|
|
||||||
|
|
||||||
lovrShaderSetMatrix(shader, "lovrNormalMatrix", normalMatrix, 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color
|
|
||||||
Color color = state.color;
|
|
||||||
gammaCorrectColor(&color);
|
|
||||||
float data[4] = { color.r, color.g, color.b, color.a };
|
|
||||||
lovrShaderSetFloat(shader, "lovrColor", data, 4);
|
|
||||||
|
|
||||||
// Point size
|
|
||||||
lovrShaderSetFloat(shader, "lovrPointSize", &state.pointSize, 1);
|
|
||||||
|
|
||||||
// Pose
|
// Pose
|
||||||
float* pose = lovrMeshGetPose(mesh);
|
float* pose = lovrMeshGetPose(mesh);
|
||||||
if (pose) {
|
if (pose) {
|
||||||
|
@ -1076,51 +1011,59 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
Material* material = lovrMeshGetMaterial(mesh);
|
Material* material = lovrMeshGetMaterial(mesh);
|
||||||
|
material = material ? material : lovrGraphicsGetDefaultMaterial();
|
||||||
if (!material) {
|
|
||||||
material = lovrGraphicsGetDefaultMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MATERIAL_SCALARS; i++) {
|
|
||||||
float value = lovrMaterialGetScalar(material, i);
|
|
||||||
lovrShaderSetFloat(shader, lovrShaderScalarUniforms[i], &value, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
|
|
||||||
Color color = lovrMaterialGetColor(material, i);
|
|
||||||
gammaCorrectColor(&color);
|
|
||||||
float data[4] = { color.r, color.g, color.b, color.a };
|
|
||||||
lovrShaderSetFloat(shader, lovrShaderColorUniforms[i], data, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
|
||||||
Texture* texture = lovrMaterialGetTexture(material, i);
|
|
||||||
lovrShaderSetTexture(shader, lovrShaderTextureUniforms[i], &texture, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpuDraw(&(GpuDrawCommand) {
|
gpuDraw(&(GpuDrawCommand) {
|
||||||
.mesh = mesh,
|
.layer = state.layers[state.layer],
|
||||||
.shader = shader,
|
.shader = shader,
|
||||||
|
.material = material,
|
||||||
|
.transform = state.transforms[state.transform],
|
||||||
|
.mesh = mesh,
|
||||||
|
.color = state.color,
|
||||||
|
.pointSize = state.pointSize,
|
||||||
.instances = instances
|
.instances = instances
|
||||||
});
|
});
|
||||||
|
|
||||||
if (transform) {
|
|
||||||
lovrGraphicsPop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsPushLayer(Canvas* canvas) {
|
void lovrGraphicsPushLayer(Canvas** canvas, int count, bool user) {
|
||||||
if (++state.layer >= MAX_LAYERS) {
|
lovrAssert(count <= MAX_CANVASES, "Attempt to set %d canvases (the maximum is %d)", count, MAX_CANVASES);
|
||||||
lovrThrow("Layer overflow");
|
lovrAssert(++state.layer < MAX_LAYERS, "Layer overflow");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
lovrRetain(canvas[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&state.layers[state.layer], &state.layers[state.layer - 1], sizeof(Layer));
|
Layer* prevLayer = &state.layers[state.layer - 1];
|
||||||
state.layers[state.layer].canvas = canvas;
|
for (int i = 0; i < prevLayer->canvasCount; i++) {
|
||||||
|
lovrRelease(prevLayer->canvas[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer* layer = &state.layers[state.layer];
|
||||||
|
memcpy(layer, prevLayer, sizeof(Layer));
|
||||||
|
layer->canvasCount = count;
|
||||||
|
layer->user = user;
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
memcpy(layer->canvas, canvas, count * sizeof(Canvas*));
|
||||||
|
gpuBindFramebuffer(lovrCanvasGetId(canvas[0]));
|
||||||
|
|
||||||
|
GLenum buffers[MAX_CANVASES];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
buffers[i] = GL_COLOR_ATTACHMENT0 + i;
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[i], GL_TEXTURE_2D, lovrTextureGetId((Texture*) canvas[i]), 0);
|
||||||
|
}
|
||||||
|
glDrawBuffers(count, buffers);
|
||||||
|
|
||||||
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
lovrAssert(status != GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "All multicanvas canvases must have the same dimensions");
|
||||||
|
lovrAssert(status == GL_FRAMEBUFFER_COMPLETE, "Unable to bind framebuffer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsPopLayer() {
|
void lovrGraphicsPopLayer() {
|
||||||
if (state.canvasCount == 0 && state.layers[state.layer].canvas) {
|
Layer* layer = &state.layers[state.layer];
|
||||||
lovrCanvasResolve(state.layers[state.layer].canvas);
|
if (layer->canvasCount > 0) {
|
||||||
|
lovrCanvasResolve(layer->canvas[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrAssert(--state.layer >= 0, "Layer underflow");
|
lovrAssert(--state.layer >= 0, "Layer underflow");
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MAX_CANVASES 4
|
|
||||||
#define MAX_LAYERS 4
|
#define MAX_LAYERS 4
|
||||||
#define MAX_TRANSFORMS 60
|
#define MAX_TRANSFORMS 60
|
||||||
#define INTERNAL_TRANSFORMS 4
|
#define INTERNAL_TRANSFORMS 4
|
||||||
|
@ -72,13 +71,6 @@ typedef enum {
|
||||||
STENCIL_INVERT
|
STENCIL_INVERT
|
||||||
} StencilAction;
|
} StencilAction;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float projection[16];
|
|
||||||
float view[16];
|
|
||||||
Canvas* canvas;
|
|
||||||
uint32_t viewport[4];
|
|
||||||
} Layer;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool initialized;
|
bool initialized;
|
||||||
float pointSizes[2];
|
float pointSizes[2];
|
||||||
|
@ -100,8 +92,6 @@ typedef struct {
|
||||||
Color backgroundColor;
|
Color backgroundColor;
|
||||||
BlendMode blendMode;
|
BlendMode blendMode;
|
||||||
BlendAlphaMode blendAlphaMode;
|
BlendAlphaMode blendAlphaMode;
|
||||||
Canvas* canvas[MAX_CANVASES];
|
|
||||||
int canvasCount;
|
|
||||||
Color color;
|
Color color;
|
||||||
bool culling;
|
bool culling;
|
||||||
TextureFilter defaultFilter;
|
TextureFilter defaultFilter;
|
||||||
|
@ -191,9 +181,9 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
|
||||||
void lovrGraphicsFill(Texture* texture);
|
void lovrGraphicsFill(Texture* texture);
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader shader, int instances);
|
void lovrGraphicsDraw(Mesh* mesh, DefaultShader shader, int instances);
|
||||||
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
|
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
|
||||||
void lovrGraphicsPushLayer(Canvas* canvas);
|
void lovrGraphicsPushLayer(Canvas** canvas, int count, bool user);
|
||||||
void lovrGraphicsPopLayer();
|
void lovrGraphicsPopLayer();
|
||||||
void lovrGraphicsSetCamera(mat4 projection, mat4 view);
|
void lovrGraphicsSetCamera(mat4 projection, mat4 view);
|
||||||
void lovrGraphicsSetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
void lovrGraphicsSetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||||
|
|
|
@ -43,7 +43,7 @@ static void renderNode(Model* model, int nodeIndex, int instances) {
|
||||||
|
|
||||||
lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount);
|
lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount);
|
||||||
lovrMeshSetPose(model->mesh, (float*) model->pose);
|
lovrMeshSetPose(model->mesh, (float*) model->pose);
|
||||||
lovrGraphicsDraw(model->mesh, NULL, SHADER_DEFAULT, instances);
|
lovrGraphicsDraw(model->mesh, SHADER_DEFAULT, instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrGraphicsPop();
|
lovrGraphicsPop();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "graphics/gpu.h"
|
#include "graphics/gpu.h"
|
||||||
#include "graphics/opengl/opengl.h"
|
#include "graphics/opengl/opengl.h"
|
||||||
|
#include "resources/shaders.h"
|
||||||
|
#include "math/mat4.h"
|
||||||
#include "lib/glfw.h"
|
#include "lib/glfw.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -14,9 +16,18 @@ static struct {
|
||||||
uint32_t vertexArray;
|
uint32_t vertexArray;
|
||||||
uint32_t vertexBuffer;
|
uint32_t vertexBuffer;
|
||||||
uint32_t viewport[4];
|
uint32_t viewport[4];
|
||||||
|
bool srgb;
|
||||||
GpuStats stats;
|
GpuStats stats;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
|
static void gammaCorrectColor(Color* color) {
|
||||||
|
if (state.srgb) {
|
||||||
|
color->r = lovrMathGammaToLinear(color->r);
|
||||||
|
color->g = lovrMathGammaToLinear(color->g);
|
||||||
|
color->b = lovrMathGammaToLinear(color->b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
|
void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
|
||||||
#ifndef EMSCRIPTEN
|
#ifndef EMSCRIPTEN
|
||||||
gladLoadGLLoader((GLADloadproc) getProcAddress);
|
gladLoadGLLoader((GLADloadproc) getProcAddress);
|
||||||
|
@ -31,6 +42,7 @@ void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
state.srgb = srgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpuDestroy() {
|
void gpuDestroy() {
|
||||||
|
@ -42,14 +54,74 @@ void gpuDestroy() {
|
||||||
|
|
||||||
void gpuDraw(GpuDrawCommand* command) {
|
void gpuDraw(GpuDrawCommand* command) {
|
||||||
Mesh* mesh = command->mesh;
|
Mesh* mesh = command->mesh;
|
||||||
|
Material* material = command->material;
|
||||||
Shader* shader = command->shader;
|
Shader* shader = command->shader;
|
||||||
int instances = command->instances;
|
int instances = command->instances;
|
||||||
|
|
||||||
|
// Transform
|
||||||
|
lovrShaderSetMatrix(shader, "lovrProjection", command->layer.projection, 16);
|
||||||
|
lovrShaderSetMatrix(shader, "lovrView", command->layer.view, 16);
|
||||||
|
lovrShaderSetMatrix(shader, "lovrModel", command->transform, 16);
|
||||||
|
|
||||||
|
float modelView[16];
|
||||||
|
mat4_multiply(mat4_set(modelView, command->layer.view), command->transform);
|
||||||
|
lovrShaderSetMatrix(shader, "lovrTransform", modelView, 16);
|
||||||
|
|
||||||
|
if (lovrShaderHasUniform(shader, "lovrNormalMatrix")) {
|
||||||
|
if (mat4_invert(modelView)) {
|
||||||
|
mat4_transpose(modelView);
|
||||||
|
} else {
|
||||||
|
mat4_identity(modelView);
|
||||||
|
}
|
||||||
|
|
||||||
|
float normalMatrix[9] = {
|
||||||
|
modelView[0], modelView[1], modelView[2],
|
||||||
|
modelView[4], modelView[5], modelView[6],
|
||||||
|
modelView[8], modelView[9], modelView[10],
|
||||||
|
};
|
||||||
|
|
||||||
|
lovrShaderSetMatrix(shader, "lovrNormalMatrix", normalMatrix, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Point size
|
||||||
|
lovrShaderSetFloat(shader, "lovrPointSize", &command->pointSize, 1);
|
||||||
|
|
||||||
|
// Color
|
||||||
|
Color color = command->color;
|
||||||
|
gammaCorrectColor(&color);
|
||||||
|
float data[4] = { color.r, color.g, color.b, color.a };
|
||||||
|
lovrShaderSetFloat(shader, "lovrColor", data, 4);
|
||||||
|
|
||||||
|
// Material
|
||||||
|
for (int i = 0; i < MAX_MATERIAL_SCALARS; i++) {
|
||||||
|
float value = lovrMaterialGetScalar(material, i);
|
||||||
|
lovrShaderSetFloat(shader, lovrShaderScalarUniforms[i], &value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
|
||||||
|
Color color = lovrMaterialGetColor(material, i);
|
||||||
|
gammaCorrectColor(&color);
|
||||||
|
float data[4] = { color.r, color.g, color.b, color.a };
|
||||||
|
lovrShaderSetFloat(shader, lovrShaderColorUniforms[i], data, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
||||||
|
Texture* texture = lovrMaterialGetTexture(material, i);
|
||||||
|
lovrShaderSetTexture(shader, lovrShaderTextureUniforms[i], &texture, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer
|
||||||
|
gpuBindFramebuffer(command->layer.canvasCount > 0 ? lovrCanvasGetId(command->layer.canvas[0]) : 0);
|
||||||
|
gpuSetViewport(command->layer.viewport);
|
||||||
|
|
||||||
|
// Shader
|
||||||
gpuUseProgram(lovrShaderGetProgram(shader));
|
gpuUseProgram(lovrShaderGetProgram(shader));
|
||||||
lovrShaderBind(shader);
|
lovrShaderBind(shader);
|
||||||
|
|
||||||
|
// Attributes
|
||||||
lovrMeshBind(mesh, shader);
|
lovrMeshBind(mesh, shader);
|
||||||
|
|
||||||
// TODEW
|
// Draw (TODEW)
|
||||||
uint32_t rangeStart, rangeCount;
|
uint32_t rangeStart, rangeCount;
|
||||||
lovrMeshGetDrawRange(mesh, &rangeStart, &rangeCount);
|
lovrMeshGetDrawRange(mesh, &rangeStart, &rangeCount);
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
|
|
|
@ -292,7 +292,7 @@ static void fakeRenderTo(void (*callback)(void*), void* userdata) {
|
||||||
mat4_multiply(view, state.transform);
|
mat4_multiply(view, state.transform);
|
||||||
mat4_invert(view);
|
mat4_invert(view);
|
||||||
|
|
||||||
lovrGraphicsPushLayer(NULL);
|
lovrGraphicsPushLayer(NULL, 0, false);
|
||||||
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||||
lovrGraphicsSetCamera(projection, view);
|
lovrGraphicsSetCamera(projection, view);
|
||||||
lovrGraphicsSetViewport(0, 0, width, height);
|
lovrGraphicsSetViewport(0, 0, width, height);
|
||||||
|
|
|
@ -671,7 +671,7 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
|
||||||
state.compositor->WaitGetPoses(state.renderPoses, 16, NULL, 0);
|
state.compositor->WaitGetPoses(state.renderPoses, 16, NULL, 0);
|
||||||
mat4_fromMat34(head, state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m);
|
mat4_fromMat34(head, state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m);
|
||||||
|
|
||||||
lovrGraphicsPushLayer(state.canvas);
|
lovrGraphicsPushLayer(&state.canvas, 1, false);
|
||||||
lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0);
|
lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||||
|
|
||||||
for (HeadsetEye i = EYE_LEFT; i <= EYE_RIGHT; i++) {
|
for (HeadsetEye i = EYE_LEFT; i <= EYE_RIGHT; i++) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void onMountChanged(bool mounted) {
|
||||||
static void onFrame(float* leftView, float* rightView, float* leftProjection, float* rightProjection, void* userdata) {
|
static void onFrame(float* leftView, float* rightView, float* leftProjection, float* rightProjection, void* userdata) {
|
||||||
int width, height;
|
int width, height;
|
||||||
webvrGetDisplayDimensions(&width, &height);
|
webvrGetDisplayDimensions(&width, &height);
|
||||||
lovrGraphicsPushLayer(NULL);
|
lovrGraphicsPushLayer(NULL, 0, false);
|
||||||
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||||
lovrGraphicsSetCamera(leftProjection, leftView);
|
lovrGraphicsSetCamera(leftProjection, leftView);
|
||||||
lovrGraphicsSetViewport(0, 0, width, height);
|
lovrGraphicsSetViewport(0, 0, width, height);
|
||||||
|
|
Loading…
Reference in New Issue