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);
|
||||
float transform[16];
|
||||
luax_readtransform(L, 3, transform, 1);
|
||||
lovrGraphicsDraw(mesh, transform, SHADER_DEFAULT, instances);
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsMatrixTransform(transform);
|
||||
lovrGraphicsDraw(mesh, SHADER_DEFAULT, instances);
|
||||
lovrGraphicsPop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,43 @@
|
|||
#include "graphics/canvas.h"
|
||||
#include "graphics/material.h"
|
||||
#include "graphics/mesh.h"
|
||||
#include "graphics/shader.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "math/math.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MAX_CANVASES 4
|
||||
|
||||
typedef struct {
|
||||
int shaderSwitches;
|
||||
int drawCalls;
|
||||
} GpuStats;
|
||||
|
||||
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;
|
||||
mat4 transform;
|
||||
Material* material;
|
||||
Color color;
|
||||
float pointSize;
|
||||
Shader* shader;
|
||||
int instances;
|
||||
|
||||
/*
|
||||
eventually:
|
||||
|
||||
Canvas* canvas;
|
||||
uint32_t viewport[4];
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
mat4 model;
|
||||
|
||||
Color color;
|
||||
float pointSize;
|
||||
|
||||
Material* material;
|
||||
|
||||
struct {
|
||||
CompareMode test;
|
||||
bool write;
|
||||
|
|
|
@ -93,14 +93,13 @@ void lovrGraphicsReset() {
|
|||
|
||||
void lovrGraphicsClear(bool clearColor, bool clearDepth, bool clearStencil, Color color, float depth, int stencil) {
|
||||
Layer layer = state.layers[state.layer];
|
||||
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
|
||||
gpuBindFramebuffer(canvas ? lovrCanvasGetId(canvas) : 0);
|
||||
gpuBindFramebuffer(layer.canvasCount > 0 ? lovrCanvasGetId(layer.canvas[0]) : 0);
|
||||
|
||||
if (clearColor) {
|
||||
gammaCorrectColor(&color);
|
||||
float c[4] = { color.r, color.g, color.b, color.a };
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -263,46 +262,21 @@ void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) {
|
|||
}
|
||||
|
||||
void lovrGraphicsGetCanvas(Canvas** canvas, int* count) {
|
||||
*count = state.canvasCount;
|
||||
memcpy(canvas, state.canvas, state.canvasCount * sizeof(Canvas*));
|
||||
Layer layer = state.layers[state.layer];
|
||||
if (layer.user) {
|
||||
*count = layer.canvasCount;
|
||||
memcpy(canvas, layer.canvas, layer.canvasCount * sizeof(Canvas*));
|
||||
} else {
|
||||
*count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
|
||||
if (count == state.canvasCount && !memcmp(state.canvas, canvas, count * sizeof(Canvas*))) {
|
||||
return;
|
||||
if (state.layers[state.layer].user) {
|
||||
lovrGraphicsPopLayer();
|
||||
}
|
||||
|
||||
lovrAssert(count <= MAX_CANVASES, "Attempt to simultaneously render to %d canvases (the maximum is %d)", count, MAX_CANVASES);
|
||||
|
||||
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;
|
||||
lovrGraphicsPushLayer(canvas, count, true);
|
||||
}
|
||||
|
||||
Color lovrGraphicsGetColor() {
|
||||
|
@ -542,7 +516,7 @@ void lovrGraphicsPoints(uint32_t count) {
|
|||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||
lovrMeshSetMaterial(state.mesh, NULL);
|
||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
||||
lovrGraphicsDraw(state.mesh, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsLine(uint32_t count) {
|
||||
|
@ -550,7 +524,7 @@ void lovrGraphicsLine(uint32_t count) {
|
|||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||
lovrMeshSetMaterial(state.mesh, NULL);
|
||||
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]) {
|
||||
|
@ -582,7 +556,7 @@ void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
|||
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 3);
|
||||
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) {
|
||||
|
@ -613,7 +587,10 @@ void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||
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) {
|
||||
|
@ -695,7 +672,10 @@ void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -742,7 +722,10 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 tr
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
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);
|
||||
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) {
|
||||
|
@ -842,7 +825,7 @@ void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, floa
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
||||
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) {
|
||||
|
@ -887,7 +870,10 @@ void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
|||
lovrMeshSetDrawMode(state.mesh, GL_TRIANGLES);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, segments * segments * 6);
|
||||
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) {
|
||||
|
@ -912,7 +898,7 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||
lovrGraphicsDraw(state.mesh, NULL, shader, 1);
|
||||
lovrGraphicsDraw(state.mesh, shader, 1);
|
||||
lovrMaterialSetTexture(material, materialTexture, NULL);
|
||||
lovrGraphicsSetWinding(winding);
|
||||
}
|
||||
|
@ -940,7 +926,7 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, vertexCount);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FONT, 1);
|
||||
lovrGraphicsDraw(state.mesh, SHADER_FONT, 1);
|
||||
lovrGraphicsSetDepthTest(mode, write);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||
lovrGraphicsPop();
|
||||
|
@ -1000,70 +986,19 @@ void lovrGraphicsFill(Texture* texture) {
|
|||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FILL, 1);
|
||||
lovrGraphicsDraw(state.mesh, SHADER_FILL, 1);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||
lovrGraphicsSetDepthTest(mode, write);
|
||||
}
|
||||
|
||||
// Internal
|
||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, 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);
|
||||
}
|
||||
|
||||
void lovrGraphicsDraw(Mesh* mesh, DefaultShader defaultShader, int instances) {
|
||||
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 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
|
||||
float* pose = lovrMeshGetPose(mesh);
|
||||
if (pose) {
|
||||
|
@ -1076,51 +1011,59 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i
|
|||
|
||||
// Material
|
||||
Material* material = lovrMeshGetMaterial(mesh);
|
||||
|
||||
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);
|
||||
}
|
||||
material = material ? material : lovrGraphicsGetDefaultMaterial();
|
||||
|
||||
gpuDraw(&(GpuDrawCommand) {
|
||||
.mesh = mesh,
|
||||
.layer = state.layers[state.layer],
|
||||
.shader = shader,
|
||||
.material = material,
|
||||
.transform = state.transforms[state.transform],
|
||||
.mesh = mesh,
|
||||
.color = state.color,
|
||||
.pointSize = state.pointSize,
|
||||
.instances = instances
|
||||
});
|
||||
|
||||
if (transform) {
|
||||
lovrGraphicsPop();
|
||||
}
|
||||
}
|
||||
|
||||
void lovrGraphicsPushLayer(Canvas* canvas) {
|
||||
if (++state.layer >= MAX_LAYERS) {
|
||||
lovrThrow("Layer overflow");
|
||||
void lovrGraphicsPushLayer(Canvas** canvas, int count, bool user) {
|
||||
lovrAssert(count <= MAX_CANVASES, "Attempt to set %d canvases (the maximum is %d)", count, MAX_CANVASES);
|
||||
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));
|
||||
state.layers[state.layer].canvas = canvas;
|
||||
Layer* prevLayer = &state.layers[state.layer - 1];
|
||||
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() {
|
||||
if (state.canvasCount == 0 && state.layers[state.layer].canvas) {
|
||||
lovrCanvasResolve(state.layers[state.layer].canvas);
|
||||
Layer* layer = &state.layers[state.layer];
|
||||
if (layer->canvasCount > 0) {
|
||||
lovrCanvasResolve(layer->canvas[0]);
|
||||
}
|
||||
|
||||
lovrAssert(--state.layer >= 0, "Layer underflow");
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define MAX_CANVASES 4
|
||||
#define MAX_LAYERS 4
|
||||
#define MAX_TRANSFORMS 60
|
||||
#define INTERNAL_TRANSFORMS 4
|
||||
|
@ -72,13 +71,6 @@ typedef enum {
|
|||
STENCIL_INVERT
|
||||
} StencilAction;
|
||||
|
||||
typedef struct {
|
||||
float projection[16];
|
||||
float view[16];
|
||||
Canvas* canvas;
|
||||
uint32_t viewport[4];
|
||||
} Layer;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
float pointSizes[2];
|
||||
|
@ -100,8 +92,6 @@ typedef struct {
|
|||
Color backgroundColor;
|
||||
BlendMode blendMode;
|
||||
BlendAlphaMode blendAlphaMode;
|
||||
Canvas* canvas[MAX_CANVASES];
|
||||
int canvasCount;
|
||||
Color color;
|
||||
bool culling;
|
||||
TextureFilter defaultFilter;
|
||||
|
@ -191,9 +181,9 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
|
|||
void lovrGraphicsFill(Texture* texture);
|
||||
|
||||
// Internal
|
||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader shader, int instances);
|
||||
void lovrGraphicsDraw(Mesh* mesh, DefaultShader shader, int instances);
|
||||
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
|
||||
void lovrGraphicsPushLayer(Canvas* canvas);
|
||||
void lovrGraphicsPushLayer(Canvas** canvas, int count, bool user);
|
||||
void lovrGraphicsPopLayer();
|
||||
void lovrGraphicsSetCamera(mat4 projection, mat4 view);
|
||||
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);
|
||||
lovrMeshSetPose(model->mesh, (float*) model->pose);
|
||||
lovrGraphicsDraw(model->mesh, NULL, SHADER_DEFAULT, instances);
|
||||
lovrGraphicsDraw(model->mesh, SHADER_DEFAULT, instances);
|
||||
}
|
||||
|
||||
lovrGraphicsPop();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "graphics/gpu.h"
|
||||
#include "graphics/opengl/opengl.h"
|
||||
#include "resources/shaders.h"
|
||||
#include "math/mat4.h"
|
||||
#include "lib/glfw.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -14,9 +16,18 @@ static struct {
|
|||
uint32_t vertexArray;
|
||||
uint32_t vertexBuffer;
|
||||
uint32_t viewport[4];
|
||||
bool srgb;
|
||||
GpuStats stats;
|
||||
} 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*)) {
|
||||
#ifndef EMSCRIPTEN
|
||||
gladLoadGLLoader((GLADloadproc) getProcAddress);
|
||||
|
@ -31,6 +42,7 @@ void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
state.srgb = srgb;
|
||||
}
|
||||
|
||||
void gpuDestroy() {
|
||||
|
@ -42,14 +54,74 @@ void gpuDestroy() {
|
|||
|
||||
void gpuDraw(GpuDrawCommand* command) {
|
||||
Mesh* mesh = command->mesh;
|
||||
Material* material = command->material;
|
||||
Shader* shader = command->shader;
|
||||
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));
|
||||
lovrShaderBind(shader);
|
||||
|
||||
// Attributes
|
||||
lovrMeshBind(mesh, shader);
|
||||
|
||||
// TODEW
|
||||
// Draw (TODEW)
|
||||
uint32_t rangeStart, rangeCount;
|
||||
lovrMeshGetDrawRange(mesh, &rangeStart, &rangeCount);
|
||||
uint32_t indexCount;
|
||||
|
|
|
@ -292,7 +292,7 @@ static void fakeRenderTo(void (*callback)(void*), void* userdata) {
|
|||
mat4_multiply(view, state.transform);
|
||||
mat4_invert(view);
|
||||
|
||||
lovrGraphicsPushLayer(NULL);
|
||||
lovrGraphicsPushLayer(NULL, 0, false);
|
||||
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
lovrGraphicsSetCamera(projection, view);
|
||||
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);
|
||||
mat4_fromMat34(head, state.renderPoses[state.headsetIndex].mDeviceToAbsoluteTracking.m);
|
||||
|
||||
lovrGraphicsPushLayer(state.canvas);
|
||||
lovrGraphicsPushLayer(&state.canvas, 1, false);
|
||||
lovrGraphicsClear(true, true, false, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
|
||||
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) {
|
||||
int width, height;
|
||||
webvrGetDisplayDimensions(&width, &height);
|
||||
lovrGraphicsPushLayer(NULL);
|
||||
lovrGraphicsPushLayer(NULL, 0, false);
|
||||
lovrGraphicsClear(true, true, true, lovrGraphicsGetBackgroundColor(), 1., 0);
|
||||
lovrGraphicsSetCamera(leftProjection, leftView);
|
||||
lovrGraphicsSetViewport(0, 0, width, height);
|
||||
|
|
Loading…
Reference in New Issue