mirror of https://github.com/bjornbytes/lovr.git
Organization;
This commit is contained in:
parent
b4752dd6a1
commit
56bbf1cf56
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue