Organization;

This commit is contained in:
bjorn 2018-07-15 17:05:06 -07:00
parent b4752dd6a1
commit 56bbf1cf56
8 changed files with 281 additions and 270 deletions

View File

@ -281,53 +281,6 @@ int l_lovrGraphicsInit(lua_State* L) {
return 1;
}
int l_lovrGraphicsReset(lua_State* L) {
lovrGraphicsReset();
return 0;
}
int l_lovrGraphicsClear(lua_State* L) {
int index = 1;
int top = lua_gettop(L);
bool clearColor = true;
bool clearDepth = true;
bool clearStencil = true;
Color color = lovrGraphicsGetBackgroundColor();
float depth = 1.f;
int stencil = 0;
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
color.r = luaL_checknumber(L, index++);
color.g = luaL_checknumber(L, index++);
color.b = luaL_checknumber(L, index++);
color.a = luaL_optnumber(L, index++, 1.);
} else {
clearColor = lua_toboolean(L, index++);
}
}
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
depth = luaL_checknumber(L, index++);
} else {
clearDepth = lua_toboolean(L, index++);
}
}
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
stencil = luaL_checkinteger(L, index++);
} else {
clearStencil = lua_toboolean(L, index++);
}
}
lovrGraphicsClear(clearColor ? &color : NULL, clearDepth ? &depth : NULL, clearStencil ? &stencil : NULL);
return 0;
}
int l_lovrGraphicsPresent(lua_State* L) {
lovrGraphicsPresent();
return 0;
@ -366,6 +319,20 @@ int l_lovrGraphicsGetDimensions(lua_State* L) {
return 2;
}
int l_lovrGraphicsGetSystemLimits(lua_State* L) {
GraphicsLimits limits = lovrGraphicsGetLimits();
lua_newtable(L);
lua_pushnumber(L, limits.pointSizes[1]);
lua_setfield(L, -2, "pointsize");
lua_pushinteger(L, limits.textureSize);
lua_setfield(L, -2, "texturesize");
lua_pushinteger(L, limits.textureMSAA);
lua_setfield(L, -2, "texturemsaa");
lua_pushinteger(L, limits.textureAnisotropy);
lua_setfield(L, -2, "anisotropy");
return 1;
}
int l_lovrGraphicsGetStats(lua_State* L) {
if (lua_gettop(L) > 0) {
luaL_checktype(L, 1, LUA_TTABLE);
@ -387,6 +354,11 @@ int l_lovrGraphicsGetStats(lua_State* L) {
// State
int l_lovrGraphicsReset(lua_State* L) {
lovrGraphicsReset();
return 0;
}
int l_lovrGraphicsGetBackgroundColor(lua_State* L) {
Color color = lovrGraphicsGetBackgroundColor();
lua_pushnumber(L, color.r);
@ -518,20 +490,6 @@ int l_lovrGraphicsIsGammaCorrect(lua_State* L) {
return 1;
}
int l_lovrGraphicsGetSystemLimits(lua_State* L) {
GraphicsLimits limits = lovrGraphicsGetLimits();
lua_newtable(L);
lua_pushnumber(L, limits.pointSizes[1]);
lua_setfield(L, -2, "pointsize");
lua_pushinteger(L, limits.textureSize);
lua_setfield(L, -2, "texturesize");
lua_pushinteger(L, limits.textureMSAA);
lua_setfield(L, -2, "texturemsaa");
lua_pushinteger(L, limits.textureAnisotropy);
lua_setfield(L, -2, "anisotropy");
return 1;
}
int l_lovrGraphicsGetLineWidth(lua_State* L) {
lua_pushnumber(L, lovrGraphicsGetLineWidth());
return 1;
@ -661,7 +619,49 @@ int l_lovrGraphicsTransform(lua_State* L) {
return 0;
}
// Primitives
// Drawing
int l_lovrGraphicsClear(lua_State* L) {
int index = 1;
int top = lua_gettop(L);
bool clearColor = true;
bool clearDepth = true;
bool clearStencil = true;
Color color = lovrGraphicsGetBackgroundColor();
float depth = 1.f;
int stencil = 0;
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
color.r = luaL_checknumber(L, index++);
color.g = luaL_checknumber(L, index++);
color.b = luaL_checknumber(L, index++);
color.a = luaL_optnumber(L, index++, 1.);
} else {
clearColor = lua_toboolean(L, index++);
}
}
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
depth = luaL_checknumber(L, index++);
} else {
clearDepth = lua_toboolean(L, index++);
}
}
if (top >= index) {
if (lua_type(L, index) == LUA_TNUMBER) {
stencil = luaL_checkinteger(L, index++);
} else {
clearStencil = lua_toboolean(L, index++);
}
}
lovrGraphicsClear(clearColor ? &color : NULL, clearDepth ? &depth : NULL, clearStencil ? &stencil : NULL);
return 0;
}
int l_lovrGraphicsPoints(lua_State* L) {
uint32_t count = luax_readvertices(L, 1);
@ -1122,14 +1122,18 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
}
const luaL_Reg lovrGraphics[] = {
{ "reset", l_lovrGraphicsReset },
{ "clear", l_lovrGraphicsClear },
// Base
{ "present", l_lovrGraphicsPresent },
{ "createWindow", l_lovrGraphicsCreateWindow },
{ "getWidth", l_lovrGraphicsGetWidth },
{ "getHeight", l_lovrGraphicsGetHeight },
{ "getDimensions", l_lovrGraphicsGetDimensions },
{ "getSystemLimits", l_lovrGraphicsGetSystemLimits },
{ "getStats", l_lovrGraphicsGetStats },
// State
{ "reset", l_lovrGraphicsReset },
{ "getBackgroundColor", l_lovrGraphicsGetBackgroundColor },
{ "setBackgroundColor", l_lovrGraphicsSetBackgroundColor },
{ "getBlendMode", l_lovrGraphicsGetBlendMode },
@ -1147,7 +1151,6 @@ const luaL_Reg lovrGraphics[] = {
{ "getFont", l_lovrGraphicsGetFont },
{ "setFont", l_lovrGraphicsSetFont },
{ "isGammaCorrect", l_lovrGraphicsIsGammaCorrect },
{ "getSystemLimits", l_lovrGraphicsGetSystemLimits },
{ "getLineWidth", l_lovrGraphicsGetLineWidth },
{ "setLineWidth", l_lovrGraphicsSetLineWidth },
{ "getPointSize", l_lovrGraphicsGetPointSize },
@ -1160,6 +1163,8 @@ const luaL_Reg lovrGraphics[] = {
{ "setWinding", l_lovrGraphicsSetWinding },
{ "isWireframe", l_lovrGraphicsIsWireframe },
{ "setWireframe", l_lovrGraphicsSetWireframe },
// Transforms
{ "push", l_lovrGraphicsPush },
{ "pop", l_lovrGraphicsPop },
{ "origin", l_lovrGraphicsOrigin },
@ -1167,6 +1172,9 @@ const luaL_Reg lovrGraphics[] = {
{ "rotate", l_lovrGraphicsRotate },
{ "scale", l_lovrGraphicsScale },
{ "transform", l_lovrGraphicsTransform },
// Drawing
{ "clear", l_lovrGraphicsClear },
{ "points", l_lovrGraphicsPoints },
{ "line", l_lovrGraphicsLine },
{ "triangle", l_lovrGraphicsTriangle },
@ -1181,6 +1189,8 @@ const luaL_Reg lovrGraphics[] = {
{ "print", l_lovrGraphicsPrint },
{ "stencil", l_lovrGraphicsStencil },
{ "fill", l_lovrGraphicsFill },
// Types
{ "newAnimator", l_lovrGraphicsNewAnimator },
{ "newCanvas", l_lovrGraphicsNewCanvas },
{ "newFont", l_lovrGraphicsNewFont },
@ -1189,5 +1199,6 @@ const luaL_Reg lovrGraphics[] = {
{ "newModel", l_lovrGraphicsNewModel },
{ "newShader", l_lovrGraphicsNewShader },
{ "newTexture", l_lovrGraphicsNewTexture },
{ NULL, NULL }
};

View File

@ -57,7 +57,7 @@ int l_lovrMeshDrawInstanced(lua_State* L) {
int instances = luaL_checkinteger(L, 2);
float transform[16];
luax_readtransform(L, 3, transform, 1);
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.mesh = mesh,
.material = lovrMeshGetMaterial(mesh),

View File

@ -1,5 +1,6 @@
#include "graphics/canvas.h"
#include "graphics/font.h"
#include "graphics/graphics.h"
#include "graphics/material.h"
#include "graphics/mesh.h"
#include "graphics/shader.h"
@ -10,99 +11,6 @@
#pragma once
typedef void (*StencilCallback)(void* userdata);
typedef struct {
int shaderSwitches;
int drawCalls;
} GraphicsStats;
typedef enum {
BLEND_ALPHA,
BLEND_ADD,
BLEND_SUBTRACT,
BLEND_MULTIPLY,
BLEND_LIGHTEN,
BLEND_DARKEN,
BLEND_SCREEN,
BLEND_REPLACE
} BlendMode;
typedef enum {
BLEND_ALPHA_MULTIPLY,
BLEND_PREMULTIPLIED
} BlendAlphaMode;
typedef enum {
DRAW_MODE_FILL,
DRAW_MODE_LINE
} DrawMode;
typedef enum {
ARC_MODE_PIE,
ARC_MODE_OPEN,
ARC_MODE_CLOSED
} ArcMode;
typedef enum {
WINDING_CLOCKWISE,
WINDING_COUNTERCLOCKWISE
} Winding;
typedef enum {
COMPARE_NONE,
COMPARE_EQUAL,
COMPARE_NEQUAL,
COMPARE_LESS,
COMPARE_LEQUAL,
COMPARE_GREATER,
COMPARE_GEQUAL
} CompareMode;
typedef enum {
STENCIL_REPLACE,
STENCIL_INCREMENT,
STENCIL_DECREMENT,
STENCIL_INCREMENT_WRAP,
STENCIL_DECREMENT_WRAP,
STENCIL_INVERT
} StencilAction;
typedef struct {
bool initialized;
float pointSizes[2];
int textureSize;
int textureMSAA;
float textureAnisotropy;
} GraphicsLimits;
typedef struct {
Color backgroundColor;
BlendMode blendMode;
BlendAlphaMode blendAlphaMode;
Color color;
bool culling;
CompareMode depthTest;
bool depthWrite;
Font* font;
float lineWidth;
float pointSize;
Shader* shader;
CompareMode stencilMode;
int stencilValue;
Winding winding;
bool wireframe;
} Pipeline;
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;
mat4 transform;

View File

@ -1,6 +1,6 @@
#include "graphics/graphics.h"
#include "graphics/gpu.h"
#include "data/rasterizer.h"
#include "resources/shaders.h"
#include "event/event.h"
#include "math/mat4.h"
#include "math/vec3.h"
@ -11,8 +11,6 @@
#include <string.h>
#include <math.h>
#include "graphics/opengl/opengl.h"
static GraphicsState state;
static void onCloseWindow(GLFWwindow* window) {
@ -45,36 +43,6 @@ void lovrGraphicsDestroy() {
memset(&state, 0, sizeof(GraphicsState));
}
void lovrGraphicsReset() {
int width, height;
lovrGraphicsGetDimensions(&width, &height);
state.transform = 0;
state.layer = 0;
memcpy(state.layers[state.layer].viewport, (int[]) { 0, 0, width, height }, 4 * sizeof(uint32_t));
mat4_perspective(state.layers[state.layer].projection, .01f, 100.f, 67 * M_PI / 180., (float) width / height);
mat4_identity(state.layers[state.layer].view);
lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1. });
lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY);
lovrGraphicsSetCanvas(NULL, 0);
lovrGraphicsSetColor((Color) { 1., 1., 1., 1. });
lovrGraphicsSetCullingEnabled(false);
lovrGraphicsSetDefaultFilter((TextureFilter) { .mode = FILTER_TRILINEAR });
lovrGraphicsSetDepthTest(COMPARE_LEQUAL, true);
lovrGraphicsSetFont(NULL);
lovrGraphicsSetLineWidth(1);
lovrGraphicsSetPointSize(1);
lovrGraphicsSetShader(NULL);
lovrGraphicsSetStencilTest(COMPARE_NONE, 0);
lovrGraphicsSetWinding(WINDING_COUNTERCLOCKWISE);
lovrGraphicsSetWireframe(false);
lovrGraphicsOrigin();
}
void lovrGraphicsClear(Color* color, float* depth, int* stencil) {
Layer layer = state.layers[state.layer];
gpuClear(layer.canvas, layer.canvasCount, color, depth, stencil);
}
void lovrGraphicsPresent() {
glfwSwapBuffers(state.window);
gpuPresent();
@ -146,6 +114,31 @@ void lovrGraphicsGetDimensions(int* width, int* height) {
// State
void lovrGraphicsReset() {
int width, height;
lovrGraphicsGetDimensions(&width, &height);
state.transform = 0;
state.layer = 0;
memcpy(state.layers[state.layer].viewport, (int[]) { 0, 0, width, height }, 4 * sizeof(uint32_t));
mat4_perspective(state.layers[state.layer].projection, .01f, 100.f, 67 * M_PI / 180., (float) width / height);
mat4_identity(state.layers[state.layer].view);
lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1. });
lovrGraphicsSetBlendMode(BLEND_ALPHA, BLEND_ALPHA_MULTIPLY);
lovrGraphicsSetCanvas(NULL, 0);
lovrGraphicsSetColor((Color) { 1., 1., 1., 1. });
lovrGraphicsSetCullingEnabled(false);
lovrGraphicsSetDefaultFilter((TextureFilter) { .mode = FILTER_TRILINEAR });
lovrGraphicsSetDepthTest(COMPARE_LEQUAL, true);
lovrGraphicsSetFont(NULL);
lovrGraphicsSetLineWidth(1);
lovrGraphicsSetPointSize(1);
lovrGraphicsSetShader(NULL);
lovrGraphicsSetStencilTest(COMPARE_NONE, 0);
lovrGraphicsSetWinding(WINDING_COUNTERCLOCKWISE);
lovrGraphicsSetWireframe(false);
lovrGraphicsOrigin();
}
Color lovrGraphicsGetBackgroundColor() {
return state.pipelines[state.pipeline].backgroundColor;
}
@ -336,22 +329,82 @@ void lovrGraphicsMatrixTransform(mat4 transform) {
mat4_multiply(state.transforms[state.transform], transform);
}
// Primitives
// Drawing
VertexPointer lovrGraphicsGetVertexPointer(uint32_t count) {
lovrMeshResize(state.mesh, count);
return lovrMeshMapVertices(state.mesh, 0, count, false, true);
}
void lovrGraphicsClear(Color* color, float* depth, int* stencil) {
Layer layer = state.layers[state.layer];
gpuClear(layer.canvas, layer.canvasCount, color, depth, stencil);
}
void lovrGraphicsDraw(DrawCommand* draw) {
if (draw->transform) {
lovrGraphicsPush();
lovrGraphicsMatrixTransform(draw->transform);
}
Shader* shader = state.pipelines[state.pipeline].shader ? state.pipelines[state.pipeline].shader : state.defaultShaders[draw->shader];
if (!shader) shader = state.defaultShaders[draw->shader] = lovrShaderCreateDefault(draw->shader);
Mesh* mesh = draw->mesh;
if (!mesh) {
int drawCount = draw->range.count ? draw->range.count : (draw->index.count ? draw->index.count : draw->vertex.count);
mesh = state.mesh;
lovrMeshSetDrawMode(mesh, draw->mode);
lovrMeshSetDrawRange(mesh, draw->range.start, drawCount);
if (draw->vertex.count) {
VertexPointer vertexPointer = lovrGraphicsGetVertexPointer(draw->vertex.count);
memcpy(vertexPointer.raw, draw->vertex.data, draw->vertex.count * 8 * sizeof(float));
if (draw->index.count) {
IndexPointer indexPointer = lovrMeshWriteIndices(mesh, draw->index.count, sizeof(uint16_t));
memcpy(indexPointer.shorts, draw->index.data, draw->index.count * sizeof(uint16_t));
} else {
lovrMeshWriteIndices(mesh, 0, 0);
}
}
}
Material* material = draw->material;
if (!material) {
material = state.defaultMaterial;
if (!material) {
material = state.defaultMaterial = lovrMaterialCreate(true);
}
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
lovrMaterialSetTexture(material, i, draw->textures[i]);
}
}
gpuDraw(&(GpuDrawCommand) {
.layer = state.layers[state.layer],
.shader = shader,
.material = material,
.transform = state.transforms[state.transform],
.mesh = mesh,
.pipeline = state.pipelines[state.pipeline],
.instances = draw->instances
});
if (draw->transform) {
lovrGraphicsPop();
}
}
void lovrGraphicsPoints(uint32_t count) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.mode = MESH_POINTS,
.range = { 0, count }
});
}
void lovrGraphicsLine(uint32_t count) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.mode = MESH_LINE_STRIP,
.range = { 0, count }
});
@ -359,7 +412,7 @@ void lovrGraphicsLine(uint32_t count) {
void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
if (mode == DRAW_MODE_LINE) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.material = material,
.mode = MESH_LINE_LOOP,
.vertex.count = 3,
@ -372,7 +425,7 @@ void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
} else {
float normal[3];
vec3_cross(vec3_init(normal, &points[0]), &points[3]);
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.material = material,
.mode = MESH_TRIANGLES,
.vertex.count = 3,
@ -387,7 +440,7 @@ void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
if (mode == DRAW_MODE_LINE) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = MESH_LINE_LOOP,
@ -400,7 +453,7 @@ void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
}
});
} else if (mode == DRAW_MODE_FILL) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = MESH_TRIANGLE_STRIP,
@ -417,7 +470,7 @@ void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
if (mode == DRAW_MODE_LINE) {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = MESH_LINES,
@ -443,7 +496,7 @@ void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
}
});
} else {
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = MESH_TRIANGLE_STRIP,
@ -520,7 +573,7 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 tr
theta += angleShift;
}
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = mode == DRAW_MODE_LINE ? (arcMode == ARC_MODE_OPEN ? MESH_LINE_STRIP : MESH_LINE_LOOP) : MESH_TRIANGLE_FAN,
@ -622,7 +675,7 @@ void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, floa
#undef PUSH_CYLINDER_VERTEX
#undef PUSH_CYLINDER_TRIANGLE
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.material = material,
.mode = MESH_TRIANGLES,
.range = { 0, indexCount }
@ -657,7 +710,7 @@ void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
}
}
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = transform,
.material = material,
.mode = MESH_TRIANGLES,
@ -670,7 +723,7 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float
lovrAssert(type == TEXTURE_CUBE || type == TEXTURE_2D, "Only 2D and cube textures can be used as skyboxes");
lovrGraphicsPushPipeline();
lovrGraphicsSetWinding(WINDING_COUNTERCLOCKWISE);
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.shader = type == TEXTURE_CUBE ? SHADER_CUBE : SHADER_PANO,
.textures[TEXTURE_DIFFUSE] = texture,
.textures[TEXTURE_ENVIRONMENT_MAP] = texture,
@ -702,7 +755,7 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
lovrGraphicsTranslate(0, offsety, 0);
lovrGraphicsPushPipeline();
state.pipelines[state.pipeline].depthWrite = false;
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.shader = SHADER_FONT,
.textures[TEXTURE_DIFFUSE] = font->texture,
.mode = MESH_TRIANGLES,
@ -715,7 +768,7 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
void lovrGraphicsFill(Texture* texture) {
lovrGraphicsPushPipeline();
lovrGraphicsSetDepthTest(COMPARE_NONE, false);
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.shader = SHADER_FILL,
.textures[TEXTURE_DIFFUSE] = texture,
.mode = MESH_TRIANGLE_STRIP,
@ -731,61 +784,6 @@ void lovrGraphicsFill(Texture* texture) {
}
// Internal
void lovrGraphicsDraw(GraphicsDraw* draw) {
if (draw->transform) {
lovrGraphicsPush();
lovrGraphicsMatrixTransform(draw->transform);
}
Shader* shader = state.pipelines[state.pipeline].shader ? state.pipelines[state.pipeline].shader : state.defaultShaders[draw->shader];
if (!shader) shader = state.defaultShaders[draw->shader] = lovrShaderCreateDefault(draw->shader);
Mesh* mesh = draw->mesh;
if (!mesh) {
int drawCount = draw->range.count ? draw->range.count : (draw->index.count ? draw->index.count : draw->vertex.count);
mesh = state.mesh;
lovrMeshSetDrawMode(mesh, draw->mode);
lovrMeshSetDrawRange(mesh, draw->range.start, drawCount);
if (draw->vertex.count) {
VertexPointer vertexPointer = lovrGraphicsGetVertexPointer(draw->vertex.count);
memcpy(vertexPointer.raw, draw->vertex.data, draw->vertex.count * 8 * sizeof(float));
if (draw->index.count) {
IndexPointer indexPointer = lovrMeshWriteIndices(mesh, draw->index.count, sizeof(uint16_t));
memcpy(indexPointer.shorts, draw->index.data, draw->index.count * sizeof(uint16_t));
} else {
lovrMeshWriteIndices(mesh, 0, 0);
}
}
}
Material* material = draw->material;
if (!material) {
material = state.defaultMaterial;
if (!material) {
material = state.defaultMaterial = lovrMaterialCreate(true);
}
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
lovrMaterialSetTexture(material, i, draw->textures[i]);
}
}
gpuDraw(&(GpuDrawCommand) {
.layer = state.layers[state.layer],
.shader = shader,
.material = material,
.transform = state.transforms[state.transform],
.mesh = mesh,
.pipeline = state.pipelines[state.pipeline],
.instances = draw->instances
});
if (draw->transform) {
lovrGraphicsPop();
}
}
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");

View File

@ -1,4 +1,3 @@
#include "graphics/gpu.h"
#include "graphics/canvas.h"
#include "graphics/font.h"
#include "graphics/material.h"
@ -20,6 +19,99 @@
#define DEFAULT_SHADER_COUNT 5
#define MAX_TEXTURES 16
typedef void (*StencilCallback)(void* userdata);
typedef struct {
int shaderSwitches;
int drawCalls;
} GraphicsStats;
typedef enum {
BLEND_ALPHA,
BLEND_ADD,
BLEND_SUBTRACT,
BLEND_MULTIPLY,
BLEND_LIGHTEN,
BLEND_DARKEN,
BLEND_SCREEN,
BLEND_REPLACE
} BlendMode;
typedef enum {
BLEND_ALPHA_MULTIPLY,
BLEND_PREMULTIPLIED
} BlendAlphaMode;
typedef enum {
DRAW_MODE_FILL,
DRAW_MODE_LINE
} DrawMode;
typedef enum {
ARC_MODE_PIE,
ARC_MODE_OPEN,
ARC_MODE_CLOSED
} ArcMode;
typedef enum {
WINDING_CLOCKWISE,
WINDING_COUNTERCLOCKWISE
} Winding;
typedef enum {
COMPARE_NONE,
COMPARE_EQUAL,
COMPARE_NEQUAL,
COMPARE_LESS,
COMPARE_LEQUAL,
COMPARE_GREATER,
COMPARE_GEQUAL
} CompareMode;
typedef enum {
STENCIL_REPLACE,
STENCIL_INCREMENT,
STENCIL_DECREMENT,
STENCIL_INCREMENT_WRAP,
STENCIL_DECREMENT_WRAP,
STENCIL_INVERT
} StencilAction;
typedef struct {
bool initialized;
float pointSizes[2];
int textureSize;
int textureMSAA;
float textureAnisotropy;
} GraphicsLimits;
typedef struct {
Color backgroundColor;
BlendMode blendMode;
BlendAlphaMode blendAlphaMode;
Color color;
bool culling;
CompareMode depthTest;
bool depthWrite;
Font* font;
float lineWidth;
float pointSize;
Shader* shader;
CompareMode stencilMode;
int stencilValue;
Winding winding;
bool wireframe;
} Pipeline;
typedef struct {
float projection[16];
float view[16];
uint32_t viewport[4];
Canvas* canvas[MAX_CANVASES];
int canvasCount;
bool user;
} Layer;
typedef struct {
mat4 transform;
DefaultShader shader;
@ -40,7 +132,7 @@ typedef struct {
int count;
} range;
int instances;
} GraphicsDraw;
} DrawCommand;
typedef struct {
bool initialized;
@ -62,8 +154,6 @@ typedef struct {
// Base
void lovrGraphicsInit();
void lovrGraphicsDestroy();
void lovrGraphicsReset();
void lovrGraphicsClear(Color* color, float* depth, int* stencil);
void lovrGraphicsPresent();
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon);
void lovrGraphicsGetDimensions(int* width, int* height);
@ -71,6 +161,7 @@ GraphicsLimits lovrGraphicsGetLimits();
GraphicsStats lovrGraphicsGetStats();
// State
void lovrGraphicsReset();
Color lovrGraphicsGetBackgroundColor();
void lovrGraphicsSetBackgroundColor(Color color);
void lovrGraphicsGetBlendMode(BlendMode* mode, BlendAlphaMode* alphaMode);
@ -111,7 +202,10 @@ void lovrGraphicsRotate(float angle, float ax, float ay, float az);
void lovrGraphicsScale(float x, float y, float z);
void lovrGraphicsMatrixTransform(mat4 transform);
// Primitives
// Drawing
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
void lovrGraphicsClear(Color* color, float* depth, int* stencil);
void lovrGraphicsDraw(DrawCommand* draw);
void lovrGraphicsPoints(uint32_t count);
void lovrGraphicsLine(uint32_t count);
void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]);
@ -127,8 +221,6 @@ void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback
void lovrGraphicsFill(Texture* texture);
// Internal
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
void lovrGraphicsDraw(GraphicsDraw* draw);
void lovrGraphicsPushLayer(Canvas** canvas, int count, bool user);
void lovrGraphicsPopLayer();
void lovrGraphicsPushPipeline();

View File

@ -40,7 +40,7 @@ static void renderNode(Model* model, int nodeIndex, int instances) {
lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount);
lovrMeshSetPose(model->mesh, (float*) model->pose);
lovrGraphicsDraw(&(GraphicsDraw) {
lovrGraphicsDraw(&(DrawCommand) {
.transform = model->nodeTransforms[nodeIndex],
.mesh = model->mesh,
.material = lovrMeshGetMaterial(model->mesh),

View File

@ -1,5 +1,6 @@
#include "graphics/opengl/opengl.h"
#include "graphics/graphics.h"
#include "graphics/gpu.h"
#include "resources/shaders.h"
#include "math/math.h"
#include <string.h>

View File

@ -1,5 +1,6 @@
#include "graphics/opengl/opengl.h"
#include "graphics/graphics.h"
#include "graphics/gpu.h"
#include "lib/vec/vec.h"
#include "math/math.h"
#include <math.h>