lovr.graphics.arc;

This commit is contained in:
bjorn 2017-11-22 11:32:30 -08:00
parent b540fdbfdb
commit 5c45282d9b
3 changed files with 62 additions and 16 deletions

View File

@ -12,6 +12,7 @@
#include <math.h>
#include <stdbool.h>
map_int_t ArcModes;
map_int_t BlendAlphaModes;
map_int_t BlendModes;
map_int_t CompareModes;
@ -82,6 +83,11 @@ int l_lovrGraphicsInit(lua_State* L) {
luax_registertype(L, "Shader", lovrShader);
luax_registertype(L, "Texture", lovrTexture);
map_init(&ArcModes);
map_set(&ArcModes, "pie", ARC_MODE_PIE);
map_set(&ArcModes, "open", ARC_MODE_OPEN);
map_set(&ArcModes, "closed", ARC_MODE_CLOSED);
map_init(&BlendAlphaModes);
map_set(&BlendAlphaModes, "alphamultiply", BLEND_ALPHA_MULTIPLY);
map_set(&BlendAlphaModes, "premultiplied", BLEND_PREMULTIPLIED);
@ -525,6 +531,22 @@ int l_lovrGraphicsBox(lua_State* L) {
return luax_rectangularprism(L, false);
}
int l_lovrGraphicsArc(lua_State* L) {
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
ArcMode arcMode = ARC_MODE_PIE;
int index = 2;
if (lua_type(L, 2) == LUA_TSTRING) {
arcMode = *(ArcMode*) luax_checkenum(L, index++, &ArcModes, "arc mode");
}
float transform[16];
index = luax_readtransform(L, index, transform, true);
float theta1 = luaL_optnumber(L, index++, 0);
float theta2 = luaL_optnumber(L, index++, 2 * M_PI);
int segments = luaL_optinteger(L, index, 32) * fabsf(theta2 - theta1) * 2 * M_PI + .5f;
lovrGraphicsArc(drawMode, arcMode, transform, theta1, theta2, segments);
return 0;
}
int l_lovrGraphicsCircle(lua_State* L) {
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
float transform[16];
@ -824,6 +846,7 @@ const luaL_Reg lovrGraphics[] = {
{ "plane", l_lovrGraphicsPlane },
{ "cube", l_lovrGraphicsCube },
{ "box", l_lovrGraphicsBox },
{ "arc", l_lovrGraphicsArc },
{ "circle", l_lovrGraphicsCircle },
{ "cylinder", l_lovrGraphicsCylinder },
{ "sphere", l_lovrGraphicsSphere },

View File

@ -707,38 +707,49 @@ void lovrGraphicsBox(DrawMode mode, mat4 transform) {
lovrGraphicsPop();
}
void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments) {
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, mat4 transform, float theta1, float theta2, int segments) {
if (fabsf(theta1 - theta2) >= 2 * M_PI) {
theta1 = 0;
theta2 = 2 * M_PI;
}
lovrGraphicsPush();
lovrGraphicsMatrixTransform(MATRIX_MODEL, transform);
vec_clear(&state.streamData);
if (arcMode == ARC_MODE_PIE && fabsf(theta1 - theta2) < 2 * M_PI) {
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
if (mode == DRAW_MODE_FILL) {
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 1);
vec_push(&state.streamData, .5);
vec_push(&state.streamData, .5);
}
}
float theta = theta1;
float angleShift = (theta2 - theta1) / (float) segments;
if (mode == DRAW_MODE_LINE) {
for (int i = 0; i < segments; i++) {
float theta = i / (float) segments * 2 * M_PI;
for (int i = 0; i <= segments; i++) {
float x = cos(theta) * .5;
float y = sin(theta) * .5;
vec_push(&state.streamData, x);
vec_push(&state.streamData, y);
vec_push(&state.streamData, 0);
theta += angleShift;
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, false, false, false);
lovrGraphicsDrawPrimitive(arcMode == ARC_MODE_OPEN ? GL_LINE_STRIP : GL_LINE_LOOP, false, false, false);
} else if (mode == DRAW_MODE_FILL) {
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 0);
vec_push(&state.streamData, 1);
vec_push(&state.streamData, .5);
vec_push(&state.streamData, .5);
for (int i = 0; i <= segments; i++) {
float theta = i / (float) segments * 2 * M_PI;
float x = cos(theta) * .5;
float y = sin(theta) * .5;
vec_push(&state.streamData, x);
@ -751,6 +762,7 @@ void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments) {
vec_push(&state.streamData, x + .5);
vec_push(&state.streamData, 1 - (y + .5));
theta += angleShift;
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
@ -760,6 +772,10 @@ void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments) {
lovrGraphicsPop();
}
void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments) {
lovrGraphicsArc(mode, ARC_MODE_OPEN, transform, 0, 2 * M_PI, segments);
}
void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments) {
float axis[3] = { x1 - x2, y1 - y2, z1 - z2 };
float n[3] = { x1 - x2, y1 - y2, z1 - z2 };

View File

@ -35,6 +35,12 @@ typedef enum {
DRAW_MODE_LINE
} DrawMode;
typedef enum {
ARC_MODE_PIE,
ARC_MODE_OPEN,
ARC_MODE_CLOSED
} ArcMode;
typedef enum {
WINDING_CLOCKWISE = GL_CW,
WINDING_COUNTERCLOCKWISE = GL_CCW
@ -163,6 +169,7 @@ void lovrGraphicsTriangle(DrawMode mode, float* points);
void lovrGraphicsPlane(DrawMode mode, mat4 transform);
void lovrGraphicsPlaneFullscreen(Texture* texture);
void lovrGraphicsBox(DrawMode mode, mat4 transform);
void lovrGraphicsArc(DrawMode mode, ArcMode, mat4 transform, float theta1, float theta2, int segments);
void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments);
void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments);
void lovrGraphicsSphere(mat4 transform, int segments);