mirror of https://github.com/bjornbytes/lovr.git
Organize drawing code;
This commit is contained in:
parent
8e5061f918
commit
c0ea3240c3
|
@ -57,8 +57,7 @@ int l_lovrMeshDrawInstanced(lua_State* L) {
|
|||
int instances = luaL_checkinteger(L, 2);
|
||||
float transform[16];
|
||||
luax_readtransform(L, 3, transform, 1);
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshDraw(mesh, transform, NULL, instances);
|
||||
lovrGraphicsDraw(mesh, transform, SHADER_DEFAULT, instances);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ void lovrGraphicsReset() {
|
|||
int h = lovrGraphicsGetHeight();
|
||||
state.transform = 0;
|
||||
state.layer = 0;
|
||||
state.defaultShader = SHADER_DEFAULT;
|
||||
mat4_perspective(state.layers[state.layer].projections, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
mat4_perspective(state.layers[state.layer].projections + 16, .01f, 100.f, 67 * M_PI / 180., (float) w / h / 2.);
|
||||
mat4_identity(state.layers[state.layer].views);
|
||||
|
@ -106,102 +105,6 @@ void lovrGraphicsPresent() {
|
|||
state.program = -1; // Fixes a driver bug with instancing seen on macOS
|
||||
}
|
||||
|
||||
void lovrGraphicsPrepare(Material* material, float* pose) {
|
||||
Shader* shader = lovrGraphicsGetActiveShader();
|
||||
|
||||
if (!shader) {
|
||||
shader = state.defaultShaders[state.defaultShader] = lovrShaderCreateDefault(state.defaultShader);
|
||||
}
|
||||
|
||||
// Layer
|
||||
Layer layer = state.layers[state.layer];
|
||||
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
|
||||
int w = canvas ? canvas->texture.width : lovrGraphicsGetWidth();
|
||||
int h = canvas ? canvas->texture.height : lovrGraphicsGetHeight();
|
||||
lovrGraphicsBindFramebuffer(canvas ? canvas->framebuffer : 0);
|
||||
lovrGraphicsSetViewport(0, 0, w, h);
|
||||
lovrGraphicsBindUniformBuffer(state.cameraUBO);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 16 * sizeof(float), &layer); // TODO
|
||||
|
||||
// Transforms
|
||||
mat4 model = state.transforms[state.transform];
|
||||
lovrShaderSetMatrix(shader, "lovrModel", model, 16);
|
||||
|
||||
float transforms[32];
|
||||
mat4_multiply(mat4_set(transforms + 0, layer.views + 0), model);
|
||||
mat4_multiply(mat4_set(transforms + 16, layer.views + 16), model);
|
||||
lovrShaderSetMatrix(shader, "lovrTransforms", transforms, 32);
|
||||
|
||||
if (lovrShaderGetUniform(shader, "lovrNormalMatrices")) {
|
||||
if (mat4_invert(transforms)) {
|
||||
mat4_transpose(transforms);
|
||||
} else {
|
||||
mat4_identity(transforms);
|
||||
}
|
||||
|
||||
if (mat4_invert(transforms + 16)) {
|
||||
mat4_transpose(transforms + 16);
|
||||
} else {
|
||||
mat4_identity(transforms + 16);
|
||||
}
|
||||
|
||||
float normalMatrix[18] = {
|
||||
transforms[0], transforms[1], transforms[2],
|
||||
transforms[4], transforms[5], transforms[6],
|
||||
transforms[8], transforms[9], transforms[10],
|
||||
|
||||
transforms[16], transforms[17], transforms[18],
|
||||
transforms[20], transforms[21], transforms[22],
|
||||
transforms[24], transforms[25], transforms[26]
|
||||
};
|
||||
|
||||
lovrShaderSetMatrix(shader, "lovrNormalMatrices", normalMatrix, 18);
|
||||
}
|
||||
|
||||
// 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
|
||||
if (pose) {
|
||||
lovrShaderSetMatrix(shader, "lovrPose", pose, MAX_BONES * 16);
|
||||
} else {
|
||||
float identity[16];
|
||||
mat4_identity(identity);
|
||||
lovrShaderSetMatrix(shader, "lovrPose", identity, 16);
|
||||
}
|
||||
|
||||
// Material
|
||||
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);
|
||||
}
|
||||
|
||||
lovrGraphicsUseProgram(shader->program);
|
||||
lovrShaderBind(shader);
|
||||
}
|
||||
|
||||
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon) {
|
||||
lovrAssert(!state.window, "Window is already created");
|
||||
|
||||
|
@ -635,21 +538,19 @@ VertexPointer lovrGraphicsGetVertexPointer(uint32_t count) {
|
|||
}
|
||||
|
||||
void lovrGraphicsPoints(uint32_t count) {
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_POINTS);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||
lovrMeshSetMaterial(state.mesh, NULL);
|
||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsLine(uint32_t count) {
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_LINE_STRIP);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, count);
|
||||
lovrMeshSetMaterial(state.mesh, NULL);
|
||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
||||
|
@ -680,9 +581,8 @@ void lovrGraphicsTriangle(DrawMode mode, Material* material, float points[9]) {
|
|||
}
|
||||
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 3);
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
||||
|
@ -710,11 +610,10 @@ void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
|
|||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshWriteIndices(state.mesh, 0, 0);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||
lovrMeshDraw(state.mesh, transform, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
||||
|
@ -795,9 +694,8 @@ void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
|
|||
lovrMeshSetDrawRange(state.mesh, 0, 26);
|
||||
}
|
||||
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshDraw(state.mesh, transform, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 transform, float theta1, float theta2, int segments) {
|
||||
|
@ -841,11 +739,10 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 tr
|
|||
theta += angleShift;
|
||||
}
|
||||
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
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);
|
||||
lovrMeshDraw(state.mesh, transform, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsCircle(DrawMode mode, Material* material, mat4 transform, int segments) {
|
||||
|
@ -942,11 +839,10 @@ void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, floa
|
|||
#undef PUSH_CYLINDER_VERTEX
|
||||
#undef PUSH_CYLINDER_TRIANGLE
|
||||
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLES);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, indexCount);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
||||
|
@ -988,11 +884,10 @@ void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
|
|||
}
|
||||
}
|
||||
|
||||
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
|
||||
lovrMeshSetDrawMode(state.mesh, GL_TRIANGLES);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, segments * segments * 6);
|
||||
lovrMeshSetMaterial(state.mesh, material);
|
||||
lovrMeshDraw(state.mesh, transform, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, transform, SHADER_DEFAULT, 1);
|
||||
}
|
||||
|
||||
void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float az) {
|
||||
|
@ -1006,9 +901,9 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float
|
|||
TextureType type = texture->type;
|
||||
lovrAssert(type == TEXTURE_CUBE || type == TEXTURE_2D, "Only 2D and cube textures can be used as skyboxes");
|
||||
MaterialTexture materialTexture = type == TEXTURE_CUBE ? TEXTURE_ENVIRONMENT_MAP : TEXTURE_DIFFUSE;
|
||||
DefaultShader shader = type == TEXTURE_CUBE ? SHADER_CUBE : SHADER_PANO;
|
||||
Winding winding = state.winding;
|
||||
lovrGraphicsSetWinding(WINDING_COUNTERCLOCKWISE);
|
||||
lovrGraphicsSetDefaultShader(type == TEXTURE_CUBE ? SHADER_CUBE : SHADER_PANO);
|
||||
Material* material = lovrGraphicsGetDefaultMaterial();
|
||||
lovrMaterialSetTexture(material, materialTexture, texture);
|
||||
VertexPointer vertexPointer = lovrGraphicsGetVertexPointer(4);
|
||||
|
@ -1017,7 +912,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);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, shader, 1);
|
||||
lovrMaterialSetTexture(material, materialTexture, NULL);
|
||||
lovrGraphicsSetWinding(winding);
|
||||
}
|
||||
|
@ -1036,7 +931,6 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
|
|||
lovrGraphicsMatrixTransform(transform);
|
||||
lovrGraphicsScale(scale, scale, scale);
|
||||
lovrGraphicsTranslate(0, offsety, 0);
|
||||
lovrGraphicsSetDefaultShader(SHADER_FONT);
|
||||
Material* material = lovrGraphicsGetDefaultMaterial();
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, font->texture);
|
||||
CompareMode mode;
|
||||
|
@ -1046,7 +940,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);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FONT, 1);
|
||||
lovrGraphicsSetDepthTest(mode, write);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||
lovrGraphicsPop();
|
||||
|
@ -1088,7 +982,6 @@ void lovrGraphicsFill(Texture* texture) {
|
|||
bool write;
|
||||
lovrGraphicsGetDepthTest(&mode, &write);
|
||||
lovrGraphicsSetDepthTest(COMPARE_NONE, false);
|
||||
lovrGraphicsSetDefaultShader(SHADER_FILL);
|
||||
Material* material = lovrGraphicsGetDefaultMaterial();
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
|
||||
VertexPointer vertexPointer = lovrGraphicsGetVertexPointer(4);
|
||||
|
@ -1098,11 +991,137 @@ void lovrGraphicsFill(Texture* texture) {
|
|||
lovrMeshSetDrawMode(state.mesh, MESH_TRIANGLE_STRIP);
|
||||
lovrMeshSetDrawRange(state.mesh, 0, 4);
|
||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
|
||||
lovrMeshDraw(state.mesh, NULL, NULL, 1);
|
||||
lovrGraphicsDraw(state.mesh, NULL, SHADER_FILL, 1);
|
||||
lovrGraphicsSetDepthTest(mode, write);
|
||||
}
|
||||
|
||||
// Internal State
|
||||
// Internal
|
||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, int instances) {
|
||||
Shader* shader = state.shader ? state.shader : state.defaultShaders[defaultShader];
|
||||
|
||||
if (!shader) {
|
||||
shader = state.defaultShaders[defaultShader] = lovrShaderCreateDefault(defaultShader);
|
||||
}
|
||||
|
||||
// Layer
|
||||
Layer layer = state.layers[state.layer];
|
||||
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
|
||||
int w = canvas ? canvas->texture.width : lovrGraphicsGetWidth();
|
||||
int h = canvas ? canvas->texture.height : lovrGraphicsGetHeight();
|
||||
lovrGraphicsBindFramebuffer(canvas ? canvas->framebuffer : 0);
|
||||
lovrGraphicsSetViewport(0, 0, w, h);
|
||||
lovrGraphicsBindUniformBuffer(state.cameraUBO);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 16 * sizeof(float), &layer); // TODO
|
||||
|
||||
// Transforms
|
||||
if (transform) {
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsMatrixTransform(transform);
|
||||
}
|
||||
|
||||
mat4 model = state.transforms[state.transform];
|
||||
lovrShaderSetMatrix(shader, "lovrModel", model, 16);
|
||||
|
||||
float transforms[32];
|
||||
mat4_multiply(mat4_set(transforms + 0, layer.views + 0), model);
|
||||
mat4_multiply(mat4_set(transforms + 16, layer.views + 16), model);
|
||||
lovrShaderSetMatrix(shader, "lovrTransforms", transforms, 32);
|
||||
|
||||
if (lovrShaderGetUniform(shader, "lovrNormalMatrices")) {
|
||||
if (mat4_invert(transforms)) {
|
||||
mat4_transpose(transforms);
|
||||
} else {
|
||||
mat4_identity(transforms);
|
||||
}
|
||||
|
||||
if (mat4_invert(transforms + 16)) {
|
||||
mat4_transpose(transforms + 16);
|
||||
} else {
|
||||
mat4_identity(transforms + 16);
|
||||
}
|
||||
|
||||
float normalMatrix[18] = {
|
||||
transforms[0], transforms[1], transforms[2],
|
||||
transforms[4], transforms[5], transforms[6],
|
||||
transforms[8], transforms[9], transforms[10],
|
||||
|
||||
transforms[16], transforms[17], transforms[18],
|
||||
transforms[20], transforms[21], transforms[22],
|
||||
transforms[24], transforms[25], transforms[26]
|
||||
};
|
||||
|
||||
lovrShaderSetMatrix(shader, "lovrNormalMatrices", normalMatrix, 18);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
lovrShaderSetMatrix(shader, "lovrPose", pose, MAX_BONES * 16);
|
||||
} else {
|
||||
float identity[16];
|
||||
mat4_identity(identity);
|
||||
lovrShaderSetMatrix(shader, "lovrPose", identity, 16);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
lovrGraphicsUseProgram(shader->program);
|
||||
lovrShaderBind(shader);
|
||||
|
||||
lovrGraphicsBindVertexArray(mesh->vao);
|
||||
lovrMeshUnmapVertices(mesh);
|
||||
lovrMeshUnmapIndices(mesh);
|
||||
lovrMeshBind(mesh, shader);
|
||||
|
||||
size_t start = mesh->rangeStart;
|
||||
if (mesh->indexCount > 0) {
|
||||
size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->indexCount;
|
||||
GLenum indexType = mesh->indexSize == sizeof(uint16_t) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
||||
size_t offset = start * mesh->indexSize;
|
||||
glDrawElementsInstanced(mesh->drawMode, count, indexType, (GLvoid*) offset, instances * 2);
|
||||
} else {
|
||||
size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->count;
|
||||
glDrawArraysInstanced(mesh->drawMode, start, count, instances * 2);
|
||||
}
|
||||
|
||||
if (transform) {
|
||||
lovrGraphicsPop();
|
||||
}
|
||||
|
||||
state.stats.drawCalls++;
|
||||
}
|
||||
|
||||
void lovrGraphicsPushLayer(Layer layer) {
|
||||
if (++state.layer >= MAX_LAYERS) {
|
||||
lovrThrow("Layer overflow");
|
||||
|
@ -1154,14 +1173,6 @@ Material* lovrGraphicsGetDefaultMaterial() {
|
|||
return state.defaultMaterial;
|
||||
}
|
||||
|
||||
void lovrGraphicsSetDefaultShader(DefaultShader shader) {
|
||||
state.defaultShader = shader;
|
||||
}
|
||||
|
||||
Shader* lovrGraphicsGetActiveShader() {
|
||||
return state.shader ? state.shader : state.defaultShaders[state.defaultShader];
|
||||
}
|
||||
|
||||
void lovrGraphicsUseProgram(uint32_t program) {
|
||||
if (state.program != program) {
|
||||
state.program = program;
|
||||
|
@ -1204,14 +1215,3 @@ void lovrGraphicsBindIndexBuffer(uint32_t indexBuffer) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void lovrGraphicsDrawArrays(GLenum mode, size_t start, size_t count, int instances) {
|
||||
glDrawArraysInstanced(mode, start, count, instances * 2);
|
||||
state.stats.drawCalls++;
|
||||
}
|
||||
|
||||
void lovrGraphicsDrawElements(GLenum mode, size_t count, size_t indexSize, size_t offset, int instances) {
|
||||
GLenum indexType = indexSize == sizeof(uint16_t) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
||||
glDrawElementsInstanced(mode, count, indexType, (GLvoid*) offset, instances * 2);
|
||||
state.stats.drawCalls++;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,6 @@ typedef struct {
|
|||
bool initialized;
|
||||
GLFWwindow* window;
|
||||
Shader* defaultShaders[DEFAULT_SHADER_COUNT];
|
||||
DefaultShader defaultShader;
|
||||
Material* defaultMaterial;
|
||||
Font* defaultFont;
|
||||
Texture* defaultTexture;
|
||||
|
@ -141,7 +140,6 @@ void lovrGraphicsDestroy();
|
|||
void lovrGraphicsReset();
|
||||
void lovrGraphicsClear(bool clearColor, bool clearDepth, bool clearStencil, Color color, float depth, int stencil);
|
||||
void lovrGraphicsPresent();
|
||||
void lovrGraphicsPrepare(Material* material, float* pose);
|
||||
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon);
|
||||
int lovrGraphicsGetWidth();
|
||||
int lovrGraphicsGetHeight();
|
||||
|
@ -204,7 +202,8 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
|
|||
void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback callback, void* userdata);
|
||||
void lovrGraphicsFill(Texture* texture);
|
||||
|
||||
// Internal State
|
||||
// Internal
|
||||
void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader shader, int instances);
|
||||
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);
|
||||
void lovrGraphicsPushLayer(Layer layer);
|
||||
void lovrGraphicsPopLayer();
|
||||
|
@ -212,13 +211,9 @@ void lovrGraphicsSetViewport(int x, int y, int w, int h);
|
|||
Texture* lovrGraphicsGetTexture(int slot);
|
||||
void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot);
|
||||
Material* lovrGraphicsGetDefaultMaterial();
|
||||
void lovrGraphicsSetDefaultShader(DefaultShader defaultShader);
|
||||
Shader* lovrGraphicsGetActiveShader();
|
||||
void lovrGraphicsUseProgram(uint32_t program);
|
||||
void lovrGraphicsBindFramebuffer(uint32_t framebuffer);
|
||||
void lovrGraphicsBindVertexArray(uint32_t vao);
|
||||
void lovrGraphicsBindVertexBuffer(uint32_t vbo);
|
||||
void lovrGraphicsBindUniformBuffer(uint32_t ubo);
|
||||
void lovrGraphicsBindIndexBuffer(uint32_t ibo);
|
||||
void lovrGraphicsDrawArrays(GLenum mode, size_t start, size_t count, int instances);
|
||||
void lovrGraphicsDrawElements(GLenum mode, size_t count, size_t indexSize, size_t offset, int instances);
|
||||
|
|
|
@ -3,68 +3,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void lovrMeshBindAttributes(Mesh* mesh) {
|
||||
const char* key;
|
||||
map_iter_t iter = map_iter(&mesh->attachments);
|
||||
Shader* shader = lovrGraphicsGetActiveShader();
|
||||
|
||||
MeshAttachment layout[MAX_ATTACHMENTS];
|
||||
memset(layout, 0, MAX_ATTACHMENTS * sizeof(MeshAttachment));
|
||||
|
||||
while ((key = map_next(&mesh->attachments, &iter)) != NULL) {
|
||||
int location = lovrShaderGetAttributeId(shader, key);
|
||||
|
||||
if (location >= 0) {
|
||||
MeshAttachment* attachment = map_get(&mesh->attachments, key);
|
||||
layout[location] = *attachment;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_ATTACHMENTS; i++) {
|
||||
MeshAttachment previous = mesh->layout[i];
|
||||
MeshAttachment current = layout[i];
|
||||
|
||||
if (!memcmp(&previous, ¤t, sizeof(MeshAttachment))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previous.enabled != current.enabled) {
|
||||
if (current.enabled) {
|
||||
glEnableVertexAttribArray(i);
|
||||
} else {
|
||||
glDisableVertexAttribArray(i);
|
||||
mesh->layout[i] = current;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (previous.divisor != current.divisor) {
|
||||
glVertexAttribDivisor(i, current.divisor);
|
||||
}
|
||||
|
||||
if (previous.mesh != current.mesh || previous.attributeIndex != current.attributeIndex) {
|
||||
lovrGraphicsBindVertexBuffer(current.mesh->vbo);
|
||||
VertexFormat* format = ¤t.mesh->format;
|
||||
Attribute attribute = format->attributes[current.attributeIndex];
|
||||
switch (attribute.type) {
|
||||
case ATTR_FLOAT:
|
||||
glVertexAttribPointer(i, attribute.count, GL_FLOAT, GL_TRUE, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
|
||||
case ATTR_BYTE:
|
||||
glVertexAttribPointer(i, attribute.count, GL_UNSIGNED_BYTE, GL_TRUE, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
|
||||
case ATTR_INT:
|
||||
glVertexAttribIPointer(i, attribute.count, GL_UNSIGNED_INT, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->layout[i] = current;
|
||||
}
|
||||
}
|
||||
|
||||
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, MeshUsage usage) {
|
||||
Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy);
|
||||
if (!mesh) return NULL;
|
||||
|
@ -135,30 +73,64 @@ void lovrMeshDetachAttribute(Mesh* mesh, const char* name) {
|
|||
map_remove(&mesh->attachments, name);
|
||||
}
|
||||
|
||||
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
|
||||
lovrMeshUnmapVertices(mesh);
|
||||
lovrMeshUnmapIndices(mesh);
|
||||
void lovrMeshBind(Mesh* mesh, Shader* shader) {
|
||||
const char* key;
|
||||
map_iter_t iter = map_iter(&mesh->attachments);
|
||||
|
||||
if (transform) {
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsMatrixTransform(transform);
|
||||
MeshAttachment layout[MAX_ATTACHMENTS];
|
||||
memset(layout, 0, MAX_ATTACHMENTS * sizeof(MeshAttachment));
|
||||
|
||||
while ((key = map_next(&mesh->attachments, &iter)) != NULL) {
|
||||
int location = lovrShaderGetAttributeId(shader, key);
|
||||
|
||||
if (location >= 0) {
|
||||
MeshAttachment* attachment = map_get(&mesh->attachments, key);
|
||||
layout[location] = *attachment;
|
||||
}
|
||||
}
|
||||
|
||||
lovrGraphicsPrepare(mesh->material, pose);
|
||||
lovrGraphicsBindVertexArray(mesh->vao);
|
||||
lovrMeshBindAttributes(mesh);
|
||||
size_t start = mesh->rangeStart;
|
||||
size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->count;
|
||||
if (mesh->indexCount > 0) {
|
||||
size_t offset = start * mesh->indexSize;
|
||||
count = mesh->rangeCount ? mesh->rangeCount : mesh->indexCount;
|
||||
lovrGraphicsDrawElements(mesh->drawMode, count, mesh->indexSize, offset, instances);
|
||||
} else {
|
||||
lovrGraphicsDrawArrays(mesh->drawMode, start, count, instances);
|
||||
}
|
||||
for (int i = 0; i < MAX_ATTACHMENTS; i++) {
|
||||
MeshAttachment previous = mesh->layout[i];
|
||||
MeshAttachment current = layout[i];
|
||||
|
||||
if (transform) {
|
||||
lovrGraphicsPop();
|
||||
if (!memcmp(&previous, ¤t, sizeof(MeshAttachment))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previous.enabled != current.enabled) {
|
||||
if (current.enabled) {
|
||||
glEnableVertexAttribArray(i);
|
||||
} else {
|
||||
glDisableVertexAttribArray(i);
|
||||
mesh->layout[i] = current;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (previous.divisor != current.divisor) {
|
||||
glVertexAttribDivisor(i, current.divisor);
|
||||
}
|
||||
|
||||
if (previous.mesh != current.mesh || previous.attributeIndex != current.attributeIndex) {
|
||||
lovrGraphicsBindVertexBuffer(current.mesh->vbo);
|
||||
VertexFormat* format = ¤t.mesh->format;
|
||||
Attribute attribute = format->attributes[current.attributeIndex];
|
||||
switch (attribute.type) {
|
||||
case ATTR_FLOAT:
|
||||
glVertexAttribPointer(i, attribute.count, GL_FLOAT, GL_TRUE, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
|
||||
case ATTR_BYTE:
|
||||
glVertexAttribPointer(i, attribute.count, GL_UNSIGNED_BYTE, GL_TRUE, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
|
||||
case ATTR_INT:
|
||||
glVertexAttribIPointer(i, attribute.count, GL_UNSIGNED_INT, format->stride, (void*) attribute.offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->layout[i] = current;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,6 +187,14 @@ void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
|
|||
}
|
||||
}
|
||||
|
||||
float* lovrMeshGetPose(Mesh* mesh) {
|
||||
return mesh->pose;
|
||||
}
|
||||
|
||||
void lovrMeshSetPose(Mesh* mesh, float* pose) {
|
||||
mesh->pose = pose;
|
||||
}
|
||||
|
||||
VertexPointer lovrMeshMapVertices(Mesh* mesh, uint32_t start, uint32_t count, bool read, bool write) {
|
||||
#ifdef EMSCRIPTEN
|
||||
mesh->mappedVertices = true;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "graphics/material.h"
|
||||
#include "graphics/shader.h"
|
||||
#include "data/vertexData.h"
|
||||
#include "math/math.h"
|
||||
#include "lib/glfw.h"
|
||||
|
@ -59,6 +60,7 @@ struct Mesh {
|
|||
GLuint vbo;
|
||||
GLuint ibo;
|
||||
Material* material;
|
||||
float* pose;
|
||||
map_attachment_t attachments;
|
||||
MeshAttachment layout[MAX_ATTACHMENTS];
|
||||
bool isAttachment;
|
||||
|
@ -68,7 +70,7 @@ Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode,
|
|||
void lovrMeshDestroy(void* ref);
|
||||
void lovrMeshAttachAttribute(Mesh* mesh, Mesh* other, const char* name, int divisor);
|
||||
void lovrMeshDetachAttribute(Mesh* mesh, const char* name);
|
||||
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances);
|
||||
void lovrMeshBind(Mesh* mesh, Shader* shader);
|
||||
VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh);
|
||||
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
|
||||
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
|
||||
|
@ -79,6 +81,8 @@ void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count);
|
|||
void lovrMeshSetDrawRange(Mesh* mesh, int start, int count);
|
||||
Material* lovrMeshGetMaterial(Mesh* mesh);
|
||||
void lovrMeshSetMaterial(Mesh* mesh, Material* material);
|
||||
float* lovrMeshGetPose(Mesh* mesh);
|
||||
void lovrMeshSetPose(Mesh* mesh, float* pose);
|
||||
VertexPointer lovrMeshMapVertices(Mesh* mesh, uint32_t start, uint32_t count, bool read, bool write);
|
||||
void lovrMeshUnmapVertices(Mesh* mesh);
|
||||
IndexPointer lovrMeshReadIndices(Mesh* mesh, uint32_t* count, size_t* size);
|
||||
|
|
|
@ -38,7 +38,8 @@ static void renderNode(Model* model, int nodeIndex, int instances) {
|
|||
}
|
||||
|
||||
lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount);
|
||||
lovrMeshDraw(model->mesh, NULL, (float*) model->pose, instances);
|
||||
lovrMeshSetPose(model->mesh, (float*) model->pose);
|
||||
lovrGraphicsDraw(model->mesh, NULL, SHADER_DEFAULT, instances);
|
||||
}
|
||||
|
||||
lovrGraphicsPop();
|
||||
|
@ -163,6 +164,7 @@ void lovrModelDraw(Model* model, mat4 transform, int instances) {
|
|||
lovrGraphicsMatrixTransform(transform);
|
||||
renderNode(model, 0, instances);
|
||||
lovrGraphicsPop();
|
||||
lovrMeshSetPose(model->mesh, NULL);
|
||||
}
|
||||
|
||||
Animator* lovrModelGetAnimator(Model* model) {
|
||||
|
|
Loading…
Reference in New Issue