shaders
This commit is contained in:
parent
eb3e576521
commit
e0f3985b00
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
|||
#ifndef TWODPHYSICS_H
|
||||
#define TWODPHYSICS_H
|
||||
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include "script.h"
|
||||
#include <chipmunk/chipmunk.h>
|
||||
|
||||
struct gameobject;
|
||||
|
||||
|
@ -18,53 +18,53 @@ extern float kinematic_color[3];
|
|||
extern float static_color[3];
|
||||
|
||||
struct phys2d_shape {
|
||||
cpShape *shape;
|
||||
int go;
|
||||
void *data;
|
||||
void (*debugdraw)(void *data);
|
||||
float (*moi)(void *data, float mass);
|
||||
cpShape *shape;
|
||||
int go;
|
||||
void *data;
|
||||
void (*debugdraw)(void *data);
|
||||
float (*moi)(void *data, float mass);
|
||||
};
|
||||
|
||||
/* Circles are the fastest collier type */
|
||||
struct phys2d_circle {
|
||||
float radius;
|
||||
cpVect offset;
|
||||
struct phys2d_shape shape;
|
||||
float radius;
|
||||
cpVect offset;
|
||||
struct phys2d_shape shape;
|
||||
};
|
||||
|
||||
/* A single segment */
|
||||
struct phys2d_segment {
|
||||
float a[2];
|
||||
float b[2];
|
||||
float thickness;
|
||||
struct phys2d_shape shape;
|
||||
float a[2];
|
||||
float b[2];
|
||||
float thickness;
|
||||
struct phys2d_shape shape;
|
||||
};
|
||||
|
||||
/* A convex polygon; defined as the convex hull around the given set of points */
|
||||
struct phys2d_poly {
|
||||
cpVect *points;
|
||||
float radius;
|
||||
struct phys2d_shape shape;
|
||||
cpVect *points;
|
||||
float radius;
|
||||
struct phys2d_shape shape;
|
||||
};
|
||||
|
||||
/* A box shape; a type of a polygon collider */
|
||||
struct phys2d_box {
|
||||
float w;
|
||||
float h;
|
||||
float offset[2];
|
||||
float rotation;
|
||||
float r;
|
||||
struct phys2d_shape shape;
|
||||
float w;
|
||||
float h;
|
||||
float offset[2];
|
||||
float rotation;
|
||||
float r;
|
||||
struct phys2d_shape shape;
|
||||
};
|
||||
|
||||
/* An edge with no volume. Cannot collide with each other. Join to make levels. Static only. */
|
||||
struct phys2d_edge {
|
||||
cpVect *points;
|
||||
float thickness;
|
||||
cpShape **shapes;
|
||||
int closed; /* True if the first and last points should be connected */
|
||||
struct phys2d_shape shape;
|
||||
int draws;
|
||||
cpVect *points;
|
||||
float thickness;
|
||||
cpShape **shapes;
|
||||
int closed; /* True if the first and last points should be connected */
|
||||
struct phys2d_shape shape;
|
||||
int draws;
|
||||
};
|
||||
|
||||
struct phys2d_circle *Make2DCircle(int go);
|
||||
|
@ -107,8 +107,8 @@ cpShape *phys2d_query_pos(cpVect pos);
|
|||
int *phys2d_query_box(cpVect pos, cpVect wh);
|
||||
|
||||
struct phys_cbs {
|
||||
struct callee begin;
|
||||
struct callee separate;
|
||||
struct callee begin;
|
||||
struct callee separate;
|
||||
};
|
||||
|
||||
struct shape_cb {
|
||||
|
@ -127,9 +127,9 @@ void shape_set_sensor(struct phys2d_shape *shape, int sensor);
|
|||
int shape_get_sensor(struct phys2d_shape *shape);
|
||||
|
||||
struct color {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
};
|
||||
|
||||
void color2float(struct color, float *fcolor);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef THREEDPHYSICS_H
|
||||
#define THREEDPHYSICS_H
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,26 +42,26 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
|||
glm::vec3 p1 = CalculateCenter();
|
||||
|
||||
glm::vec3 p2 =
|
||||
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
||||
FloatWidths.
|
||||
x) : GetExtentsOffset(TFOR.Right(),
|
||||
FloatWidths.x,
|
||||
TargetOffset.x,
|
||||
AnchorWidths.x);
|
||||
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
||||
FloatWidths.
|
||||
x) : GetExtentsOffset(TFOR.Right(),
|
||||
FloatWidths.x,
|
||||
TargetOffset.x,
|
||||
AnchorWidths.x);
|
||||
glm::vec3 p3 =
|
||||
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
||||
FloatWidths.
|
||||
y) : GetExtentsOffset(TFOR.Up(),
|
||||
FloatWidths.y,
|
||||
TargetOffset.y,
|
||||
AnchorWidths.y);
|
||||
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
||||
FloatWidths.
|
||||
y) : GetExtentsOffset(TFOR.Up(),
|
||||
FloatWidths.y,
|
||||
TargetOffset.y,
|
||||
AnchorWidths.y);
|
||||
glm::vec3 p4 =
|
||||
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
||||
FloatWidths.
|
||||
z) : GetExtentsOffset(TFOR.Back(),
|
||||
FloatWidths.z,
|
||||
TargetOffset.z,
|
||||
AnchorWidths.z);
|
||||
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
||||
FloatWidths.
|
||||
z) : GetExtentsOffset(TFOR.Back(),
|
||||
FloatWidths.z,
|
||||
TargetOffset.z,
|
||||
AnchorWidths.z);
|
||||
|
||||
return p1 + p2 + p3 + p4;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
|||
glm::vec3 ThirdPersonFollow::CalculateCenter()
|
||||
{
|
||||
return Target->get_global_translation() +
|
||||
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
||||
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
||||
}
|
||||
|
||||
glm::vec3 ThirdPersonFollow::
|
||||
|
@ -82,37 +82,37 @@ GetPostsOffset(const glm::vec3 & DirectionVector, float AnchorWidth)
|
|||
|
||||
glm::vec3 ThirdPersonFollow::
|
||||
GetExtentsOffset(const glm::vec3 & DirectionVector, float AnchorWidth,
|
||||
float TOffset, float Width)
|
||||
float TOffset, float Width)
|
||||
{
|
||||
|
||||
float negated_offset_sign = ((0 <= TOffset) - (TOffset < 0)) * -1.f;
|
||||
float TotalWidth = AnchorWidth + Width;
|
||||
|
||||
if (glm::abs(TOffset) > TotalWidth
|
||||
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
||||
return DirectionVector * TotalWidth * negated_offset_sign;
|
||||
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
||||
return DirectionVector * TotalWidth * negated_offset_sign;
|
||||
else {
|
||||
if (glm::abs(TOffset) >= AnchorWidth)
|
||||
return DirectionVector * AnchorWidth * negated_offset_sign;
|
||||
else
|
||||
return DirectionVector * TOffset * -1.f;
|
||||
if (glm::abs(TOffset) >= AnchorWidth)
|
||||
return DirectionVector * AnchorWidth * negated_offset_sign;
|
||||
else
|
||||
return DirectionVector * TOffset * -1.f;
|
||||
}
|
||||
|
||||
return glm::vec3(0.f);
|
||||
}
|
||||
|
||||
glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds,
|
||||
float Tick)
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds,
|
||||
float Tick)
|
||||
{
|
||||
// Previously "FORTransform.TransformVector(Speeds)
|
||||
glm::vec3 TSpeed = glm::abs(TFOR.TransformDirection(Speeds));
|
||||
glm::vec3 TOffset = glm::abs(TFOR.TransformDirection(TargetOffset));
|
||||
glm::vec3 TAnchorWidths =
|
||||
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
||||
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
||||
glm::vec3 TFloatWidths =
|
||||
glm::abs(TFOR.TransformDirection(FloatWidths));
|
||||
glm::abs(TFOR.TransformDirection(FloatWidths));
|
||||
|
||||
|
||||
|
||||
|
@ -124,14 +124,14 @@ glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
|||
|
||||
|
||||
float xAlpha =
|
||||
glm::clamp((bUseX ? AnchorSpeed : TSpeed.x) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseX ? AnchorSpeed : TSpeed.x) * Tick, 0.f, 1.f);
|
||||
float yAlpha =
|
||||
glm::clamp((bUseY ? AnchorSpeed : TSpeed.y) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseY ? AnchorSpeed : TSpeed.y) * Tick, 0.f, 1.f);
|
||||
float zAlpha =
|
||||
glm::clamp((bUseZ ? AnchorSpeed : TSpeed.z) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseZ ? AnchorSpeed : TSpeed.z) * Tick, 0.f, 1.f);
|
||||
|
||||
return VectorLerpPiecewise(From, To,
|
||||
glm::vec3(xAlpha, yAlpha, zAlpha));
|
||||
glm::vec3(xAlpha, yAlpha, zAlpha));
|
||||
}
|
||||
|
||||
int float_epsilon(mfloat_t a, mfloat_t b, mfloat_t e)
|
||||
|
@ -165,11 +165,11 @@ void ThirdPersonFollow::CalculateTargets()
|
|||
// For rotation
|
||||
// TODO: Check of this implementation is the same as UKismetMath FindLookAtRotation
|
||||
TargetRotation =
|
||||
RemoveLockedRotation(glm::quat
|
||||
(mytransform->
|
||||
get_global_transform()->get_origin() -
|
||||
Target->
|
||||
get_global_transform()->get_origin()));
|
||||
RemoveLockedRotation(glm::quat
|
||||
(mytransform->
|
||||
get_global_transform()->get_origin() -
|
||||
Target->
|
||||
get_global_transform()->get_origin()));
|
||||
}
|
||||
|
||||
follow_removelockedrot()
|
||||
|
@ -185,11 +185,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
|||
//
|
||||
|
||||
NewRotator.x =
|
||||
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
||||
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
||||
NewRotator.y =
|
||||
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
||||
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
||||
NewRotator.z =
|
||||
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
||||
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
||||
|
||||
return glm::quat(NewRotator);
|
||||
}
|
||||
|
@ -199,11 +199,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
|||
void ThirdPersonFollow::CalculateTargetOffset()
|
||||
{
|
||||
glm::vec3 p1 =
|
||||
(mytransform->Forward() * Distance) +
|
||||
TFOR.TransformDirection(Offset) +
|
||||
mytransform->get_global_translation();
|
||||
(mytransform->Forward() * Distance) +
|
||||
TFOR.TransformDirection(Offset) +
|
||||
mytransform->get_global_translation();
|
||||
glm::vec3 p2 =
|
||||
TFOR.InverseTransformDirection(Target->get_global_translation());
|
||||
TFOR.InverseTransformDirection(Target->get_global_translation());
|
||||
glm::vec3 p3 = TFOR.InverseTransformDirection(p1);
|
||||
|
||||
TargetOffset = p2 - p3;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include "transform.h"
|
||||
|
||||
struct follow {
|
||||
float distance;
|
||||
mfloat_t target_rot[4];
|
||||
float distance;
|
||||
mfloat_t target_rot[4];
|
||||
};
|
||||
|
||||
mfloat_t *follow_calccenter();
|
||||
|
@ -31,45 +31,45 @@ class ThirdPersonFollow {
|
|||
|
||||
public:
|
||||
enum CameraType {
|
||||
STATIONARY,
|
||||
TRANSLATING,
|
||||
ROTATING,
|
||||
SPLINE
|
||||
STATIONARY,
|
||||
TRANSLATING,
|
||||
ROTATING,
|
||||
SPLINE
|
||||
};
|
||||
|
||||
enum CameraTransition {
|
||||
NONE,
|
||||
CROSSDISSOLVE,
|
||||
WIPE,
|
||||
DIP
|
||||
NONE,
|
||||
CROSSDISSOLVE,
|
||||
WIPE,
|
||||
DIP
|
||||
};
|
||||
|
||||
enum FrameOfReference {
|
||||
LOCAL,
|
||||
WORLD,
|
||||
EXTERNAL
|
||||
LOCAL,
|
||||
WORLD,
|
||||
EXTERNAL
|
||||
};
|
||||
|
||||
ThirdPersonFollow() {
|
||||
// Rotation
|
||||
RotationSpeed = 10.0f;
|
||||
LockPitch = LockYaw = LockRoll = true;
|
||||
// Rotation
|
||||
RotationSpeed = 10.0f;
|
||||
LockPitch = LockYaw = LockRoll = true;
|
||||
|
||||
XDirPosts = false;
|
||||
YDirPosts = false;
|
||||
ZDirPosts = false;
|
||||
XDirPosts = false;
|
||||
YDirPosts = false;
|
||||
ZDirPosts = false;
|
||||
|
||||
|
||||
// Translation
|
||||
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
||||
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
||||
//TranslationScales = glm::vec3(1, 1, 1);
|
||||
// Translation
|
||||
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
||||
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
||||
//TranslationScales = glm::vec3(1, 1, 1);
|
||||
|
||||
// Frame settings
|
||||
Offset = glm::vec3(0.f, 0.f, 0.f);
|
||||
Distance = 10;
|
||||
// Frame settings
|
||||
Offset = glm::vec3(0.f, 0.f, 0.f);
|
||||
Distance = 10;
|
||||
|
||||
AnchorSpeed = 80;
|
||||
AnchorSpeed = 80;
|
||||
} ~ThirdPersonFollow() {
|
||||
}
|
||||
|
||||
|
@ -81,14 +81,14 @@ class ThirdPersonFollow {
|
|||
|
||||
|
||||
void SetExternalFrame(Transform * val) {
|
||||
ExternalFrame = val;
|
||||
ExternalFrame = val;
|
||||
}
|
||||
|
||||
// The target the camera "looks" at, used for calculations
|
||||
Transform *Target = nullptr;
|
||||
|
||||
void SetTarget(Transform * val) {
|
||||
Target = val;
|
||||
Target = val;
|
||||
}
|
||||
|
||||
// Offset from the target
|
||||
|
@ -158,25 +158,25 @@ class ThirdPersonFollow {
|
|||
|
||||
/// Given a direction and width, find the offsets.
|
||||
glm::vec3 GetPostsOffset(const glm::vec3 & DirectionVector,
|
||||
float AnchorWidth);
|
||||
float AnchorWidth);
|
||||
|
||||
/// Given anchors, what's the anchor width?
|
||||
glm::vec3 GetExtentsOffset(const glm::vec3 & DirectionVector,
|
||||
float AnchorWidth, float TOffset,
|
||||
float Width);
|
||||
float AnchorWidth, float TOffset,
|
||||
float Width);
|
||||
|
||||
glm::quat RemoveLockedRotation(const glm::quat & CurrentRotation);
|
||||
|
||||
glm::vec3 FrameBasedVectorLerp(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds, float Tick);
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds, float Tick);
|
||||
|
||||
glm::vec3 VectorLerpPiecewise(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Alpha);
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Alpha);
|
||||
|
||||
bool GetLerpParam(const float Offst, const float AnchorWidth,
|
||||
const float FloatWidth);
|
||||
const float FloatWidth);
|
||||
|
||||
/// Set to a value that gives good clamping, smoothly. Activates when
|
||||
/// the target is out of range.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "light.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/*
|
||||
void Light::serialize(FILE * file)
|
||||
{
|
||||
|
@ -30,20 +29,20 @@ struct mDirectionalLight *dLight = NULL;
|
|||
struct mDirectionalLight *MakeDLight()
|
||||
{
|
||||
if (dLight != NULL) {
|
||||
dLight =
|
||||
(struct mDirectionalLight *)
|
||||
malloc(sizeof(struct mDirectionalLight));
|
||||
quat_from_euler(dLight->light.obj.transform.rotation,
|
||||
dlight_init_rot);
|
||||
dLight =
|
||||
(struct mDirectionalLight *)
|
||||
malloc(sizeof(struct mDirectionalLight));
|
||||
quat_from_euler(dLight->light.obj.transform.rotation,
|
||||
dlight_init_rot);
|
||||
|
||||
return dLight;
|
||||
return dLight;
|
||||
}
|
||||
|
||||
return dLight;
|
||||
}
|
||||
|
||||
void dlight_prepshader(struct mDirectionalLight *light,
|
||||
struct shader *shader)
|
||||
struct shader *shader)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
trans_forward(fwd, &light->light.obj.transform);
|
||||
|
@ -61,14 +60,14 @@ static int numLights = 0;
|
|||
struct mPointLight *MakePointlight()
|
||||
{
|
||||
if (numLights < 4) {
|
||||
struct mPointLight *light =
|
||||
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
||||
pointLights[numLights++] = light;
|
||||
light->light.strength = 0.2f;
|
||||
light->constant = 1.f;
|
||||
light->linear = 0.9f;
|
||||
light->quadratic = 0.032f;
|
||||
return light;
|
||||
struct mPointLight *light =
|
||||
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
||||
pointLights[numLights++] = light;
|
||||
light->light.strength = 0.2f;
|
||||
light->constant = 1.f;
|
||||
light->linear = 0.9f;
|
||||
light->quadratic = 0.032f;
|
||||
return light;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -82,11 +81,11 @@ static void prepstring(char *buffer, char *prepend, const char *append)
|
|||
void pointlights_prepshader(struct shader *shader)
|
||||
{
|
||||
for (int i = 0; i < numLights; i++)
|
||||
pointlight_prepshader(pointLights[i], shader, i);
|
||||
pointlight_prepshader(pointLights[i], shader, i);
|
||||
}
|
||||
|
||||
void pointlight_prepshader(struct mPointLight *light,
|
||||
struct shader *shader, int num)
|
||||
struct shader *shader, int num)
|
||||
{
|
||||
shader_use(shader);
|
||||
char prepend[100] = { '\0' };
|
||||
|
@ -121,10 +120,10 @@ static int numSpots = 0;
|
|||
struct mSpotLight *MakeSpotlight()
|
||||
{
|
||||
if (numSpots < 4) {
|
||||
struct mSpotLight *light =
|
||||
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
||||
spotLights[numSpots++] = light;
|
||||
return light;
|
||||
struct mSpotLight *light =
|
||||
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
||||
spotLights[numSpots++] = light;
|
||||
return light;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -135,17 +134,17 @@ struct mSpotLight *MakeSpotlight()
|
|||
void spotlights_prepshader(struct shader *shader)
|
||||
{
|
||||
for (int i = 0; i < numSpots; i++)
|
||||
spotlight_prepshader(spotLights[i], shader, i);
|
||||
spotlight_prepshader(spotLights[i], shader, i);
|
||||
}
|
||||
|
||||
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||
int num)
|
||||
int num)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
trans_forward(fwd, &light->light.obj.transform);
|
||||
shader_use(shader);
|
||||
shader_setvec3(shader, "spotLight.position",
|
||||
light->light.obj.transform.position);
|
||||
light->light.obj.transform.position);
|
||||
shader_setvec3(shader, "spotLight.direction", fwd);
|
||||
shader_setvec3(shader, "spotLight.color", light->light.color);
|
||||
shader_setfloat(shader, "spotLight.strength", light->light.strength);
|
||||
|
@ -165,10 +164,10 @@ void light_gui(struct mLight *light)
|
|||
object_gui(&light->obj);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Light", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Strength", 0.f, &light->strength, 1.f, 0.01f, 0.001f);
|
||||
// ImGui::ColorEdit3("Color", &light->color[0]);
|
||||
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Strength", 0.f, &light->strength, 1.f, 0.01f, 0.001f);
|
||||
// ImGui::ColorEdit3("Color", &light->color[0]);
|
||||
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,10 +177,10 @@ void pointlight_gui(struct mPointLight *light)
|
|||
light_gui(&light->light);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Point Light", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Constant", 0.f, &light->constant, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Linear", 0.f, &light->linear, 0.3f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &light->quadratic, 0.3f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Constant", 0.f, &light->constant, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Linear", 0.f, &light->linear, 0.3f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &light->quadratic, 0.3f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -191,12 +190,12 @@ void spotlight_gui(struct mSpotLight *spot)
|
|||
light_gui(&spot->light);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Spotlight", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Linear", 0.f, &spot->linear, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &spot->quadratic, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Distance", 0.f, &spot->distance, 200.f, 1.f, 0.1f, 200.f);
|
||||
nk_property_float(ctx, "Cutoff Degrees", 0.f, &spot->cutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Outer Cutoff Degrees", 0.f, &spot->outerCutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Linear", 0.f, &spot->linear, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &spot->quadratic, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Distance", 0.f, &spot->distance, 200.f, 1.f, 0.1f, 200.f);
|
||||
nk_property_float(ctx, "Cutoff Degrees", 0.f, &spot->cutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Outer Cutoff Degrees", 0.f, &spot->outerCutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include <stdint.h>
|
||||
|
||||
struct mLight {
|
||||
struct gameobject *go;
|
||||
uint8_t color[3];
|
||||
float strength;
|
||||
int dynamic;
|
||||
int on;
|
||||
struct gameobject *go;
|
||||
uint8_t color[3];
|
||||
float strength;
|
||||
int dynamic;
|
||||
int on;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -21,7 +21,7 @@ struct mPointLight {
|
|||
|
||||
struct mPointLight *MakePointlight();
|
||||
void pointlight_prepshader(struct mPointLight *light,
|
||||
struct shader *shader, int num);
|
||||
struct shader *shader, int num);
|
||||
void pointlights_prepshader(struct shader *shader);
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct mSpotLight {
|
|||
struct mSpotLight *MakeSpotlight();
|
||||
void spotlight_gui(struct mSpotLight *light);
|
||||
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||
int num);
|
||||
int num);
|
||||
void spotlights_prepshader(struct shader *shader);
|
||||
|
||||
|
||||
|
@ -49,7 +49,7 @@ struct mDirectionalLight {
|
|||
};
|
||||
|
||||
void dlight_prepshader(struct mDirectionalLight *light,
|
||||
struct shader *shader);
|
||||
struct shader *shader);
|
||||
struct mDirectionalLight *MakeDLight();
|
||||
|
||||
extern struct mDirectionalLight *dLight;
|
||||
|
|
|
@ -4,122 +4,94 @@
|
|||
#include "shader.h"
|
||||
#include "texture.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader)
|
||||
{
|
||||
// bind appropriate textures
|
||||
uint32_t diffuseNr = 1;
|
||||
uint32_t specularNr = 1;
|
||||
uint32_t normalNr = 1;
|
||||
uint32_t heightNr = 1;
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader) {
|
||||
// bind appropriate textures
|
||||
uint32_t diffuseNr = 1;
|
||||
uint32_t specularNr = 1;
|
||||
uint32_t normalNr = 1;
|
||||
uint32_t heightNr = 1;
|
||||
|
||||
for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
||||
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||
// retrieve texture number (the N in diffuse_textureN)
|
||||
char number = 0;
|
||||
// TODO: malloc every single frame ... nope! Change to stack
|
||||
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
||||
/*
|
||||
if (mesh->textures[i].type == TEX_DIFF)
|
||||
number = diffuseNr++;
|
||||
else if (mesh->textures[i].type == TEX_SPEC)
|
||||
number = specularNr++;
|
||||
else if (mesh->textures[i].type == TEX_NORM)
|
||||
number = normalNr++;
|
||||
else if (mesh->textures[i].type == TEX_HEIGHT)
|
||||
number = heightNr++;
|
||||
// for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
||||
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||
// retrieve texture number (the N in diffuse_textureN)
|
||||
// char number = 0;
|
||||
// TODO: malloc every single frame ... nope! Change to stack
|
||||
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
||||
/*
|
||||
// if (mesh->textures[i].type == TEX_DIFF)
|
||||
// number = diffuseNr++;
|
||||
// else if (mesh->textures[i].type == TEX_SPEC)
|
||||
// number = specularNr++;
|
||||
// else if (mesh->textures[i].type == TEX_NORM)
|
||||
// number = normalNr++;
|
||||
// else if (mesh->textures[i].type == TEX_HEIGHT)
|
||||
// number = heightNr++;
|
||||
*/
|
||||
|
||||
/*
|
||||
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
||||
free(name);
|
||||
*/
|
||||
}
|
||||
|
||||
// draw mesh
|
||||
glBindVertexArray(mesh->VAO);
|
||||
DrawMeshAgain(mesh);
|
||||
|
||||
// DEBUG
|
||||
// triCount += indices.size() / 3;
|
||||
/*
|
||||
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
||||
free(name);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void DrawMeshAgain(struct mesh *mesh)
|
||||
{
|
||||
void DrawMeshAgain(struct mesh *mesh) {
|
||||
}
|
||||
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
||||
uint32_t * indices, uint32_t * ie,
|
||||
struct Texture *textures, struct Texture *te)
|
||||
{
|
||||
struct mesh *newmesh = (struct mesh *) malloc(sizeof(struct mesh));
|
||||
newmesh->vertices = vertices;
|
||||
newmesh->ve = ve;
|
||||
newmesh->indices = indices;
|
||||
newmesh->ie = ie;
|
||||
newmesh->textures = textures;
|
||||
newmesh->te = te;
|
||||
void setupmesh(struct mesh *mesh) {
|
||||
/*
|
||||
// create buffers/arrays
|
||||
glGenVertexArrays(1, &mesh->VAO);
|
||||
glGenBuffers(1, &mesh->VBO);
|
||||
glGenBuffers(1, &mesh->EBO);
|
||||
|
||||
setupmesh(newmesh);
|
||||
return newmesh;
|
||||
}
|
||||
|
||||
void setupmesh(struct mesh *mesh)
|
||||
{
|
||||
/*
|
||||
// create buffers/arrays
|
||||
glGenVertexArrays(1, &mesh->VAO);
|
||||
glGenBuffers(1, &mesh->VBO);
|
||||
glGenBuffers(1, &mesh->EBO);
|
||||
|
||||
glBindVertexArray(mesh->VAO);
|
||||
// load data into vertex buffers
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||
|
||||
|
||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to vevc array which
|
||||
// again translates to 3/2 floats which translates to a byte array.
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
||||
&mesh->vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
||||
&mesh->indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// set the vertex attribute pointers
|
||||
// vertex Positions
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
||||
// vertex normals
|
||||
glEnableVertexAttribArray(1);
|
||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
||||
// vertex texture coords
|
||||
glEnableVertexAttribArray(2);
|
||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
||||
// vertex tangent
|
||||
glEnableVertexAttribArray(3);
|
||||
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
||||
// vertex bitangent
|
||||
glEnableVertexAttribArray(4);
|
||||
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
||||
|
||||
// Bone ids
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex,
|
||||
m_BoneIDs
|
||||
[MAX_BONE_INFLUENCE]));
|
||||
|
||||
// Weights
|
||||
glEnableVertexAttribArray(6);
|
||||
// glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, m_Weights));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
*/
|
||||
glBindVertexArray(mesh->VAO);
|
||||
// load data into vertex buffers
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||
|
||||
|
||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to vevc array which
|
||||
// again translates to 3/2 floats which translates to a byte array.
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
||||
&mesh->vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
||||
&mesh->indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// set the vertex attribute pointers
|
||||
// vertex Positions
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
||||
// vertex normals
|
||||
glEnableVertexAttribArray(1);
|
||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
||||
// vertex texture coords
|
||||
glEnableVertexAttribArray(2);
|
||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
||||
// vertex tangent
|
||||
glEnableVertexAttribArray(3);
|
||||
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
||||
// vertex bitangent
|
||||
glEnableVertexAttribArray(4);
|
||||
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
||||
|
||||
// Bone ids
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex,
|
||||
m_BoneIDs
|
||||
[MAX_BONE_INFLUENCE]));
|
||||
|
||||
// Weights
|
||||
glEnableVertexAttribArray(6);
|
||||
// glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, m_Weights));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -2,40 +2,20 @@
|
|||
#define MESH_H
|
||||
|
||||
#include "mathc.h"
|
||||
#include "sokol/sokol_gfx.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct shader;
|
||||
struct Texture;
|
||||
|
||||
#define MAX_BONE_INFLUENCE 4
|
||||
|
||||
struct Vertex {
|
||||
mfloat_t Position[3];
|
||||
mfloat_t Normal[3];
|
||||
mfloat_t TexCoords[2];
|
||||
mfloat_t Tangent[3];
|
||||
mfloat_t Bitangent[3];
|
||||
|
||||
int m_BoneIDs[MAX_BONE_INFLUENCE];
|
||||
|
||||
float m_Weights[MAX_BONE_INFLUENCE];
|
||||
};
|
||||
|
||||
struct mesh {
|
||||
struct Vertex *vertices;
|
||||
struct Vertex *ve;
|
||||
uint32_t *indices;
|
||||
uint32_t *ie;
|
||||
struct Texture *textures;
|
||||
struct Texture *te;
|
||||
uint32_t VAO, VBO, EBO;
|
||||
sg_bindings bind;
|
||||
uint32_t face_count;
|
||||
};
|
||||
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
||||
uint32_t * indices, uint32_t * ie,
|
||||
struct Texture *textures, struct Texture *te);
|
||||
void setupmesh(struct mesh *mesh); /* Loads mesh into the GPU */
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve, uint32_t *indices, uint32_t *ie, struct Texture *textures, struct Texture *te);
|
||||
void setupmesh(struct mesh *mesh); /* Loads mesh into the GPU */
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader);
|
||||
void DrawMeshAgain(struct mesh *mesh); /* Draws whatever mesh was drawn last */
|
||||
void DrawMeshAgain(struct mesh *mesh); /* Draws whatever mesh was drawn last */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,10 +5,27 @@
|
|||
#include "resources.h"
|
||||
#include "shader.h"
|
||||
#include "stb_ds.h"
|
||||
#include "font.h"
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
// #define HANDMADE_MATH_USE_TURNS
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#include "math.h"
|
||||
#include "time.h"
|
||||
|
||||
#define CGLTF_IMPLEMENTATION
|
||||
#include <cgltf.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#include "mathc.h"
|
||||
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
struct Texture *value;
|
||||
|
@ -18,6 +35,59 @@ static void processnode();
|
|||
static void processmesh();
|
||||
static void processtexture();
|
||||
|
||||
static sg_shader model_shader;
|
||||
static sg_pipeline model_pipe;
|
||||
|
||||
void model_init() {
|
||||
YughWarn("Creating model");
|
||||
model_shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/diffuse_v.glsl"),
|
||||
.fs.source = slurp_text("shaders/diffuse_f.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = sizeof(float) * 16 * 4,
|
||||
.uniforms = {
|
||||
[0] = {.name = "vp", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[1] = {.name = "model", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[2] = {.name = "proj", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[3] = {.name = "lsm", .type = SG_UNIFORMTYPE_MAT4},
|
||||
}},
|
||||
|
||||
.fs.uniform_blocks[0] = {
|
||||
.size = sizeof(float) * 3 * 5,
|
||||
.uniforms = {
|
||||
[0] = {.name = "point_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[1] = {.name = "dir_dir", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[2] = {.name = "view_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[3] = {.name = "spot_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[4] = {.name = "spot_dir", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
},
|
||||
},
|
||||
|
||||
.fs.images[0] = {.name = "diffuse", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
.fs.images[1] = { .name = "normmap", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
.fs.images[2] = {.name = "shadow_map", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
|
||||
});
|
||||
|
||||
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = model_shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[0].buffer_index = 0, /* position */
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].buffer_index = 1, /* tex coords */
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].buffer_index = 2, /* normal */
|
||||
},
|
||||
},
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_FRONT,
|
||||
.depth.write_enabled = true,
|
||||
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||
});
|
||||
}
|
||||
|
||||
struct model *GetExistingModel(const char *path) {
|
||||
if (!path || path[0] == '\0') return NULL;
|
||||
|
||||
|
@ -27,8 +97,18 @@ struct model *GetExistingModel(const char *path) {
|
|||
return MakeModel(path);
|
||||
}
|
||||
|
||||
/* TODO: Make this a hash compare for speedup */
|
||||
cgltf_attribute *get_attr_type(cgltf_primitive p, cgltf_attribute_type t)
|
||||
{
|
||||
for (int i = 0; i < p.attributes_count; i++) {
|
||||
if (p.attributes[i].type == t)
|
||||
return &p.attributes[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct model *MakeModel(const char *path) {
|
||||
YughWarn("Making the model from %s.", path);
|
||||
cgltf_options options = {0};
|
||||
cgltf_data *data = NULL;
|
||||
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
||||
|
@ -45,188 +125,166 @@ struct model *MakeModel(const char *path) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct model *model = malloc(sizeof(struct model));
|
||||
struct model *model = calloc(1, sizeof(*model));
|
||||
/* TODO: Optimize by grouping by material. One material per draw. */
|
||||
YughWarn("Model has %d materials.", data->materials_count);
|
||||
|
||||
model->meshes = malloc(sizeof(struct mesh) * data->meshes_count);
|
||||
float vs[65535*3];
|
||||
uint16_t idxs[65535];
|
||||
|
||||
for (int i = 0; i < data->nodes_count; i++) {
|
||||
|
||||
if (data->nodes[i].mesh) {
|
||||
cgltf_mesh *mesh = data->nodes[i].mesh;
|
||||
|
||||
for (int j = 0; j < mesh->primitives_count; j++) {
|
||||
cgltf_primitive primitive = mesh->primitives[j];
|
||||
|
||||
for (int k = 0; k < primitive.attributes_count; k++) {
|
||||
cgltf_attribute attribute = primitive.attributes[k];
|
||||
|
||||
switch (attribute.type) {
|
||||
|
||||
case cgltf_attribute_type_position:
|
||||
// float *vs = malloc(sizeof(float) * cgltf_accessor_unpack_floats(attribute.accessor, NULL, attribute.accessor.count);
|
||||
// cgltf_accessor_unpack_floats(attribute.accessor, vs, attribute.accessor.count);
|
||||
for (int i = 0; i < data->meshes_count; i++) {
|
||||
cgltf_mesh *mesh = &data->meshes[i];
|
||||
struct mesh newmesh = {0};
|
||||
arrput(model->meshes,newmesh);
|
||||
|
||||
YughWarn("Making mesh %d. It has %d primitives.", i, mesh->primitives_count);
|
||||
|
||||
for (int j = 0; j < mesh->primitives_count; j++) {
|
||||
cgltf_primitive primitive = mesh->primitives[j];
|
||||
|
||||
if (primitive.indices) {
|
||||
int c = primitive.indices->count;
|
||||
memcpy(idxs, cgltf_buffer_view_data(primitive.indices->buffer_view), sizeof(uint16_t) * c);
|
||||
|
||||
model->meshes[j].bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = idxs,
|
||||
.data.size = sizeof(uint16_t) * c,
|
||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||
|
||||
model->meshes[j].face_count = c;
|
||||
} else {
|
||||
YughWarn("Model does not have indices. Generating them.");
|
||||
int c = primitive.attributes[0].data->count;
|
||||
model->meshes[j].face_count = c;
|
||||
for (int z = 0; z < c; z++)
|
||||
idxs[z] = z;
|
||||
|
||||
model->meshes[j].bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = idxs,
|
||||
.data.size = sizeof(uint16_t) * c,
|
||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||
}
|
||||
|
||||
if (primitive.material->has_pbr_metallic_roughness && primitive.material->pbr_metallic_roughness.base_color_texture.texture) {
|
||||
// YughWarn("Texture is %s.", primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri);
|
||||
|
||||
model->meshes[j].bind.fs_images[0] = texture_pullfromfile(primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri)->id;
|
||||
} else
|
||||
model->meshes[j].bind.fs_images[0] = texture_pullfromfile("k")->id;
|
||||
|
||||
cgltf_texture *tex;
|
||||
if (tex = primitive.material->normal_texture.texture) {
|
||||
model->meshes[j].bind.fs_images[1] = texture_pullfromfile(tex->image->uri)->id;
|
||||
} else
|
||||
model->meshes[j].bind.fs_images[1] = texture_pullfromfile("k")->id;
|
||||
|
||||
model->meshes[j].bind.fs_images[2] = ddimg;
|
||||
|
||||
int has_norm = 0;
|
||||
|
||||
for (int k = 0; k < primitive.attributes_count; k++) {
|
||||
cgltf_attribute attribute = primitive.attributes[k];
|
||||
|
||||
int n = cgltf_accessor_unpack_floats(attribute.data, NULL, 0); /* floats per element x num elements */
|
||||
|
||||
cgltf_accessor_unpack_floats(attribute.data, vs, n);
|
||||
|
||||
switch (attribute.type) {
|
||||
case cgltf_attribute_type_position:
|
||||
model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_normal:
|
||||
break;
|
||||
case cgltf_attribute_type_normal:
|
||||
has_norm = 1;
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_tangent:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_tangent:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_texcoord:
|
||||
break;
|
||||
}
|
||||
case cgltf_attribute_type_texcoord:
|
||||
model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_norm) {
|
||||
YughWarn("Model does not have normals. Generating them.");
|
||||
float norms[3 * model->meshes[j].face_count];
|
||||
|
||||
|
||||
cgltf_attribute *pa = get_attr_type(primitive, cgltf_attribute_type_position);
|
||||
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
||||
float ps[n];
|
||||
cgltf_accessor_unpack_floats(pa->data,ps,n);
|
||||
|
||||
for (int i = 0; i < model->meshes[j].face_count/3; i++) {
|
||||
int o = i*9;
|
||||
HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]};
|
||||
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
|
||||
for (int j = 0; j < 3; j++) {
|
||||
norms[i*9+j*3+0] = norm.X;
|
||||
norms[i*9+j*3+1] = norm.Y;
|
||||
norms[i*9+j*3+2] = norm.Z;
|
||||
}
|
||||
}
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = norms,
|
||||
.data.size = sizeof(float) * model->meshes[j].face_count * 3
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
HMM_Vec3 eye = {50,10,5};
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
||||
HMM_Mat4 proj = HMM_Perspective_RH_ZO(45, 1200.f / 720, 0.1, 10000);
|
||||
HMM_Vec3 center = {0.f, 0.f, 0.f};
|
||||
HMM_Vec3 up = {0.f, 1.f, 0.f};
|
||||
HMM_Mat4 view = HMM_LookAt_RH(eye, center, up);
|
||||
|
||||
HMM_Mat4 vp = HMM_MulM4(proj, view);
|
||||
HMM_Mat4 mvp = HMM_MulM4(vp, amodel);
|
||||
|
||||
HMM_Vec3 lp = {1, 1, 1};
|
||||
HMM_Vec3 dir_dir = HMM_NormV3(HMM_SubV3(center, dirl_pos));
|
||||
|
||||
HMM_Mat4 m2[4];
|
||||
m2[0] = view;
|
||||
m2[1] = amodel;
|
||||
m2[2] = proj;
|
||||
m2[3] = lsm;
|
||||
|
||||
HMM_Vec3 f_ubo[5];
|
||||
f_ubo[0] = lp;
|
||||
f_ubo[1] = dir_dir;
|
||||
f_ubo[2] = eye;
|
||||
f_ubo[3] = eye;
|
||||
f_ubo[4] = eye;
|
||||
|
||||
sg_apply_pipeline(model_pipe);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(m2));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(f_ubo));
|
||||
|
||||
|
||||
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||
sg_apply_bindings(&model->meshes[i].bind);
|
||||
sg_draw(0, model->meshes[i].face_count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: DELETE
|
||||
static void processnode() {
|
||||
|
||||
for (uint32_t i = 0; i < node->mNumMeshes; i++) {
|
||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
*mp = processMesh(mesh, scene);
|
||||
mp++;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < node->mNumChildren; i++) {
|
||||
processnode(node->mChildren[i], scene);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
static void processmesh() {
|
||||
/*
|
||||
Vertex *vertices =
|
||||
(Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices);
|
||||
Vertex *vp = vertices + mesh->mNumVertices;
|
||||
Vertex *p = vertices;
|
||||
for (int i = 0; i < mesh->mNumVertices; i++) {
|
||||
// positions
|
||||
(p + i)->Position.x = mesh->mVertices[i][0];
|
||||
(p + i)->Position.y = mesh->mVertices[i][1];
|
||||
(p + i)->Position.z = mesh->mVertices[i][2];
|
||||
|
||||
|
||||
// normals
|
||||
if (mesh->HasNormals()) {
|
||||
(p + i)->Normal.x = mesh->mNormals[i][0];
|
||||
(p + i)->Normal.y = mesh->mNormals[i].y;
|
||||
(p + i)->Normal.z = mesh->mNormals[i].z;
|
||||
}
|
||||
|
||||
// texture coordinates
|
||||
if (mesh->mTextureCoords[0]) {
|
||||
glm::vec2 vec;
|
||||
// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
|
||||
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
|
||||
(p + i)->TexCoords.x = mesh->mTextureCoords[0][i].x;
|
||||
(p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y;
|
||||
|
||||
// tangent
|
||||
(p + i)->Tangent.x = mesh->mTangents[i].x;
|
||||
(p + i)->Tangent.y = mesh->mTangents[i].y;
|
||||
(p + i)->Tangent.z = mesh->mTangents[i].z;
|
||||
|
||||
// bitangent
|
||||
(p + i)->Bitangent.x = mesh->mBitangents[i].x;
|
||||
(p + i)->Bitangent.y = mesh->mBitangents[i].y;
|
||||
(p + i)->Bitangent.z = mesh->mBitangents[i].z;
|
||||
|
||||
} else
|
||||
(p + i)->TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Done quickly, find better way. Go through for loop twice!
|
||||
int numindices = 0;
|
||||
// now walk through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
|
||||
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
numindices += mesh->mFaces[i].mNumIndices;
|
||||
}
|
||||
|
||||
uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices);
|
||||
uint32_t *ip = indices;
|
||||
|
||||
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) {
|
||||
*ip = mesh->mFaces[i].mIndices[j];
|
||||
ip++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// std::vector<Texture> textures;
|
||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
// TODO: Allocating 100 to be safe, can probably be way less
|
||||
textures_loaded = (Texture *) malloc(sizeof(Texture) * 100);
|
||||
tp = textures_loaded;
|
||||
// we assume a convention for sampler names in the shaders. Each diffuse texture should be named
|
||||
// as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
|
||||
// Same applies to other texture as the following list summarizes:
|
||||
// diffuse: texture_diffuseN
|
||||
// specular: texture_specularN
|
||||
// normal: texture_normalN
|
||||
|
||||
// 1. diffuse maps
|
||||
loadMaterialTextures(material, aiTextureType_DIFFUSE,
|
||||
"texture_diffuse");
|
||||
|
||||
// 2. specular maps
|
||||
loadMaterialTextures(material, aiTextureType_SPECULAR,
|
||||
"texture_specular");
|
||||
|
||||
// 3. normal maps
|
||||
loadMaterialTextures(material, aiTextureType_NORMALS,
|
||||
"texture_normal");
|
||||
|
||||
// 4. height maps
|
||||
loadMaterialTextures(material, aiTextureType_AMBIENT,
|
||||
"texture_height");
|
||||
|
||||
|
||||
// return a mesh object created from the extracted mesh data
|
||||
return Mesh(vertices, vp, indices, ip, textures_loaded, tp);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO: This routine mallocs inside the function
|
||||
static void processtexture() {
|
||||
/*
|
||||
for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
for (Texture * tpp = textures_loaded; tpp != tp; tpp++) {
|
||||
if (strcmp(tpp->path, str.data) == 0)
|
||||
goto next; // Check if we already have this texture
|
||||
}
|
||||
|
||||
tp->id = TextureFromFile(str.data, this->directory);
|
||||
tp->type = (char *) malloc(sizeof(char) * strlen(typeName));
|
||||
strcpy(tp->type, typeName);
|
||||
tp->path = (char *) malloc(sizeof(char) * strlen(str.data));
|
||||
strcpy(tp->path, str.data);
|
||||
|
||||
tp++;
|
||||
|
||||
next:;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void draw_models(struct model *model, struct shader *shader)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TODO: Come back to this; simple optimization
|
||||
void draw_model(struct model *model, struct shader *shader) {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
struct mesh;
|
||||
#include "mesh.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
extern HMM_Vec3 eye;
|
||||
struct shader;
|
||||
|
||||
struct model {
|
||||
struct mesh *meshes;
|
||||
struct mesh *mp;
|
||||
struct mesh *meshes;
|
||||
};
|
||||
|
||||
/* Get the model at a path, or create and return if it doesn't exist */
|
||||
|
@ -18,7 +20,9 @@ struct model *MakeModel(const char *path);
|
|||
/* Load a model from memory into the GPU */
|
||||
void loadmodel(struct model *model);
|
||||
|
||||
void draw_model(struct model *model, struct shader *shader);
|
||||
void model_init();
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm);
|
||||
void draw_models(struct model *model, struct shader *shader);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "skybox.h"
|
||||
|
||||
#include "shader.h"
|
||||
#include "camera.h"
|
||||
#include <string.h>
|
||||
#include "shader.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
|
@ -48,82 +48,79 @@ static const float skyboxVertices[216] = {
|
|||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f
|
||||
};
|
||||
1.0f, -1.0f, 1.0f};
|
||||
|
||||
struct mSkybox *MakeSkybox(const char *cubemap)
|
||||
{
|
||||
/*
|
||||
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
||||
struct mSkybox *MakeSkybox(const char *cubemap) {
|
||||
/*
|
||||
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
||||
|
||||
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
||||
shader_compile(newskybox->shader);
|
||||
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
||||
shader_compile(newskybox->shader);
|
||||
|
||||
glGenVertexArrays(1, &newskybox->VAO);
|
||||
glGenBuffers(1, &newskybox->VBO);
|
||||
glBindVertexArray(newskybox->VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
||||
(void *) 0);
|
||||
glGenVertexArrays(1, &newskybox->VAO);
|
||||
glGenBuffers(1, &newskybox->VBO);
|
||||
glBindVertexArray(newskybox->VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
||||
(void *) 0);
|
||||
|
||||
shader_use(newskybox->shader);
|
||||
shader_setint(newskybox->shader, "skybox", 0);
|
||||
*/
|
||||
/*
|
||||
const char *faces[6] =
|
||||
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
||||
"back.jpg"
|
||||
};
|
||||
*/
|
||||
/*
|
||||
glGenTextures(1, &newskybox->id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
||||
*/
|
||||
/*char buf[100] = { '\0' };*/
|
||||
shader_use(newskybox->shader);
|
||||
shader_setint(newskybox->shader, "skybox", 0);
|
||||
*/
|
||||
/*
|
||||
const char *faces[6] =
|
||||
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
||||
"back.jpg"
|
||||
};
|
||||
*/
|
||||
/*
|
||||
glGenTextures(1, &newskybox->id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
||||
*/
|
||||
/*char buf[100] = { '\0' };*/
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
/*
|
||||
buf[0] = '\0';
|
||||
strcat(buf, cubemap);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, faces[i]);
|
||||
IMG_Load(buf);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
||||
2048, 0, GL_RGB, GL_UNSIGNED_BYTE, data->pixels);
|
||||
buf[0] = '\0';
|
||||
strcat(buf, cubemap);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, faces[i]);
|
||||
IMG_Load(buf);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
||||
2048, 0, GL_RGB, GL_UNSIGNED_BYTE, data->pixels);
|
||||
*/
|
||||
}
|
||||
/*
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
/*
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
||||
return newskybox;
|
||||
*/
|
||||
return newskybox;
|
||||
*/
|
||||
}
|
||||
|
||||
void skybox_draw(const struct mSkybox *skybox,
|
||||
const struct mCamera *camera)
|
||||
{
|
||||
/*
|
||||
shader_use(skybox->shader);
|
||||
const struct mCamera *camera) {
|
||||
/*
|
||||
shader_use(skybox->shader);
|
||||
|
||||
mfloat_t view[16] = { 0.f };
|
||||
getviewmatrix(view, camera);
|
||||
shader_setmat4(skybox->shader, "skyview", view);
|
||||
mfloat_t view[16] = { 0.f };
|
||||
getviewmatrix(view, camera);
|
||||
shader_setmat4(skybox->shader, "skyview", view);
|
||||
|
||||
// skybox cube
|
||||
glBindVertexArray(skybox->VAO);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
*/
|
||||
// skybox cube
|
||||
glBindVertexArray(skybox->VAO);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
struct mCamera;
|
||||
|
||||
struct mSkybox {
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
unsigned int id;
|
||||
struct shader *shader;
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
unsigned int id;
|
||||
struct shader *shader;
|
||||
};
|
||||
|
||||
struct mSkybox *MakeSkybox(const char *cubemap);
|
||||
void skybox_draw(const struct mSkybox *skybox,
|
||||
const struct mCamera *camera);
|
||||
const struct mCamera *camera);
|
||||
|
||||
#endif
|
||||
|
|
3553
source/engine/HandmadeMath.h
Normal file
3553
source/engine/HandmadeMath.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,311 +0,0 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
|
@ -1,51 +1,51 @@
|
|||
#include "anim.h"
|
||||
#include "stb_ds.h"
|
||||
#include "log.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
struct anim make_anim() {
|
||||
struct anim a = {0};
|
||||
a.interp = 1;
|
||||
struct anim a = {0};
|
||||
a.interp = 1;
|
||||
|
||||
return a;
|
||||
return a;
|
||||
}
|
||||
|
||||
void free_anim(struct anim a) {
|
||||
arrfree(a.frames);
|
||||
arrfree(a.frames);
|
||||
}
|
||||
|
||||
struct anim anim_add_keyframe(struct anim a, struct keyframe key) {
|
||||
arrput(a.frames, key);
|
||||
arrput(a.frames, key);
|
||||
|
||||
return a;
|
||||
return a;
|
||||
}
|
||||
|
||||
double interval(struct keyframe a, struct keyframe b, double t) {
|
||||
return (t - a.time) / (b.time - a.time);
|
||||
return (t - a.time) / (b.time - a.time);
|
||||
}
|
||||
|
||||
double near_val(struct anim anim, double t) {
|
||||
for (int i = 0; i < arrlen(anim.frames) - 1; i++) {
|
||||
for (int i = 0; i < arrlen(anim.frames) - 1; i++) {
|
||||
|
||||
if (t > anim.frames[i+1].time)
|
||||
continue;
|
||||
if (t > anim.frames[i + 1].time)
|
||||
continue;
|
||||
|
||||
return (interval(anim.frames[i], anim.frames[i+1], t) >= 0.5f ? anim.frames[i+1].val : anim.frames[i].val);
|
||||
}
|
||||
return (interval(anim.frames[i], anim.frames[i + 1], t) >= 0.5f ? anim.frames[i + 1].val : anim.frames[i].val);
|
||||
}
|
||||
|
||||
return arrlast(anim.frames).val;
|
||||
return arrlast(anim.frames).val;
|
||||
}
|
||||
|
||||
double lerp_val(struct anim anim, double t) {
|
||||
|
||||
for (int i = 0; i < arrlen(anim.frames) - 1; i++) {
|
||||
if (t > anim.frames[i+1].time)
|
||||
continue;
|
||||
for (int i = 0; i < arrlen(anim.frames) - 1; i++) {
|
||||
if (t > anim.frames[i + 1].time)
|
||||
continue;
|
||||
|
||||
double intv = interval(anim.frames[i], anim.frames[i+1], t);
|
||||
return ((1 - intv) * anim.frames[i].val) + (intv * anim.frames[i+1].val);
|
||||
}
|
||||
double intv = interval(anim.frames[i], anim.frames[i + 1], t);
|
||||
return ((1 - intv) * anim.frames[i].val) + (intv * anim.frames[i + 1].val);
|
||||
}
|
||||
|
||||
return arrlast(anim.frames).val;
|
||||
return arrlast(anim.frames).val;
|
||||
}
|
||||
|
||||
double cubic_val(struct anim anim, double t) {
|
||||
|
@ -53,8 +53,8 @@ double cubic_val(struct anim anim, double t) {
|
|||
}
|
||||
|
||||
double anim_val(struct anim anim, double t) {
|
||||
if (anim.interp == 0)
|
||||
return near_val(anim, t);
|
||||
if (anim.interp == 0)
|
||||
return near_val(anim, t);
|
||||
|
||||
return lerp_val(anim, t);
|
||||
return lerp_val(anim, t);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,18 @@
|
|||
#define ANIM_H
|
||||
|
||||
struct keyframe {
|
||||
double time;
|
||||
double val;
|
||||
double time;
|
||||
double val;
|
||||
};
|
||||
|
||||
struct anim {
|
||||
struct keyframe *frames;
|
||||
int loop;
|
||||
int interp;
|
||||
struct keyframe *frames;
|
||||
int loop;
|
||||
int interp;
|
||||
};
|
||||
|
||||
struct anim make_anim();
|
||||
struct anim anim_add_keyframe(struct anim a, struct keyframe f);
|
||||
double anim_val(struct anim anim, double t);
|
||||
|
||||
|
||||
#endif
|
|
@ -3,70 +3,64 @@
|
|||
#include "gameobject.h"
|
||||
#include "input.h"
|
||||
|
||||
|
||||
const float CAMERA_MINSPEED = 1.f;
|
||||
const float CAMERA_MAXSPEED = 300.f;
|
||||
const float CAMERA_ROTATESPEED = 6.f;
|
||||
|
||||
void cam_goto_object(struct mCamera *cam, struct mTransform *transform)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
vec3_subtract(cam->transform.position, transform->position,
|
||||
vec3_multiply_f(fwd, trans_forward(fwd, transform),
|
||||
10.f));
|
||||
void cam_goto_object(struct mCamera *cam, struct mTransform *transform) {
|
||||
mfloat_t fwd[3] = {0.f};
|
||||
vec3_subtract(cam->transform.position, transform->position,
|
||||
vec3_multiply_f(fwd, trans_forward(fwd, transform),
|
||||
10.f));
|
||||
}
|
||||
|
||||
void cam_inverse_goto(struct mCamera *cam, struct mTransform *transform)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
vec3_add(transform->position, cam->transform.position,
|
||||
vec3_multiply_f(fwd, trans_forward(fwd, &cam->transform),
|
||||
10.f));
|
||||
void cam_inverse_goto(struct mCamera *cam, struct mTransform *transform) {
|
||||
mfloat_t fwd[3] = {0.f};
|
||||
vec3_add(transform->position, cam->transform.position,
|
||||
vec3_multiply_f(fwd, trans_forward(fwd, &cam->transform),
|
||||
10.f));
|
||||
}
|
||||
|
||||
mfloat_t *getviewmatrix(mfloat_t view[16],
|
||||
const struct mCamera *const camera)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
mfloat_t look[3] = { 0.f };
|
||||
vec3_rotate_quat(fwd, FORWARD, camera->transform.rotation);
|
||||
vec3_add(look, camera->transform.position, fwd);
|
||||
mat4_look_at(view, camera->transform.position, look, UP);
|
||||
return view;
|
||||
/*return mat4_look_at(view, ncam.transform.position,
|
||||
vec3_add(look, ncam.transform.position,
|
||||
trans_forward(fwd, &ncam.transform)),
|
||||
UP); */
|
||||
const struct mCamera *const camera) {
|
||||
mfloat_t fwd[3] = {0.f};
|
||||
mfloat_t look[3] = {0.f};
|
||||
vec3_rotate_quat(fwd, FORWARD, camera->transform.rotation);
|
||||
vec3_add(look, camera->transform.position, fwd);
|
||||
mat4_look_at(view, camera->transform.position, look, UP);
|
||||
return view;
|
||||
/*return mat4_look_at(view, ncam.transform.position,
|
||||
vec3_add(look, ncam.transform.position,
|
||||
trans_forward(fwd, &ncam.transform)),
|
||||
UP); */
|
||||
}
|
||||
|
||||
void camera_2d_update(struct mCamera *camera, float deltaT)
|
||||
{
|
||||
static mfloat_t frame[3];
|
||||
vec3_zero(frame);
|
||||
if (action_down(GLFW_KEY_W))
|
||||
vec3_add(frame, frame, UP);
|
||||
if (action_down(GLFW_KEY_S))
|
||||
vec3_add(frame, frame, DOWN);
|
||||
if (action_down(GLFW_KEY_A))
|
||||
vec3_add(frame, frame, LEFT);
|
||||
if (action_down(GLFW_KEY_D))
|
||||
vec3_add(frame, frame, RIGHT);
|
||||
void camera_2d_update(struct mCamera *camera, float deltaT) {
|
||||
static mfloat_t frame[3];
|
||||
vec3_zero(frame);
|
||||
if (action_down(GLFW_KEY_W))
|
||||
vec3_add(frame, frame, UP);
|
||||
if (action_down(GLFW_KEY_S))
|
||||
vec3_add(frame, frame, DOWN);
|
||||
if (action_down(GLFW_KEY_A))
|
||||
vec3_add(frame, frame, LEFT);
|
||||
if (action_down(GLFW_KEY_D))
|
||||
vec3_add(frame, frame, RIGHT);
|
||||
|
||||
float speedMult = action_down(GLFW_KEY_LEFT_SHIFT) ? 2.f : 1.f;
|
||||
|
||||
if (!vec3_is_zero(frame)) {
|
||||
vec3_normalize(frame, frame);
|
||||
vec3_add(camera->transform.position, camera->transform.position,
|
||||
vec3_multiply_f(frame, frame,
|
||||
camera->speed * speedMult * deltaT));
|
||||
}
|
||||
float speedMult = action_down(GLFW_KEY_LEFT_SHIFT) ? 2.f : 1.f;
|
||||
|
||||
if (!vec3_is_zero(frame)) {
|
||||
vec3_normalize(frame, frame);
|
||||
vec3_add(camera->transform.position, camera->transform.position,
|
||||
vec3_multiply_f(frame, frame,
|
||||
camera->speed * speedMult * deltaT));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void camera_update(struct mCamera * camera, float mouseX, float mouseY,
|
||||
const uint8_t * keystate, int32_t mouseWheelY,
|
||||
float deltaTime)
|
||||
const uint8_t * keystate, int32_t mouseWheelY,
|
||||
float deltaTime)
|
||||
{
|
||||
// if (SDL_GetRelativeMouseMode()) vec3_zero(camera->frame_move);
|
||||
|
||||
|
@ -74,43 +68,43 @@ void camera_update(struct mCamera * camera, float mouseX, float mouseY,
|
|||
vec3_zero(camera->frame_move);
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_W])
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_forward(holdvec, &camera->transform));
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_forward(holdvec, &camera->transform));
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_S])
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_forward(holdvec, &camera->transform));
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_forward(holdvec, &camera->transform));
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_A])
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_right(holdvec, &camera->transform));
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_right(holdvec, &camera->transform));
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_D])
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_right(holdvec, &camera->transform));
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_right(holdvec, &camera->transform));
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_E])
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_up(holdvec, &camera->transform));
|
||||
vec3_add(camera->frame_move, camera->frame_move,
|
||||
trans_up(holdvec, &camera->transform));
|
||||
|
||||
if (currentKeystates[SDL_SCANCODE_Q])
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_up(holdvec, &camera->transform));
|
||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||
trans_up(holdvec, &camera->transform));
|
||||
|
||||
camera->speedMult = currentKeystates[SDL_SCANCODE_LSHIFT] ? 2.f : 1.f;
|
||||
|
||||
|
||||
if (!vec3_is_zero(camera->frame_move)) {
|
||||
vec3_normalize(camera->frame_move, camera->frame_move);
|
||||
vec3_add(camera->transform.position, camera->transform.position,
|
||||
vec3_multiply_f(camera->frame_move, camera->frame_move,
|
||||
camera->speed * camera->speedMult *
|
||||
deltaTime));
|
||||
vec3_normalize(camera->frame_move, camera->frame_move);
|
||||
vec3_add(camera->transform.position, camera->transform.position,
|
||||
vec3_multiply_f(camera->frame_move, camera->frame_move,
|
||||
camera->speed * camera->speedMult *
|
||||
deltaTime));
|
||||
}
|
||||
// Adjust speed based on mouse wheel
|
||||
camera->speed =
|
||||
clampf(camera->speed + mouseWheelY, CAMERA_MINSPEED,
|
||||
CAMERA_MAXSPEED);
|
||||
clampf(camera->speed + mouseWheelY, CAMERA_MINSPEED,
|
||||
CAMERA_MAXSPEED);
|
||||
|
||||
|
||||
// TODO: Handle this as additive quaternions
|
||||
|
@ -120,9 +114,9 @@ void camera_update(struct mCamera * camera, float mouseX, float mouseY,
|
|||
|
||||
|
||||
if (camera->pitch > 89.f)
|
||||
camera->pitch = 89.f;
|
||||
camera->pitch = 89.f;
|
||||
if (camera->pitch < -89.f)
|
||||
camera->pitch = -89.f;
|
||||
camera->pitch = -89.f;
|
||||
|
||||
mfloat_t qyaw[4] = {0.f};
|
||||
mfloat_t qpitch[4] = {0.f};
|
||||
|
|
|
@ -8,10 +8,10 @@ extern const float CAMERA_MAXSPEED;
|
|||
extern const float CAMERA_ROTATESPEED;
|
||||
|
||||
struct mCamera {
|
||||
struct mTransform transform;
|
||||
float speed;
|
||||
float speedMult;
|
||||
mfloat_t frame_move[VEC3_SIZE];
|
||||
struct mTransform transform;
|
||||
float speed;
|
||||
float speedMult;
|
||||
mfloat_t frame_move[VEC3_SIZE];
|
||||
};
|
||||
|
||||
void camera_2d_update(struct mCamera *camera, float deltaT);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
|
||||
#define MAXPATH 256 /* 255 chars + null */
|
||||
#define MAXPATH 256 /* 255 chars + null */
|
||||
#define MAXNAME 50
|
||||
|
||||
#define SCREEN_WIDTH 1280
|
||||
|
|
|
@ -1,206 +1,189 @@
|
|||
#include "datastream.h"
|
||||
|
||||
#include "render.h"
|
||||
#include "config.h"
|
||||
#include "shader.h"
|
||||
#include "resources.h"
|
||||
#include "sound.h"
|
||||
#include <stdbool.h>
|
||||
#include "log.h"
|
||||
#include "texture.h"
|
||||
#include <stdlib.h>
|
||||
#include "mix.h"
|
||||
#include "limits.h"
|
||||
#include "iir.h"
|
||||
#include "dsp.h"
|
||||
#include "iir.h"
|
||||
#include "limits.h"
|
||||
#include "log.h"
|
||||
#include "mix.h"
|
||||
#include "render.h"
|
||||
#include "resources.h"
|
||||
#include "shader.h"
|
||||
#include "sound.h"
|
||||
#include "texture.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct shader *vid_shader;
|
||||
|
||||
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t * plane)
|
||||
{
|
||||
/*
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, plane->width, plane->height, 0, GL_RED, GL_UNSIGNED_BYTE, plane->data);
|
||||
*/
|
||||
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t *plane) {
|
||||
/*
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, plane->width, plane->height, 0, GL_RED, GL_UNSIGNED_BYTE, plane->data);
|
||||
*/
|
||||
}
|
||||
|
||||
static void render_frame(plm_t * mpeg, plm_frame_t * frame, void *user)
|
||||
{
|
||||
struct datastream *ds = user;
|
||||
shader_use(ds->shader);
|
||||
/*
|
||||
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y);
|
||||
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb);
|
||||
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr);
|
||||
*/
|
||||
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
|
||||
struct datastream *ds = user;
|
||||
shader_use(ds->shader);
|
||||
/*
|
||||
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y);
|
||||
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb);
|
||||
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr);
|
||||
*/
|
||||
}
|
||||
|
||||
static void render_audio(plm_t * mpeg, plm_samples_t * samples, void *user)
|
||||
{
|
||||
struct datastream *ds = user;
|
||||
short t;
|
||||
static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
|
||||
struct datastream *ds = user;
|
||||
short t;
|
||||
|
||||
for (int i = 0; i < samples->count * CHANNELS; i++) {
|
||||
t = (short)(samples->interleaved[i] * SHRT_MAX);
|
||||
cbuf_push(ds->astream->buf, t*5);
|
||||
}
|
||||
for (int i = 0; i < samples->count * CHANNELS; i++) {
|
||||
t = (short)(samples->interleaved[i] * SHRT_MAX);
|
||||
cbuf_push(ds->astream->buf, t * 5);
|
||||
}
|
||||
}
|
||||
|
||||
struct Texture *ds_maketexture(struct datastream *ds)
|
||||
{
|
||||
/*
|
||||
struct Texture *new = malloc(sizeof(*new));
|
||||
new->id = ds->texture_cb;
|
||||
new->width = 500;
|
||||
new->height = 500;
|
||||
return new;
|
||||
*/
|
||||
struct Texture *ds_maketexture(struct datastream *ds) {
|
||||
/*
|
||||
struct Texture *new = malloc(sizeof(*new));
|
||||
new->id = ds->texture_cb;
|
||||
new->width = 500;
|
||||
new->height = 500;
|
||||
return new;
|
||||
*/
|
||||
}
|
||||
|
||||
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
||||
{
|
||||
// ds_stop(ds);
|
||||
char buf[MAXPATH] = {'\0'};
|
||||
sprintf(buf, "%s%s", "video/", video);
|
||||
ds->plm = plm_create_with_filename(buf);
|
||||
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
|
||||
// ds_stop(ds);
|
||||
char buf[MAXPATH] = {'\0'};
|
||||
sprintf(buf, "%s%s", "video/", video);
|
||||
ds->plm = plm_create_with_filename(buf);
|
||||
|
||||
if (!ds->plm) {
|
||||
YughLog(0, 0, "Couldn't open %s", video);
|
||||
}
|
||||
if (!ds->plm) {
|
||||
YughLog(0, 0, "Couldn't open %s", video);
|
||||
}
|
||||
|
||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||
video,
|
||||
plm_get_framerate(ds->plm),
|
||||
plm_get_samplerate(ds->plm),
|
||||
plm_get_num_audio_streams(ds->plm),
|
||||
plm_get_duration(ds->plm)
|
||||
);
|
||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||
video,
|
||||
plm_get_framerate(ds->plm),
|
||||
plm_get_samplerate(ds->plm),
|
||||
plm_get_num_audio_streams(ds->plm),
|
||||
plm_get_duration(ds->plm));
|
||||
|
||||
ds->astream = soundstream_make();
|
||||
struct dsp_filter astream_filter;
|
||||
astream_filter.data = &ds->astream;
|
||||
astream_filter.filter = soundstream_fillbuf;
|
||||
ds->astream = soundstream_make();
|
||||
struct dsp_filter astream_filter;
|
||||
astream_filter.data = &ds->astream;
|
||||
astream_filter.filter = soundstream_fillbuf;
|
||||
|
||||
//struct dsp_filter lpf = lpf_make(8, 10000);
|
||||
struct dsp_filter lpf = lpf_make(1, 200);
|
||||
struct dsp_iir *iir = lpf.data;
|
||||
iir->in = astream_filter;
|
||||
// struct dsp_filter lpf = lpf_make(8, 10000);
|
||||
struct dsp_filter lpf = lpf_make(1, 200);
|
||||
struct dsp_iir *iir = lpf.data;
|
||||
iir->in = astream_filter;
|
||||
|
||||
struct dsp_filter hpf = hpf_make(1, 2000);
|
||||
struct dsp_iir *hiir = hpf.data;
|
||||
hiir->in = astream_filter;
|
||||
|
||||
struct dsp_filter hpf = hpf_make(1, 2000);
|
||||
struct dsp_iir *hiir = hpf.data;
|
||||
hiir->in = astream_filter;
|
||||
/*
|
||||
struct dsp_filter llpf = lp_fir_make(20);
|
||||
struct dsp_fir *fir = llpf.data;
|
||||
fir->in = astream_filter;
|
||||
*/
|
||||
|
||||
/*
|
||||
struct dsp_filter llpf = lp_fir_make(20);
|
||||
struct dsp_fir *fir = llpf.data;
|
||||
fir->in = astream_filter;
|
||||
*/
|
||||
// first_free_bus(astream_filter);
|
||||
|
||||
//first_free_bus(astream_filter);
|
||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
||||
plm_set_loop(ds->plm, false);
|
||||
|
||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
||||
plm_set_loop(ds->plm, false);
|
||||
plm_set_audio_enabled(ds->plm, true);
|
||||
plm_set_audio_stream(ds->plm, 0);
|
||||
|
||||
plm_set_audio_enabled(ds->plm, true);
|
||||
plm_set_audio_stream(ds->plm, 0);
|
||||
// Adjust the audio lead time according to the audio_spec buffer size
|
||||
plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE);
|
||||
|
||||
// Adjust the audio lead time according to the audio_spec buffer size
|
||||
plm_set_audio_lead_time(ds->plm, BUF_FRAMES/SAMPLERATE);
|
||||
|
||||
ds->playing = true;
|
||||
ds->playing = true;
|
||||
}
|
||||
|
||||
struct datastream *MakeDatastream()
|
||||
{
|
||||
struct datastream *newds = malloc(sizeof(*newds));
|
||||
/*
|
||||
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl");
|
||||
struct datastream *MakeDatastream() {
|
||||
struct datastream *newds = malloc(sizeof(*newds));
|
||||
/*
|
||||
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl");
|
||||
|
||||
newds->shader = vid_shader;
|
||||
shader_use(newds->shader);
|
||||
glGenTextures(1, &newds->texture_y);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_y", 0);
|
||||
newds->shader = vid_shader;
|
||||
shader_use(newds->shader);
|
||||
glGenTextures(1, &newds->texture_y);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_y", 0);
|
||||
|
||||
glGenTextures(1, &newds->texture_cb);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cb);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cb", 1);
|
||||
glGenTextures(1, &newds->texture_cb);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cb);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cb", 1);
|
||||
|
||||
glGenTextures(1, &newds->texture_cr);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cr", 2);
|
||||
*/
|
||||
return newds;
|
||||
glGenTextures(1, &newds->texture_cr);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cr", 2);
|
||||
*/
|
||||
return newds;
|
||||
}
|
||||
|
||||
void ds_advance(struct datastream *ds, double s)
|
||||
{
|
||||
if (ds->playing) {
|
||||
plm_decode(ds->plm, s);
|
||||
}
|
||||
void ds_advance(struct datastream *ds, double s) {
|
||||
if (ds->playing) {
|
||||
plm_decode(ds->plm, s);
|
||||
}
|
||||
}
|
||||
|
||||
void ds_seek(struct datastream *ds, double time)
|
||||
{
|
||||
//clear_raw(ds->audio_device);
|
||||
plm_seek(ds->plm, time, false);
|
||||
void ds_seek(struct datastream *ds, double time) {
|
||||
// clear_raw(ds->audio_device);
|
||||
plm_seek(ds->plm, time, false);
|
||||
}
|
||||
|
||||
void ds_advanceframes(struct datastream *ds, int frames)
|
||||
{
|
||||
for (int i = 0; i < frames; i++) {
|
||||
plm_frame_t *frame = plm_decode_video(ds->plm);
|
||||
render_frame(ds->plm, frame, ds);
|
||||
}
|
||||
void ds_advanceframes(struct datastream *ds, int frames) {
|
||||
for (int i = 0; i < frames; i++) {
|
||||
plm_frame_t *frame = plm_decode_video(ds->plm);
|
||||
render_frame(ds->plm, frame, ds);
|
||||
}
|
||||
}
|
||||
|
||||
void ds_pause(struct datastream *ds)
|
||||
{
|
||||
ds->playing = false;
|
||||
void ds_pause(struct datastream *ds) {
|
||||
ds->playing = false;
|
||||
}
|
||||
|
||||
void ds_stop(struct datastream *ds)
|
||||
{
|
||||
if (ds->plm != NULL) {
|
||||
plm_destroy(ds->plm);
|
||||
ds->plm = NULL;
|
||||
}
|
||||
if (ds->audio_device)
|
||||
close_audio_device(ds->audio_device);
|
||||
ds->playing = false;
|
||||
void ds_stop(struct datastream *ds) {
|
||||
if (ds->plm != NULL) {
|
||||
plm_destroy(ds->plm);
|
||||
ds->plm = NULL;
|
||||
}
|
||||
if (ds->audio_device)
|
||||
close_audio_device(ds->audio_device);
|
||||
ds->playing = false;
|
||||
}
|
||||
|
||||
// TODO: Must be a better way
|
||||
int ds_videodone(struct datastream *ds)
|
||||
{
|
||||
return (ds->plm == NULL)
|
||||
|| plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
|
||||
int ds_videodone(struct datastream *ds) {
|
||||
return (ds->plm == NULL) || plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
|
||||
}
|
||||
|
||||
double ds_remainingtime(struct datastream *ds)
|
||||
{
|
||||
if (ds->plm != NULL)
|
||||
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
|
||||
else
|
||||
return 0.f;
|
||||
double ds_remainingtime(struct datastream *ds) {
|
||||
if (ds->plm != NULL)
|
||||
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
|
||||
else
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
double ds_length(struct datastream *ds)
|
||||
{
|
||||
return plm_get_duration(ds->plm);
|
||||
double ds_length(struct datastream *ds) {
|
||||
return plm_get_duration(ds->plm);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#ifndef DATASTREAM_H
|
||||
#define DATASTREAM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pl_mpeg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct soundstream;
|
||||
|
||||
struct datastream {
|
||||
plm_t *plm;
|
||||
struct shader *shader;
|
||||
double last_time;
|
||||
int playing;
|
||||
int audio_device;
|
||||
uint32_t texture_y;
|
||||
uint32_t texture_cb;
|
||||
uint32_t texture_cr;
|
||||
struct soundstream *astream;
|
||||
plm_t *plm;
|
||||
struct shader *shader;
|
||||
double last_time;
|
||||
int playing;
|
||||
int audio_device;
|
||||
uint32_t texture_y;
|
||||
uint32_t texture_cb;
|
||||
uint32_t texture_cr;
|
||||
struct soundstream *astream;
|
||||
};
|
||||
|
||||
struct Texture;
|
||||
|
@ -24,7 +24,7 @@ extern struct shader *vid_shader;
|
|||
|
||||
struct datastream *MakeDatastream();
|
||||
void ds_openvideo(struct datastream *ds, const char *path, const char *adriver);
|
||||
struct Texture *ds_maketexture(struct datastream*);
|
||||
struct Texture *ds_maketexture(struct datastream *);
|
||||
void ds_advance(struct datastream *ds, double);
|
||||
void ds_seek(struct datastream *ds, double);
|
||||
void ds_advanceframes(struct datastream *ds, int frames);
|
||||
|
|
|
@ -11,75 +11,163 @@
|
|||
#include "stb_ds.h"
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
static uint32_t circleVBO;
|
||||
static uint32_t circleVAO;
|
||||
static struct shader *circleShader;
|
||||
#include "font.h"
|
||||
|
||||
static uint32_t gridVBO;
|
||||
static uint32_t gridVAO;
|
||||
static struct shader *gridShader;
|
||||
static sg_pipeline grid_pipe;
|
||||
static sg_bindings grid_bind;
|
||||
static sg_shader grid_shader;
|
||||
static int grid_c = 0;
|
||||
|
||||
static uint32_t rectVBO;
|
||||
static uint32_t rectVAO;
|
||||
static struct shader *rectShader;
|
||||
static sg_pipeline rect_pipe;
|
||||
static sg_bindings rect_bind;
|
||||
static sg_shader rect_shader;
|
||||
static int rect_c = 0;
|
||||
|
||||
typedef struct {
|
||||
float proj[16];
|
||||
float res[2];
|
||||
} circle_ubo;
|
||||
static sg_pipeline circle_pipe;
|
||||
static sg_bindings circle_bind;
|
||||
static sg_shader csg;
|
||||
static int circle_count = 0;
|
||||
static int circle_vert_c = 7;
|
||||
|
||||
void debug_flush()
|
||||
{
|
||||
|
||||
sg_apply_pipeline(circle_pipe);
|
||||
sg_apply_bindings(&circle_bind);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
|
||||
|
||||
sg_draw(0,4,circle_count);
|
||||
circle_count = 0;
|
||||
|
||||
sg_apply_pipeline(rect_pipe);
|
||||
sg_apply_bindings(&rect_bind);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
|
||||
sg_draw(0,rect_c*2,1);
|
||||
rect_c = 0;
|
||||
}
|
||||
|
||||
static sg_shader_uniform_block_desc projection_ubo = {
|
||||
.size = sizeof(projection),
|
||||
.uniforms = {
|
||||
[0] = { .name = "proj", .type = SG_UNIFORMTYPE_MAT4 },
|
||||
}
|
||||
};
|
||||
|
||||
void debugdraw_init()
|
||||
{
|
||||
sg_shader csg = sg_make_shader(&(sg_shader_desc){
|
||||
csg = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/circlevert.glsl"),
|
||||
.fs.source = slurp_text("shaders/circlefrag.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = sizeof(circle_ubo),
|
||||
.uniforms = {
|
||||
[0] = { .name = "proj", .type = SG_UNIFORMTYPE_MAT4 },
|
||||
[1] = { .name = "res", .type = SG_UNIFORMTYPE_FLOAT2 },
|
||||
}
|
||||
}
|
||||
.vs.uniform_blocks[0] = projection_ubo,
|
||||
});
|
||||
/*
|
||||
float gridverts[] = {
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
-1.f, 1.f,
|
||||
1.f, 1.f
|
||||
};
|
||||
|
||||
gridShader = MakeShader("gridvert.glsl", "gridfrag.glsl");
|
||||
shader_setUBO(gridShader, "Projection", 0);
|
||||
glGenBuffers(1, &gridVBO);
|
||||
glGenVertexArrays(1, &gridVAO);
|
||||
glBindVertexArray(gridVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gridVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gridverts), &gridverts, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
circle_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = csg,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[0].buffer_index = 1,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[3].format = SG_VERTEXFORMAT_FLOAT
|
||||
},
|
||||
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE,
|
||||
},
|
||||
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||
.cull_mode = SG_CULLMODE_BACK,
|
||||
.colors[0].blend = {
|
||||
.enabled = true,
|
||||
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
|
||||
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
|
||||
.src_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
|
||||
},
|
||||
.label = "circle pipeline"
|
||||
});
|
||||
|
||||
rectShader = MakeShader("linevert.glsl", "linefrag.glsl");
|
||||
shader_setUBO(rectShader, "Projection", 0);
|
||||
glGenBuffers(1, &rectVBO);
|
||||
glGenVertexArrays(1, &rectVAO);
|
||||
*/
|
||||
circle_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float)*circle_vert_c*5000,
|
||||
.usage = SG_USAGE_STREAM,
|
||||
});
|
||||
|
||||
float circleverts[8] = {
|
||||
-1,-1,
|
||||
-1,1,
|
||||
1,-1,
|
||||
1,1
|
||||
};
|
||||
|
||||
circle_bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data = SG_RANGE(circleverts),
|
||||
.usage = SG_USAGE_IMMUTABLE,
|
||||
});
|
||||
|
||||
|
||||
grid_shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/gridvert.glsl"),
|
||||
.fs.source = slurp_text("shaders/gridfrag.glsl"),
|
||||
.vs.uniform_blocks[0] = projection_ubo,
|
||||
.vs.uniform_blocks[1] = {
|
||||
.size = sizeof(float)*2,
|
||||
.uniforms = { [0] = { .name = "offset", .type = SG_UNIFORMTYPE_FLOAT2 } } },
|
||||
.fs.uniform_blocks[0] = {
|
||||
.size = sizeof(float)*5,
|
||||
.uniforms = {
|
||||
[0] = { .name = "thickness", .type = SG_UNIFORMTYPE_FLOAT },
|
||||
[1] = { .name = "span", .type = SG_UNIFORMTYPE_FLOAT },
|
||||
[2] = { .name = "color", .type = SG_UNIFORMTYPE_FLOAT3 },
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
grid_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = grid_shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2
|
||||
}
|
||||
},
|
||||
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||
// .cull_mode = SG_CULLMODE_BACK,
|
||||
.label = "grid pipeline",
|
||||
.colors[0] = {
|
||||
.blend = {
|
||||
.enabled = true,
|
||||
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
|
||||
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.op_rgb = SG_BLENDOP_ADD,
|
||||
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
|
||||
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.op_alpha = SG_BLENDOP_ADD
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
grid_bind.vertex_buffers[0] = circle_bind.vertex_buffers[1];
|
||||
|
||||
rect_shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/linevert.glsl"),
|
||||
.fs.source = slurp_text("shaders/linefrag.glsl"),
|
||||
.vs.uniform_blocks[0] = projection_ubo
|
||||
});
|
||||
|
||||
rect_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = rect_shader,
|
||||
.layout = {
|
||||
.attrs = { [0].format = SG_VERTEXFORMAT_FLOAT2 }
|
||||
},
|
||||
.primitive_type = SG_PRIMITIVETYPE_LINES
|
||||
});
|
||||
|
||||
rect_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float)*2*10000,
|
||||
.usage = SG_USAGE_STREAM
|
||||
});
|
||||
}
|
||||
|
||||
void draw_line(int x1, int y1, int x2, int y2, float *color)
|
||||
void draw_line(cpVect s, cpVect e, float *color)
|
||||
{
|
||||
shader_use(rectShader);
|
||||
float verts[] = {
|
||||
x1, y1,
|
||||
x2, y2
|
||||
};
|
||||
|
||||
draw_poly(verts, 2, color);
|
||||
cpVect verts[2] = {s, e};
|
||||
draw_poly(verts, 2, color);
|
||||
}
|
||||
|
||||
cpVect center_of_vects(cpVect *v, int n)
|
||||
|
@ -153,8 +241,8 @@ void draw_edge(cpVect *points, int n, struct color color, int thickness)
|
|||
|
||||
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
|
||||
|
||||
shader_use(rectShader);
|
||||
shader_setvec3(rectShader, "linecolor", col);
|
||||
// shader_use(rectShader);
|
||||
// shader_setvec3(rectShader, "linecolor", col);
|
||||
/*
|
||||
if (thickness <= 1) {
|
||||
// glLineStipple(1, 0x00FF);
|
||||
|
@ -204,29 +292,16 @@ void draw_edge(cpVect *points, int n, struct color color, int thickness)
|
|||
|
||||
void draw_circle(int x, int y, float radius, int pixels, float *color, int fill)
|
||||
{
|
||||
/* shader_use(circleShader);
|
||||
|
||||
float verts[] = {
|
||||
x - radius, y - radius, -1, -1,
|
||||
x + radius, y - radius, 1, -1,
|
||||
x - radius, y + radius, -1, 1,
|
||||
x + radius, y + radius, 1, 1
|
||||
};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, circleVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_DYNAMIC_DRAW);
|
||||
|
||||
shader_setfloat(circleShader, "radius", radius);
|
||||
shader_setint(circleShader, "thickness", pixels);
|
||||
shader_setvec3(circleShader, "dbgColor", color);
|
||||
shader_setbool(circleShader, "fill", fill);
|
||||
shader_setfloat(circleShader, "zoom", cam_zoom());
|
||||
|
||||
glBindVertexArray(circleVAO);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
*/
|
||||
float cv[circle_vert_c] = {0};
|
||||
cv[0] = color[0];
|
||||
cv[1] = color[1];
|
||||
cv[2] = color[2];
|
||||
cv[3] = x;
|
||||
cv[4] = y;
|
||||
cv[5] = radius;
|
||||
cv[6] = fill;
|
||||
sg_append_buffer(circle_bind.vertex_buffers[0], SG_RANGE_REF(cv));
|
||||
circle_count++;
|
||||
}
|
||||
|
||||
void draw_rect(int x, int y, int w, int h, float *color)
|
||||
|
@ -234,13 +309,13 @@ void draw_rect(int x, int y, int w, int h, float *color)
|
|||
float hw = w / 2.f;
|
||||
float hh = h / 2.f;
|
||||
|
||||
float verts[] = {
|
||||
x - hw, y - hh,
|
||||
x + hw, y - hh,
|
||||
x + hw, y + hh,
|
||||
x - hw, y + hh
|
||||
cpVect verts[4] = {
|
||||
{ .x = x-hw, .y = y-hh },
|
||||
{ .x = x+hw, .y = y-hh },
|
||||
{ .x = x+hw, .y = y+hh },
|
||||
{ .x = x-hw, .y = y+hh }
|
||||
};
|
||||
|
||||
|
||||
draw_poly(verts, 4, color);
|
||||
}
|
||||
|
||||
|
@ -253,27 +328,33 @@ void draw_box(struct cpVect c, struct cpVect wh, struct color color)
|
|||
void draw_arrow(struct cpVect start, struct cpVect end, struct color color, int capsize)
|
||||
{
|
||||
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
|
||||
draw_line(start.x, start.y, end.x, end.y, col);
|
||||
draw_line(start, end, col);
|
||||
|
||||
draw_cppoint(end, capsize, color);
|
||||
}
|
||||
|
||||
void draw_grid(int width, int span)
|
||||
{
|
||||
/* shader_use(gridShader);
|
||||
shader_setint(gridShader, "thickness", width);
|
||||
shader_setint(gridShader, "span", span);
|
||||
|
||||
cpVect offset = cam_pos();
|
||||
offset = cpvmult(offset, 1/cam_zoom());
|
||||
offset = cpvmult(offset, 1/cam_zoom());
|
||||
offset.x -= mainwin->width/2;
|
||||
offset.y -= mainwin->height/2;
|
||||
|
||||
shader_setvec2(gridShader, "offset", &offset);
|
||||
|
||||
glBindVertexArray(gridVAO);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
*/
|
||||
sg_apply_pipeline(grid_pipe);
|
||||
sg_apply_bindings(&grid_bind);
|
||||
|
||||
float col[3] = { 0.3, 0.5, 0.8};
|
||||
|
||||
float fubo[5];
|
||||
fubo[0] = width;
|
||||
fubo[1] = span;
|
||||
fubo[2] = col;
|
||||
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 1, SG_RANGE_REF(offset));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(fubo));
|
||||
|
||||
sg_draw(0,4,1);
|
||||
}
|
||||
|
||||
void draw_point(int x, int y, float r, float *color)
|
||||
|
@ -293,8 +374,33 @@ void draw_points(struct cpVect *points, int n, float size, float *color)
|
|||
draw_point(points[i].x, points[i].y, size, color);
|
||||
}
|
||||
|
||||
void draw_poly(float *points, int n, float *color)
|
||||
void draw_poly(cpVect *points, int n, float *color)
|
||||
{
|
||||
if (n == 2) {
|
||||
sg_range t;
|
||||
t.ptr = points;
|
||||
t.size = sizeof(cpVect)*2;
|
||||
sg_append_buffer(rect_bind.vertex_buffers[0], &t);
|
||||
rect_c += 1;
|
||||
return;
|
||||
} else if (n <= 1) return;
|
||||
|
||||
|
||||
cpVect buffer[2*n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
buffer[i*2] = points[i];
|
||||
buffer[i*2+1] = points[i+1];
|
||||
}
|
||||
|
||||
buffer[2*n-1] = points[0];
|
||||
|
||||
sg_range t;
|
||||
t.ptr = buffer;
|
||||
t.size = sizeof(cpVect)*2*n;
|
||||
|
||||
sg_append_buffer(rect_bind.vertex_buffers[0], &t);
|
||||
|
||||
rect_c += n;
|
||||
/* shader_use(rectShader);
|
||||
shader_setvec3(rectShader, "linecolor", color);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, rectVBO);
|
||||
|
@ -312,17 +418,6 @@ void draw_poly(float *points, int n, float *color)
|
|||
*/
|
||||
}
|
||||
|
||||
void draw_polyvec(cpVect *points, int n, float *color)
|
||||
{
|
||||
float drawvec[n*2];
|
||||
for (int i = 0; i < n; i++) {
|
||||
drawvec[i*2] = points[i].x;
|
||||
drawvec[i*2+1] = points[i].y;
|
||||
}
|
||||
|
||||
draw_poly(drawvec, n, color);
|
||||
}
|
||||
|
||||
void debugdraw_flush()
|
||||
{
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
struct color;
|
||||
|
||||
void debugdraw_init();
|
||||
void draw_line(int x1, int y1, int x2, int y2, float *color);
|
||||
void draw_line(cpVect s, cpVect e, float *color);
|
||||
void draw_edge(struct cpVect *points, int n, struct color color, int thickness);
|
||||
void draw_points(struct cpVect *points, int n, float size, float *color);
|
||||
void draw_arrow(struct cpVect start, struct cpVect end, struct color, int capsize);
|
||||
|
@ -15,7 +15,7 @@ void draw_rect(int x, int y, int w, int h, float *color);
|
|||
void draw_box(struct cpVect c, struct cpVect wh, struct color color);
|
||||
void draw_point(int x, int y, float r, float *color);
|
||||
void draw_cppoint(struct cpVect point, float r, struct color color);
|
||||
void draw_poly(float *points, int n, float *color);
|
||||
void draw_poly(cpVect *points, int n, float *color);
|
||||
|
||||
void debug_flush();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <stdbool.h>
|
||||
#include "resources.h"
|
||||
|
||||
#include "nuklear.h"
|
||||
#include "nuke.h"
|
||||
|
||||
#define ASSET_TYPE_NULL 0
|
||||
#define ASSET_TYPE_IMAGE 1
|
||||
|
|
|
@ -16,54 +16,51 @@
|
|||
#define PL_MPEG_IMPLEMENTATION
|
||||
#include <pl_mpeg.h>
|
||||
|
||||
|
||||
#ifdef EDITOR
|
||||
#include "editor.h"
|
||||
#endif
|
||||
|
||||
#include "render.h"
|
||||
|
||||
#include "openglrender.h"
|
||||
#include "window.h"
|
||||
#include "camera.h"
|
||||
#include "input.h"
|
||||
#include "sprite.h"
|
||||
#include "2dphysics.h"
|
||||
#include "camera.h"
|
||||
#include "gameobject.h"
|
||||
#include "input.h"
|
||||
#include "log.h"
|
||||
#include "openglrender.h"
|
||||
#include "resources.h"
|
||||
#include "timer.h"
|
||||
#include "script.h"
|
||||
#include "sprite.h"
|
||||
#include "timer.h"
|
||||
#include "window.h"
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
void error_callback(int error, const char *description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
YughError("GLFW Error: %s", description);
|
||||
void error_callback(int error, const char *description) {
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
YughError("GLFW Error: %s", description);
|
||||
}
|
||||
|
||||
void engine_init()
|
||||
{
|
||||
glfwSetErrorCallback(error_callback);
|
||||
/* Initialize GLFW */
|
||||
if (!glfwInit()) {
|
||||
YughError("Could not init GLFW. Exiting.");
|
||||
exit(1);
|
||||
} else {
|
||||
YughInfo("Initted GLFW.");
|
||||
}
|
||||
void engine_init() {
|
||||
glfwSetErrorCallback(error_callback);
|
||||
/* Initialize GLFW */
|
||||
if (!glfwInit()) {
|
||||
YughError("Could not init GLFW. Exiting.");
|
||||
exit(1);
|
||||
} else {
|
||||
YughInfo("Initted GLFW.");
|
||||
}
|
||||
|
||||
resources_init();
|
||||
|
||||
YughInfo("Starting physics ...");
|
||||
phys2d_init();
|
||||
|
||||
YughInfo("Starting sound ...");
|
||||
sound_init();
|
||||
resources_init();
|
||||
|
||||
YughInfo("Starting scripts ...");
|
||||
script_init();
|
||||
YughInfo("Starting physics ...");
|
||||
phys2d_init();
|
||||
|
||||
YughInfo("Starting sound ...");
|
||||
sound_init();
|
||||
|
||||
YughInfo("Starting scripts ...");
|
||||
script_init();
|
||||
}
|
||||
|
|
1985
source/engine/ffi.c
1985
source/engine/ffi.c
File diff suppressed because it is too large
Load diff
|
@ -1,169 +1,153 @@
|
|||
#include "font.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "render.h"
|
||||
#include <shader.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <shader.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <window.h>
|
||||
#include "log.h"
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
#include "stb_truetype.h"
|
||||
#include "stb_rect_pack.h"
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_rect_pack.h"
|
||||
#include "stb_truetype.h"
|
||||
|
||||
struct sFont *font;
|
||||
static struct shader *shader;
|
||||
static sg_shader fontshader;
|
||||
|
||||
|
||||
unsigned char *slurp_file(const char *filename) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
if (!f) return NULL;
|
||||
if (!f) return NULL;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *slurp = malloc(fsize+1);
|
||||
fread(slurp,fsize,1,f);
|
||||
fclose(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *slurp = malloc(fsize + 1);
|
||||
fread(slurp, fsize, 1, f);
|
||||
fclose(f);
|
||||
|
||||
return slurp;
|
||||
return slurp;
|
||||
}
|
||||
|
||||
char *slurp_text(const char *filename) {
|
||||
FILE *f = fopen(filename, "r'");
|
||||
if (!f) return NULL;
|
||||
FILE *f = fopen(filename, "r'");
|
||||
if (!f) return NULL;
|
||||
|
||||
char *buf;
|
||||
long int fsize;
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
buf = malloc(fsize+1);
|
||||
rewind(f);
|
||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||
buf[r] = '\0';
|
||||
char *buf;
|
||||
long int fsize;
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
buf = malloc(fsize + 1);
|
||||
rewind(f);
|
||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||
buf[r] = '\0';
|
||||
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int slurp_write(const char *txt, const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "w");
|
||||
if (!f) return 1;
|
||||
int slurp_write(const char *txt, const char *filename) {
|
||||
FILE *f = fopen(filename, "w");
|
||||
if (!f) return 1;
|
||||
|
||||
fputs(txt, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
fputs(txt, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static sg_shader fontshader;
|
||||
static sg_bindings bind_text;
|
||||
static sg_pipeline pipe_text;
|
||||
|
||||
void font_init(struct shader *textshader) {
|
||||
shader = textshader;
|
||||
static float text_buffer[16 * 40000];
|
||||
static uint16_t text_idx_buffer[6 * 40000];
|
||||
static float color_buffer[3 * 40000];
|
||||
|
||||
fontshader = sg_make_shader(&(sg_shader_desc){
|
||||
void font_init(struct shader *textshader) {
|
||||
fontshader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/textvert.glsl"),
|
||||
.fs.source = slurp_text("shaders/textfrag.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = sizeof(float)*16,
|
||||
// .layout = SG_UNIFORMLAYOUT_STD140,
|
||||
.uniforms = {
|
||||
[0] = { .name = "projection", .type = SG_UNIFORMTYPE_MAT4 }
|
||||
}
|
||||
},
|
||||
.size = sizeof(float) * 16,
|
||||
// .layout = SG_UNIFORMLAYOUT_STD140,
|
||||
.uniforms = {
|
||||
[0] = {.name = "projection", .type = SG_UNIFORMTYPE_MAT4}}},
|
||||
|
||||
.fs.images[0] = {
|
||||
.name = "text",
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.sampler_type = SG_SAMPLERTYPE_FLOAT
|
||||
}
|
||||
});
|
||||
.fs.images[0] = {.name = "text", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT}});
|
||||
|
||||
pipe_text = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
pipe_text = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = fontshader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[0].buffer_index = 0,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].buffer_index = 0,
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].buffer_index = 1},
|
||||
.buffers[2].step_func = SG_VERTEXSTEP_PER_INSTANCE,
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[0].buffer_index = 0,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].buffer_index = 0,
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].buffer_index = 1,
|
||||
},
|
||||
},
|
||||
// .primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||
.label = "text pipeline",
|
||||
.index_type = SG_INDEXTYPE_UINT16
|
||||
});
|
||||
.index_type = SG_INDEXTYPE_UINT16});
|
||||
|
||||
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float)*16*500,
|
||||
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float) * 16 * 40000,
|
||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||
.usage = SG_USAGE_STREAM,
|
||||
.label = "text buffer"
|
||||
});
|
||||
|
||||
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float)*3*40000,
|
||||
.label = "text buffer"});
|
||||
|
||||
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float) * 3 * 4 * 40000,
|
||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||
.usage = SG_USAGE_STREAM,
|
||||
.label = "text color buffer"
|
||||
});
|
||||
|
||||
bind_text.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(uint16_t)*6*500,
|
||||
.label = "text color buffer"});
|
||||
|
||||
bind_text.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(uint16_t) * 6 * 40000,
|
||||
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
||||
.usage = SG_USAGE_STREAM,
|
||||
.label = "text index buffer"
|
||||
});
|
||||
|
||||
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
|
||||
bind_text.fs_images[0] = font->texID;
|
||||
.label = "text index buffer"});
|
||||
|
||||
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
|
||||
bind_text.fs_images[0] = font->texID;
|
||||
}
|
||||
|
||||
void font_frame(struct window *w) {
|
||||
shader_use(shader);
|
||||
}
|
||||
struct sFont *MakeFont(const char *fontfile, int height) {
|
||||
YughInfo("Making font %s.", fontfile);
|
||||
|
||||
struct sFont *MakeFont(const char *fontfile, int height)
|
||||
{
|
||||
YughInfo("Making font %s.", fontfile);
|
||||
int packsize = 1024;
|
||||
|
||||
int packsize = 128;
|
||||
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
||||
newfont->height = height;
|
||||
|
||||
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
||||
newfont->height = height;
|
||||
char fontpath[256];
|
||||
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
||||
|
||||
char fontpath[256];
|
||||
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
||||
unsigned char *ttf_buffer = slurp_file(fontpath);
|
||||
unsigned char *bitmap = malloc(packsize * packsize);
|
||||
|
||||
unsigned char *ttf_buffer = slurp_file(fontpath);
|
||||
unsigned char *bitmap = malloc(packsize*packsize);
|
||||
stbtt_packedchar glyphs[95];
|
||||
|
||||
stbtt_packedchar glyphs[95];
|
||||
stbtt_pack_context pc;
|
||||
|
||||
stbtt_pack_context pc;
|
||||
stbtt_PackBegin(&pc, bitmap, packsize, packsize, 0, 1, NULL);
|
||||
stbtt_PackFontRange(&pc, ttf_buffer, 0, height, 32, 95, glyphs);
|
||||
stbtt_PackEnd(&pc);
|
||||
|
||||
stbtt_PackBegin(&pc, bitmap, packsize, packsize, 0, 1, NULL);
|
||||
stbtt_PackFontRange(&pc, ttf_buffer, 0, height, 32, 95, glyphs);
|
||||
stbtt_PackEnd(&pc);
|
||||
stbi_write_png("packedfont.png", packsize, packsize, 1, bitmap, sizeof(char) * packsize);
|
||||
|
||||
stbi_write_png("packedfont.png", packsize, packsize, 1, bitmap, sizeof(char) * packsize);
|
||||
stbtt_fontinfo fontinfo;
|
||||
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
|
||||
YughError("Failed to make font %s", fontfile);
|
||||
}
|
||||
|
||||
stbtt_fontinfo fontinfo;
|
||||
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0))) {
|
||||
YughError("Failed to make font %s", fontfile);
|
||||
}
|
||||
|
||||
newfont->texID = sg_make_image(&(sg_image_desc){
|
||||
newfont->texID = sg_make_image(&(sg_image_desc){
|
||||
.type = SG_IMAGETYPE_2D,
|
||||
.width = packsize,
|
||||
.height = packsize,
|
||||
|
@ -172,215 +156,201 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
|||
.min_filter = SG_FILTER_NEAREST,
|
||||
.mag_filter = SG_FILTER_NEAREST,
|
||||
.data.subimage[0][0] = {
|
||||
.ptr = bitmap,
|
||||
.size = packsize*packsize
|
||||
}
|
||||
});
|
||||
.ptr = bitmap,
|
||||
.size = packsize * packsize}});
|
||||
|
||||
free(ttf_buffer);
|
||||
free(bitmap);
|
||||
free(ttf_buffer);
|
||||
free(bitmap);
|
||||
|
||||
for (unsigned char c = 32; c < 127; c++) {
|
||||
stbtt_packedchar glyph = glyphs[c-32];
|
||||
for (unsigned char c = 32; c < 127; c++) {
|
||||
stbtt_packedchar glyph = glyphs[c - 32];
|
||||
|
||||
struct glrect r;
|
||||
r.s0 = glyph.x0 / (float) packsize;
|
||||
r.s1 = glyph.x1 / (float) packsize;
|
||||
r.t0 = glyph.y0 / (float) packsize;
|
||||
r.t1 = glyph.y1 / (float) packsize;
|
||||
struct glrect r;
|
||||
r.s0 = glyph.x0 / (float)packsize;
|
||||
r.s1 = glyph.x1 / (float)packsize;
|
||||
r.t0 = glyph.y0 / (float)packsize;
|
||||
r.t1 = glyph.y1 / (float)packsize;
|
||||
|
||||
newfont->Characters[c].Advance = glyph.xadvance;
|
||||
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
||||
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
||||
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||
newfont->Characters[c].rect = r;
|
||||
}
|
||||
newfont->Characters[c].Advance = glyph.xadvance;
|
||||
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
||||
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
||||
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||
newfont->Characters[c].rect = r;
|
||||
}
|
||||
|
||||
return newfont;
|
||||
return newfont;
|
||||
}
|
||||
|
||||
static int curchar = 0;
|
||||
|
||||
void draw_char_box(struct Character c, float cursor[2], float scale, float color[3])
|
||||
{
|
||||
void draw_char_box(struct Character c, float cursor[2], float scale, float color[3]) {
|
||||
int x, y, w, h;
|
||||
|
||||
x = cursor[0];
|
||||
y = cursor[1];
|
||||
w = 8*scale;
|
||||
w = 8 * scale;
|
||||
h = 14;
|
||||
x += w/2.f;
|
||||
y += h/2.f;
|
||||
x += w / 2.f;
|
||||
y += h / 2.f;
|
||||
|
||||
draw_rect(x,y,w,h,color);
|
||||
draw_rect(x, y, w, h, color);
|
||||
}
|
||||
|
||||
void text_flush()
|
||||
{
|
||||
sg_apply_pipeline(pipe_text);
|
||||
sg_apply_bindings(&bind_text);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
|
||||
void text_flush() {
|
||||
if (curchar == 0) return;
|
||||
sg_apply_pipeline(pipe_text);
|
||||
sg_apply_bindings(&bind_text);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
|
||||
|
||||
sg_range verts;
|
||||
verts.ptr = text_buffer;
|
||||
verts.size = sizeof(float) * 16 * curchar;
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], &verts);
|
||||
|
||||
sg_draw(0,6*curchar,1);
|
||||
sg_range idxs;
|
||||
idxs.ptr = text_idx_buffer;
|
||||
idxs.size = sizeof(uint16_t) * 6 * curchar;
|
||||
sg_update_buffer(bind_text.index_buffer, &idxs);
|
||||
|
||||
sg_range c = {
|
||||
.ptr = color_buffer,
|
||||
.size = sizeof(float) * 3 * 4 * curchar};
|
||||
|
||||
sg_update_buffer(bind_text.vertex_buffers[1], &c);
|
||||
|
||||
sg_draw(0, 6 * curchar, 1);
|
||||
curchar = 0;
|
||||
}
|
||||
|
||||
void fill_charverts(float *verts, float cursor[2], float scale, struct Character c, float *offset)
|
||||
{
|
||||
void fill_charverts(float *verts, float cursor[2], float scale, struct Character c, float *offset) {
|
||||
float w = c.Size[0] * scale;
|
||||
float h = c.Size[1] * scale;
|
||||
|
||||
float xpos = cursor[0] + (c.Bearing[0]+offset[0]) * scale;
|
||||
float ypos = cursor[1] - (c.Bearing[1]+offset[1]) * scale;
|
||||
|
||||
float xpos = cursor[0] + (c.Bearing[0] + offset[0]) * scale;
|
||||
float ypos = cursor[1] - (c.Bearing[1] + offset[1]) * scale;
|
||||
|
||||
float v[16] = {
|
||||
xpos, ypos, c.rect.s0, c.rect.t1,
|
||||
xpos+w, ypos, c.rect.s1, c.rect.t1,
|
||||
xpos, ypos + h, c.rect.s0, c.rect.t0,
|
||||
xpos + w, ypos + h, c.rect.s1, c.rect.t0
|
||||
};
|
||||
|
||||
memcpy(verts, v, sizeof(float)*16);
|
||||
xpos, ypos, c.rect.s0, c.rect.t1,
|
||||
xpos + w, ypos, c.rect.s1, c.rect.t1,
|
||||
xpos, ypos + h, c.rect.s0, c.rect.t0,
|
||||
xpos + w, ypos + h, c.rect.s1, c.rect.t0};
|
||||
|
||||
memcpy(verts, v, sizeof(float) * 16);
|
||||
}
|
||||
|
||||
static int drawcaret = 0;
|
||||
|
||||
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct shader *shader, float color[3])
|
||||
{
|
||||
float shadowcolor[3] = {0.f, 0.f, 0.f};
|
||||
float shadowcursor[2];
|
||||
|
||||
float verts[16];
|
||||
float offset[2] = {-1, 1};
|
||||
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
|
||||
/* Check if the vertex is off screen */
|
||||
if (verts[5] < 0 || verts[10] < 0 || verts[0] > window_i(0)->width || verts[1] > window_i(0)->height)
|
||||
return;
|
||||
|
||||
curchar++;
|
||||
/* SET COLOR ? */
|
||||
uint16_t pts[6] = {
|
||||
0, 1, 2,
|
||||
2, 1, 3
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; i++) pts[i] += curchar*4;
|
||||
|
||||
sg_append_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
sg_append_buffer(bind_text.vertex_buffers[1], SG_RANGE_REF(color));
|
||||
sg_append_buffer(bind_text.index_buffer, SG_RANGE_REF(pts));
|
||||
|
||||
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, float color[3]) {
|
||||
float shadowcolor[3] = {0.f, 0.f, 0.f};
|
||||
float shadowcursor[2];
|
||||
|
||||
float verts[16];
|
||||
float offset[2] = {-1, 1};
|
||||
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
|
||||
/* Check if the vertex is off screen */
|
||||
if (verts[5] < -window_i(0)->width / 2.f || verts[9] < -window_i(0)->height / 2.f || verts[0] > window_i(0)->width / 2.f || verts[1] > window_i(0)->height / 2.f)
|
||||
return;
|
||||
|
||||
// fill_charverts(verts, cursor, scale, c, offset);
|
||||
uint16_t pts[6] = {
|
||||
0, 1, 2,
|
||||
2, 1, 3};
|
||||
|
||||
/*
|
||||
if (drawcaret == curchar) {
|
||||
draw_char_box(c, cursor, scale, color);
|
||||
shader_use(shader);
|
||||
shader_setvec3(shader, "textColor", color);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, font->texID);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
}
|
||||
*/
|
||||
// sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(shadowcolor));
|
||||
/*
|
||||
sg_append_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
offset[0] = 1;
|
||||
offset[1] = -1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
offset[1] = 1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
offset[0] = -1;
|
||||
offset[1] = -1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
*/
|
||||
offset[0] = offset[1] = 0;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
/* SET COLOR ? */
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
}
|
||||
for (int i = 0; i < 6; i++)
|
||||
pts[i] += curchar * 4;
|
||||
|
||||
void text_settype(struct sFont *mfont)
|
||||
{
|
||||
font = mfont;
|
||||
}
|
||||
memcpy(text_buffer + (16 * curchar), verts, sizeof(verts));
|
||||
for (int i = 0; i < 4; i++)
|
||||
memcpy(color_buffer + (12 * curchar) + (3 * i), color, sizeof(color));
|
||||
memcpy(text_idx_buffer + (6 * curchar), pts, sizeof(pts));
|
||||
curchar++;
|
||||
return;
|
||||
|
||||
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw, int caret)
|
||||
{
|
||||
int len = strlen(text);
|
||||
drawcaret = caret;
|
||||
|
||||
mfloat_t cursor[2] = { 0.f };
|
||||
cursor[0] = pos[0];
|
||||
cursor[1] = pos[1];
|
||||
|
||||
const unsigned char *line, *wordstart, *drawstart;
|
||||
line = drawstart = (unsigned char*)text;
|
||||
|
||||
float *usecolor = color;
|
||||
|
||||
while (*line != '\0') {
|
||||
|
||||
switch (*line) {
|
||||
case '\n':
|
||||
sdrawCharacter(font->Characters[*line], cursor, scale, shader, usecolor);
|
||||
cursor[1] -= scale * font->height;
|
||||
cursor[0] = pos[0];
|
||||
line++;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
sdrawCharacter(font->Characters[*line], cursor, scale, shader, usecolor);
|
||||
cursor[0] += font->Characters[*line].Advance * scale;
|
||||
line++;
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
sdrawCharacter(font->Characters[*line], cursor, scale, shader, usecolor);
|
||||
cursor[0] += font->Characters[*line].Advance * scale;
|
||||
line++;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
wordstart = line;
|
||||
int wordWidth = 0;
|
||||
|
||||
while (!isspace(*line) && *line != '\0') {
|
||||
wordWidth += font->Characters[*line].Advance * scale;
|
||||
line++;
|
||||
}
|
||||
|
||||
if (lw > 0 && (cursor[0] + wordWidth - pos[0]) >= lw) {
|
||||
cursor[0] = pos[0];
|
||||
cursor[1] -= scale * font->height;
|
||||
}
|
||||
|
||||
while (wordstart < line) {
|
||||
sdrawCharacter(font->Characters[*wordstart], cursor, scale, shader, usecolor);
|
||||
cursor[0] += font->Characters[*wordstart].Advance * scale;
|
||||
wordstart++;
|
||||
}
|
||||
/*
|
||||
if (drawcaret == curchar) {
|
||||
draw_char_box(c, cursor, scale, color);
|
||||
shader_use(shader);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
sg_append_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
/* if (caret > curchar) {
|
||||
draw_char_box(font->Characters[69], cursor, scale, color);
|
||||
}
|
||||
*/
|
||||
offset[0] = 1;
|
||||
offset[1] = -1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
offset[1] = 1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
|
||||
offset[0] = -1;
|
||||
offset[1] = -1;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
*/
|
||||
offset[0] = offset[1] = 0;
|
||||
fill_charverts(verts, cursor, scale, c, offset);
|
||||
|
||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||
}
|
||||
|
||||
void text_settype(struct sFont *mfont) {
|
||||
font = mfont;
|
||||
}
|
||||
|
||||
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw, int caret) {
|
||||
int len = strlen(text);
|
||||
drawcaret = caret;
|
||||
|
||||
mfloat_t cursor[2] = {0.f};
|
||||
cursor[0] = pos[0];
|
||||
cursor[1] = pos[1];
|
||||
|
||||
const unsigned char *line, *wordstart, *drawstart;
|
||||
line = drawstart = (unsigned char *)text;
|
||||
|
||||
float *usecolor = color;
|
||||
|
||||
while (*line != '\0') {
|
||||
if (isblank(*line)) {
|
||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||
cursor[0] += font->Characters[*line].Advance * scale;
|
||||
line++;
|
||||
} else if (isspace(*line)) {
|
||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||
cursor[1] -= scale * font->height;
|
||||
cursor[0] = pos[0];
|
||||
line++;
|
||||
|
||||
} else {
|
||||
|
||||
wordstart = line;
|
||||
int wordWidth = 0;
|
||||
|
||||
while (!isspace(*line) && *line != '\0') {
|
||||
wordWidth += font->Characters[*line].Advance * scale;
|
||||
line++;
|
||||
}
|
||||
|
||||
if (lw > 0 && (cursor[0] + wordWidth - pos[0]) >= lw) {
|
||||
cursor[0] = pos[0];
|
||||
cursor[1] -= scale * font->height;
|
||||
}
|
||||
|
||||
while (wordstart < line) {
|
||||
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor);
|
||||
cursor[0] += font->Characters[*wordstart].Advance * scale;
|
||||
wordstart++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if (caret > curchar) {
|
||||
draw_char_box(font->Characters[69], cursor, scale, color);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
return cursor[1] - pos[1];
|
||||
}
|
||||
|
|
|
@ -2,36 +2,34 @@
|
|||
#define FONT_H
|
||||
|
||||
#include "mathc.h"
|
||||
#include "texture.h"
|
||||
#include "sokol/sokol_gfx.h"
|
||||
#include "texture.h"
|
||||
|
||||
struct shader;
|
||||
struct window;
|
||||
|
||||
/// Holds all state information relevant to a character as loaded using FreeType
|
||||
struct Character {
|
||||
mfloat_t Size[2]; // Size of glyph
|
||||
mfloat_t Bearing[2]; // Offset from baseline to left/top of glyph
|
||||
unsigned int Advance; // Horizontal offset to advance to next glyph
|
||||
struct glrect rect;
|
||||
|
||||
mfloat_t Size[2]; // Size of glyph
|
||||
mfloat_t Bearing[2]; // Offset from baseline to left/top of glyph
|
||||
unsigned int Advance; // Horizontal offset to advance to next glyph
|
||||
struct glrect rect;
|
||||
};
|
||||
|
||||
struct sFont {
|
||||
uint32_t fontTexture;
|
||||
uint32_t height;
|
||||
struct Character Characters[127];
|
||||
sg_image texID;
|
||||
uint32_t fontTexture;
|
||||
uint32_t height;
|
||||
struct Character Characters[127];
|
||||
sg_image texID;
|
||||
};
|
||||
|
||||
void font_init(struct shader *s);
|
||||
void font_frame(struct window *w);
|
||||
struct sFont *MakeFont(const char *fontfile, int height);
|
||||
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct shader *shader, float color[3]);
|
||||
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, float color[3]);
|
||||
void text_settype(struct sFont *font);
|
||||
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw,int caret);
|
||||
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw, int caret);
|
||||
|
||||
//void text_frame();
|
||||
// void text_frame();
|
||||
void text_flush();
|
||||
|
||||
unsigned char *slurp_file(const char *filename);
|
||||
|
|
|
@ -1,61 +1,56 @@
|
|||
#include "gameobject.h"
|
||||
|
||||
#include "2dphysics.h"
|
||||
#include "debugdraw.h"
|
||||
#include "input.h"
|
||||
#include "log.h"
|
||||
#include "nuke.h"
|
||||
#include "resources.h"
|
||||
#include "script.h"
|
||||
#include "shader.h"
|
||||
#include "sprite.h"
|
||||
#include "2dphysics.h"
|
||||
#include "script.h"
|
||||
#include "input.h"
|
||||
#include <string.h>
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include "resources.h"
|
||||
#include "nuke.h"
|
||||
#include "log.h"
|
||||
#include "debugdraw.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "stb_ds.h"
|
||||
|
||||
struct gameobject *gameobjects = NULL;
|
||||
static int first = -1;
|
||||
|
||||
const int nameBuf[MAXNAME] = { 0 };
|
||||
const int prefabNameBuf[MAXNAME] = { 0 };
|
||||
const int nameBuf[MAXNAME] = {0};
|
||||
const int prefabNameBuf[MAXNAME] = {0};
|
||||
|
||||
struct gameobject *get_gameobject_from_id(int id)
|
||||
{ if (id < 0) return NULL;
|
||||
struct gameobject *get_gameobject_from_id(int id) {
|
||||
if (id < 0) return NULL;
|
||||
|
||||
return &gameobjects[id];
|
||||
return &gameobjects[id];
|
||||
}
|
||||
|
||||
struct gameobject *id2go(int id)
|
||||
{
|
||||
if (id < 0) return NULL;
|
||||
struct gameobject *id2go(int id) {
|
||||
if (id < 0) return NULL;
|
||||
|
||||
return &gameobjects[id];
|
||||
return &gameobjects[id];
|
||||
}
|
||||
|
||||
int body2id(cpBody *body)
|
||||
{
|
||||
int body2id(cpBody *body) {
|
||||
return (int)cpBodyGetUserData(body);
|
||||
}
|
||||
|
||||
cpBody *id2body(int id)
|
||||
{
|
||||
cpBody *id2body(int id) {
|
||||
struct gameobject *go = id2go(id);
|
||||
|
||||
|
||||
if (go)
|
||||
return go->body;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int shape2gameobject(cpShape *shape)
|
||||
{
|
||||
int shape2gameobject(cpShape *shape) {
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
return s->go;
|
||||
}
|
||||
|
||||
int pos2gameobject(cpVect pos)
|
||||
{
|
||||
int pos2gameobject(cpVect pos) {
|
||||
cpShape *hit = phys2d_query_pos(pos);
|
||||
|
||||
if (hit) {
|
||||
|
@ -73,269 +68,255 @@ int pos2gameobject(cpVect pos)
|
|||
}
|
||||
|
||||
int id_from_gameobject(struct gameobject *go) {
|
||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||
if (&gameobjects[i] == go) return i;
|
||||
}
|
||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||
if (&gameobjects[i] == go) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gameobject_set_sensor(int id, int sensor)
|
||||
{
|
||||
void gameobject_set_sensor(int id, int sensor) {
|
||||
id2go(id)->sensor = sensor;
|
||||
gameobject_apply(id2go(id));
|
||||
}
|
||||
|
||||
int go2id(struct gameobject *go)
|
||||
{
|
||||
int go2id(struct gameobject *go) {
|
||||
return id_from_gameobject(go);
|
||||
}
|
||||
|
||||
void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go)
|
||||
{
|
||||
cpShapeSetFriction(shape, go->f);
|
||||
cpShapeSetElasticity(shape, go->e);
|
||||
cpShapeSetCollisionType(shape, go2id(go));
|
||||
|
||||
void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go) {
|
||||
cpShapeSetFriction(shape, go->f);
|
||||
cpShapeSetElasticity(shape, go->e);
|
||||
cpShapeSetCollisionType(shape, go2id(go));
|
||||
|
||||
/* cpShapeFilter filter;
|
||||
filter.group = go2id(go);
|
||||
filter.categories = 1<<go->layer;
|
||||
filter.mask = category_masks[go->layer];
|
||||
cpShapeSetFilter(shape, filter);
|
||||
*/
|
||||
/* cpShapeFilter filter;
|
||||
filter.group = go2id(go);
|
||||
filter.categories = 1<<go->layer;
|
||||
filter.mask = category_masks[go->layer];
|
||||
cpShapeSetFilter(shape, filter);
|
||||
*/
|
||||
}
|
||||
|
||||
void go_shape_moi(cpBody *body, cpShape *shape, struct gameobject *go)
|
||||
{
|
||||
float moment = cpBodyGetMoment(go->body);
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
if (!s) {
|
||||
cpBodySetMoment(go->body, moment+1);
|
||||
return;
|
||||
}
|
||||
|
||||
moment += s->moi(s->data, go->mass);
|
||||
cpBodySetMoment(go->body, moment);
|
||||
void go_shape_moi(cpBody *body, cpShape *shape, struct gameobject *go) {
|
||||
float moment = cpBodyGetMoment(go->body);
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
if (!s) {
|
||||
cpBodySetMoment(go->body, moment + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
moment += s->moi(s->data, go->mass);
|
||||
cpBodySetMoment(go->body, moment);
|
||||
}
|
||||
|
||||
void gameobject_apply(struct gameobject *go)
|
||||
{
|
||||
cpBodySetType(go->body, go->bodytype);
|
||||
cpBodyEachShape(go->body, go_shape_apply, go);
|
||||
|
||||
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||
cpBodySetMass(go->body, go->mass);
|
||||
cpBodySetMoment(go->body, 0.f);
|
||||
cpBodyEachShape(go->body, go_shape_moi, go);
|
||||
|
||||
if (cpBodyGetMoment(go->body) <= 0.f)
|
||||
cpBodySetMoment(go->body, 1.f);
|
||||
|
||||
return;
|
||||
}
|
||||
void gameobject_apply(struct gameobject *go) {
|
||||
cpBodySetType(go->body, go->bodytype);
|
||||
cpBodyEachShape(go->body, go_shape_apply, go);
|
||||
|
||||
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||
cpBodySetMass(go->body, go->mass);
|
||||
cpBodySetMoment(go->body, 0.f);
|
||||
cpBodyEachShape(go->body, go_shape_moi, go);
|
||||
|
||||
if (cpBodyGetMoment(go->body) <= 0.f)
|
||||
cpBodySetMoment(go->body, 1.f);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void gameobject_setpickcolor(struct gameobject *go)
|
||||
{
|
||||
/*
|
||||
float r = ((go->editor.id & 0x000000FF) >> 0) / 255.f;
|
||||
float g = ((go->editor.id & 0x0000FF00) >> 8) / 255.f;
|
||||
float b = ((go->editor.id & 0x00FF0000) >> 16) / 255.f;
|
||||
static void gameobject_setpickcolor(struct gameobject *go) {
|
||||
/*
|
||||
float r = ((go->editor.id & 0x000000FF) >> 0) / 255.f;
|
||||
float g = ((go->editor.id & 0x0000FF00) >> 8) / 255.f;
|
||||
float b = ((go->editor.id & 0x00FF0000) >> 16) / 255.f;
|
||||
|
||||
go->editor.color[0] = r;
|
||||
go->editor.color[1] = g;
|
||||
go->editor.color[2] = b;
|
||||
*/
|
||||
go->editor.color[0] = r;
|
||||
go->editor.color[1] = g;
|
||||
go->editor.color[2] = b;
|
||||
*/
|
||||
}
|
||||
|
||||
int MakeGameobject()
|
||||
{
|
||||
struct gameobject go = {
|
||||
.scale = 1.f,
|
||||
.bodytype = CP_BODY_TYPE_STATIC,
|
||||
.mass = 1.f,
|
||||
.next = -1,
|
||||
.sensor = 0,
|
||||
.shape_cbs = NULL,
|
||||
};
|
||||
int MakeGameobject() {
|
||||
struct gameobject go = {
|
||||
.scale = 1.f,
|
||||
.bodytype = CP_BODY_TYPE_STATIC,
|
||||
.mass = 1.f,
|
||||
.next = -1,
|
||||
.sensor = 0,
|
||||
.shape_cbs = NULL,
|
||||
};
|
||||
|
||||
go.cbs.begin.obj = JS_NULL;
|
||||
go.cbs.separate.obj = JS_NULL;
|
||||
go.cbs.begin.obj = JS_NULL;
|
||||
go.cbs.separate.obj = JS_NULL;
|
||||
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
|
||||
|
||||
int retid;
|
||||
int retid;
|
||||
|
||||
if (first<0) {
|
||||
arrput(gameobjects, go);
|
||||
retid = arrlast(gameobjects).id = arrlen(gameobjects)-1;
|
||||
} else {
|
||||
retid = first;
|
||||
first = id2go(first)->next;
|
||||
*id2go(retid) = go;
|
||||
}
|
||||
|
||||
cpBodySetUserData(go.body, (void*)retid);
|
||||
phys2d_setup_handlers(retid);
|
||||
return retid;
|
||||
if (first < 0) {
|
||||
arrput(gameobjects, go);
|
||||
retid = arrlast(gameobjects).id = arrlen(gameobjects) - 1;
|
||||
} else {
|
||||
retid = first;
|
||||
first = id2go(first)->next;
|
||||
*id2go(retid) = go;
|
||||
}
|
||||
|
||||
cpBodySetUserData(go.body, (void *)retid);
|
||||
phys2d_setup_handlers(retid);
|
||||
return retid;
|
||||
}
|
||||
|
||||
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
if (s->data) {
|
||||
free(s->data);
|
||||
s->data = NULL;
|
||||
}
|
||||
cpSpaceRemoveShape(space, shape);
|
||||
cpShapeFree(shape);
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
if (s->data) {
|
||||
free(s->data);
|
||||
s->data = NULL;
|
||||
}
|
||||
cpSpaceRemoveShape(space, shape);
|
||||
cpShapeFree(shape);
|
||||
}
|
||||
|
||||
int *go_toclean = NULL;
|
||||
|
||||
/* Free this gameobject */
|
||||
void gameobject_clean(int id) {
|
||||
struct gameobject *go = id2go(id);
|
||||
arrfree(go->shape_cbs);
|
||||
cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
||||
cpSpaceRemoveBody(space, go->body);
|
||||
cpBodyFree(go->body);
|
||||
go->body = NULL;
|
||||
struct gameobject *go = id2go(id);
|
||||
arrfree(go->shape_cbs);
|
||||
cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
||||
cpSpaceRemoveBody(space, go->body);
|
||||
cpBodyFree(go->body);
|
||||
go->body = NULL;
|
||||
}
|
||||
|
||||
/* Really more of a "mark for deletion" ... */
|
||||
void gameobject_delete(int id)
|
||||
{
|
||||
id2go(id)->next = first;
|
||||
first = id;
|
||||
void gameobject_delete(int id) {
|
||||
id2go(id)->next = first;
|
||||
first = id;
|
||||
|
||||
if (cpSpaceIsLocked(space))
|
||||
arrpush(go_toclean, id);
|
||||
else
|
||||
gameobject_clean(id);
|
||||
if (cpSpaceIsLocked(space))
|
||||
arrpush(go_toclean, id);
|
||||
else
|
||||
gameobject_clean(id);
|
||||
}
|
||||
|
||||
void gameobjects_cleanup() {
|
||||
for (int i = 0; i < arrlen(go_toclean); i++)
|
||||
gameobject_clean(go_toclean[i]);
|
||||
for (int i = 0; i < arrlen(go_toclean); i++)
|
||||
gameobject_clean(go_toclean[i]);
|
||||
|
||||
arrsetlen(go_toclean, 0);
|
||||
|
||||
return;
|
||||
arrsetlen(go_toclean, 0);
|
||||
|
||||
int clean = first;
|
||||
return;
|
||||
|
||||
while (clean >= 0 && id2go(clean)->body) {
|
||||
gameobject_clean(clean);
|
||||
clean = id2go(clean)->next;
|
||||
}
|
||||
int clean = first;
|
||||
|
||||
while (clean >= 0 && id2go(clean)->body) {
|
||||
gameobject_clean(clean);
|
||||
clean = id2go(clean)->next;
|
||||
}
|
||||
}
|
||||
|
||||
void gameobject_move(struct gameobject *go, cpVect vec)
|
||||
{
|
||||
cpVect p = cpBodyGetPosition(go->body);
|
||||
p.x += vec.x;
|
||||
p.y += vec.y;
|
||||
cpBodySetPosition(go->body, p);
|
||||
void gameobject_move(struct gameobject *go, cpVect vec) {
|
||||
cpVect p = cpBodyGetPosition(go->body);
|
||||
p.x += vec.x;
|
||||
p.y += vec.y;
|
||||
cpBodySetPosition(go->body, p);
|
||||
|
||||
phys2d_reindex_body(go->body);
|
||||
phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
||||
void gameobject_rotate(struct gameobject *go, float as)
|
||||
{
|
||||
cpFloat a = cpBodyGetAngle(go->body);
|
||||
a += as * deltaT;
|
||||
cpBodySetAngle(go->body, a);
|
||||
void gameobject_rotate(struct gameobject *go, float as) {
|
||||
cpFloat a = cpBodyGetAngle(go->body);
|
||||
a += as * deltaT;
|
||||
cpBodySetAngle(go->body, a);
|
||||
|
||||
phys2d_reindex_body(go->body);
|
||||
phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
||||
void gameobject_setangle(struct gameobject *go, float angle) {
|
||||
cpBodySetAngle(go->body, angle);
|
||||
phys2d_reindex_body(go->body);
|
||||
cpBodySetAngle(go->body, angle);
|
||||
phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
||||
void gameobject_setpos(struct gameobject *go, cpVect vec) {
|
||||
if (!go || !go->body) return;
|
||||
cpBodySetPosition(go->body, vec);
|
||||
if (!go || !go->body) return;
|
||||
cpBodySetPosition(go->body, vec);
|
||||
|
||||
phys2d_reindex_body(go->body);
|
||||
phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
||||
void object_gui(struct gameobject *go)
|
||||
{
|
||||
/*
|
||||
float temp_pos[2];
|
||||
temp_pos[0] = cpBodyGetPosition(go->body).x;
|
||||
temp_pos[1] = cpBodyGetPosition(go->body).y;
|
||||
void object_gui(struct gameobject *go) {
|
||||
/*
|
||||
float temp_pos[2];
|
||||
temp_pos[0] = cpBodyGetPosition(go->body).x;
|
||||
temp_pos[1] = cpBodyGetPosition(go->body).y;
|
||||
|
||||
draw_point(temp_pos[0], temp_pos[1], 3);
|
||||
draw_point(temp_pos[0], temp_pos[1], 3);
|
||||
|
||||
nuke_property_float2("Position", -1000000.f, temp_pos, 1000000.f, 1.f, 0.5f);
|
||||
nuke_property_float2("Position", -1000000.f, temp_pos, 1000000.f, 1.f, 0.5f);
|
||||
|
||||
cpVect tvect = { temp_pos[0], temp_pos[1] };
|
||||
cpBodySetPosition(go->body, tvect);
|
||||
cpVect tvect = { temp_pos[0], temp_pos[1] };
|
||||
cpBodySetPosition(go->body, tvect);
|
||||
|
||||
float mtry = cpBodyGetAngle(go->body);
|
||||
float modtry = fmodf(mtry * RAD2DEGS, 360.f);
|
||||
if (modtry < 0.f)
|
||||
modtry += 360.f;
|
||||
float mtry = cpBodyGetAngle(go->body);
|
||||
float modtry = fmodf(mtry * RAD2DEGS, 360.f);
|
||||
if (modtry < 0.f)
|
||||
modtry += 360.f;
|
||||
|
||||
float modtry2 = modtry;
|
||||
nuke_property_float("Angle", -1000.f, &modtry, 1000.f, 0.5f, 0.5f);
|
||||
modtry -= modtry2;
|
||||
cpBodySetAngle(go->body, mtry + (modtry * DEG2RADS));
|
||||
float modtry2 = modtry;
|
||||
nuke_property_float("Angle", -1000.f, &modtry, 1000.f, 0.5f, 0.5f);
|
||||
modtry -= modtry2;
|
||||
cpBodySetAngle(go->body, mtry + (modtry * DEG2RADS));
|
||||
|
||||
nuke_property_float("Scale", 0.f, &go->scale, 1000.f, 0.01f, go->scale * 0.01f);
|
||||
nuke_property_float("Scale", 0.f, &go->scale, 1000.f, 0.01f, go->scale * 0.01f);
|
||||
|
||||
nuke_nel(3);
|
||||
nuke_radio_btn("Static", &go->bodytype, CP_BODY_TYPE_STATIC);
|
||||
nuke_radio_btn("Dynamic", &go->bodytype, CP_BODY_TYPE_DYNAMIC);
|
||||
nuke_radio_btn("Kinematic", &go->bodytype, CP_BODY_TYPE_KINEMATIC);
|
||||
nuke_nel(3);
|
||||
nuke_radio_btn("Static", &go->bodytype, CP_BODY_TYPE_STATIC);
|
||||
nuke_radio_btn("Dynamic", &go->bodytype, CP_BODY_TYPE_DYNAMIC);
|
||||
nuke_radio_btn("Kinematic", &go->bodytype, CP_BODY_TYPE_KINEMATIC);
|
||||
|
||||
cpBodySetType(go->body, go->bodytype);
|
||||
cpBodySetType(go->body, go->bodytype);
|
||||
|
||||
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||
nuke_property_float("Mass", 0.01f, &go->mass, 1000.f, 0.01f, 0.01f);
|
||||
cpBodySetMass(go->body, go->mass);
|
||||
}
|
||||
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||
nuke_property_float("Mass", 0.01f, &go->mass, 1000.f, 0.01f, 0.01f);
|
||||
cpBodySetMass(go->body, go->mass);
|
||||
}
|
||||
|
||||
nuke_property_float("Friction", 0.f, &go->f, 10.f, 0.01f, 0.01f);
|
||||
nuke_property_float("Elasticity", 0.f, &go->e, 2.f, 0.01f, 0.01f);
|
||||
nuke_property_float("Friction", 0.f, &go->f, 10.f, 0.01f, 0.01f);
|
||||
nuke_property_float("Elasticity", 0.f, &go->e, 2.f, 0.01f, 0.01f);
|
||||
|
||||
int n = -1;
|
||||
int n = -1;
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < arrlen(go->components); i++) {
|
||||
struct component *c = &go->components[i];
|
||||
for (int i = 0; i < arrlen(go->components); i++) {
|
||||
struct component *c = &go->components[i];
|
||||
|
||||
comp_draw_debug(c);
|
||||
comp_draw_debug(c);
|
||||
|
||||
nuke_nel(5);
|
||||
if (nuke_btn("Del")) n = i;
|
||||
nuke_nel(5);
|
||||
if (nuke_btn("Del")) n = i;
|
||||
|
||||
if (nuke_push_tree_id(c->ref->name, i)) {
|
||||
comp_draw_gui(c);
|
||||
nuke_tree_pop();
|
||||
}
|
||||
if (nuke_push_tree_id(c->ref->name, i)) {
|
||||
comp_draw_gui(c);
|
||||
nuke_tree_pop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (n >= 0)
|
||||
gameobject_delcomponent(go, n);
|
||||
*/
|
||||
if (n >= 0)
|
||||
gameobject_delcomponent(go, n);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
s->debugdraw(s->data);
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
s->debugdraw(s->data);
|
||||
}
|
||||
|
||||
void gameobject_draw_debug(int go)
|
||||
{
|
||||
void gameobject_draw_debug(int go) {
|
||||
struct gameobject *g = id2go(go);
|
||||
if (!g || !g->body) return;
|
||||
|
||||
|
@ -346,37 +327,40 @@ void gameobject_draw_debug(int go)
|
|||
}
|
||||
|
||||
void gameobject_draw_debugs() {
|
||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||
gameobject_draw_debug(i);
|
||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||
gameobject_draw_debug(i);
|
||||
}
|
||||
|
||||
|
||||
static struct {struct gameobject go; cpVect pos; float angle; } *saveobjects = NULL;
|
||||
static struct {
|
||||
struct gameobject go;
|
||||
cpVect pos;
|
||||
float angle;
|
||||
} *saveobjects = NULL;
|
||||
|
||||
void gameobject_saveall() {
|
||||
arrfree(saveobjects);
|
||||
arrsetlen(saveobjects, arrlen(gameobjects));
|
||||
arrfree(saveobjects);
|
||||
arrsetlen(saveobjects, arrlen(gameobjects));
|
||||
|
||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||
saveobjects[i].go = gameobjects[i];
|
||||
saveobjects[i].pos = cpBodyGetPosition(gameobjects[i].body);
|
||||
saveobjects[i].angle = cpBodyGetAngle(gameobjects[i].body);
|
||||
}
|
||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||
saveobjects[i].go = gameobjects[i];
|
||||
saveobjects[i].pos = cpBodyGetPosition(gameobjects[i].body);
|
||||
saveobjects[i].angle = cpBodyGetAngle(gameobjects[i].body);
|
||||
}
|
||||
}
|
||||
|
||||
void gameobject_loadall() {
|
||||
YughInfo("N gameobjects: %d, N saved: %d", arrlen(gameobjects), arrlen(saveobjects));
|
||||
for (int i = 0; i < arrlen(saveobjects); i++) {
|
||||
gameobjects[i] = saveobjects[i].go;
|
||||
cpBodySetPosition(gameobjects[i].body, saveobjects[i].pos);
|
||||
cpBodySetAngle(gameobjects[i].body, saveobjects[i].angle);
|
||||
cpBodySetVelocity(gameobjects[i].body, cpvzero);
|
||||
cpBodySetAngularVelocity(gameobjects[i].body, 0.f);
|
||||
}
|
||||
YughInfo("N gameobjects: %d, N saved: %d", arrlen(gameobjects), arrlen(saveobjects));
|
||||
for (int i = 0; i < arrlen(saveobjects); i++) {
|
||||
gameobjects[i] = saveobjects[i].go;
|
||||
cpBodySetPosition(gameobjects[i].body, saveobjects[i].pos);
|
||||
cpBodySetAngle(gameobjects[i].body, saveobjects[i].angle);
|
||||
cpBodySetVelocity(gameobjects[i].body, cpvzero);
|
||||
cpBodySetAngularVelocity(gameobjects[i].body, 0.f);
|
||||
}
|
||||
|
||||
arrfree(saveobjects);
|
||||
arrfree(saveobjects);
|
||||
}
|
||||
|
||||
int gameobjects_saved() {
|
||||
return arrlen(saveobjects);
|
||||
return arrlen(saveobjects);
|
||||
}
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
#ifndef GAMEOBJECT_H
|
||||
#define GAMEOBJECT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "mathc.h"
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include "2dphysics.h"
|
||||
#include "config.h"
|
||||
#include "mathc.h"
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct shader;
|
||||
struct sprite;
|
||||
struct component;
|
||||
|
||||
struct gameobject {
|
||||
cpBodyType bodytype;
|
||||
int next;
|
||||
float scale;
|
||||
float mass;
|
||||
float f; /* friction */
|
||||
float e; /* elasticity */
|
||||
int flipx; /* 1 or -1 */
|
||||
int flipy;
|
||||
int sensor;
|
||||
unsigned int layer;
|
||||
cpShapeFilter filter;
|
||||
cpBody *body; /* NULL if this object is dead */
|
||||
int id;
|
||||
struct phys_cbs cbs;
|
||||
struct shape_cb *shape_cbs;
|
||||
cpBodyType bodytype;
|
||||
int next;
|
||||
float scale;
|
||||
float mass;
|
||||
float f; /* friction */
|
||||
float e; /* elasticity */
|
||||
int flipx; /* 1 or -1 */
|
||||
int flipy;
|
||||
int sensor;
|
||||
unsigned int layer;
|
||||
cpShapeFilter filter;
|
||||
cpBody *body; /* NULL if this object is dead */
|
||||
int id;
|
||||
struct phys_cbs cbs;
|
||||
struct shape_cb *shape_cbs;
|
||||
};
|
||||
|
||||
extern struct gameobject *gameobjects;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,14 +1,14 @@
|
|||
#include "input.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ffi.h"
|
||||
#include "font.h"
|
||||
#include "log.h"
|
||||
#include "script.h"
|
||||
#include "stb_ds.h"
|
||||
#include "log.h"
|
||||
#include "ffi.h"
|
||||
#include "time.h"
|
||||
#include "font.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#inlcude "stb_ds.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
int32_t mouseWheelX = 0;
|
||||
int32_t mouseWheelY = 0;
|
||||
|
@ -24,8 +24,8 @@ JSValue jsany;
|
|||
JSValue jsmouse;
|
||||
JSValue jspos;
|
||||
|
||||
cpVect mouse_pos = {0,0};
|
||||
cpVect mouse_delta = {0,0};
|
||||
cpVect mouse_pos = {0, 0};
|
||||
cpVect mouse_delta = {0, 0};
|
||||
|
||||
struct joystick {
|
||||
int id;
|
||||
|
@ -45,8 +45,7 @@ static struct {
|
|||
JSValue value;
|
||||
} *jshash = NULL;
|
||||
|
||||
JSValue input2js(const char *input)
|
||||
{
|
||||
JSValue input2js(const char *input) {
|
||||
int idx = shgeti(jshash, input);
|
||||
if (idx != -1)
|
||||
return jshash[idx].value;
|
||||
|
@ -60,36 +59,48 @@ JSValue input2js(const char *input)
|
|||
return n;
|
||||
}
|
||||
|
||||
const char *gamepad2str(int btn)
|
||||
{
|
||||
switch(btn) {
|
||||
case GLFW_GAMEPAD_BUTTON_CROSS: return "cross";
|
||||
case GLFW_GAMEPAD_BUTTON_CIRCLE: return "circle";
|
||||
case GLFW_GAMEPAD_BUTTON_SQUARE: return "square";
|
||||
case GLFW_GAMEPAD_BUTTON_TRIANGLE: return "triangle";
|
||||
case GLFW_GAMEPAD_BUTTON_START: return "start";
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return "lbump";
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return "rbump";
|
||||
case GLFW_GAMEPAD_BUTTON_GUIDE: return "guide";
|
||||
case GLFW_GAMEPAD_BUTTON_BACK: return "back";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP: return "dup";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return "ddown";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return "dleft";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return "dright";
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return "lthumb";
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return "rthumb";
|
||||
const char *gamepad2str(int btn) {
|
||||
switch (btn) {
|
||||
case GLFW_GAMEPAD_BUTTON_CROSS:
|
||||
return "cross";
|
||||
case GLFW_GAMEPAD_BUTTON_CIRCLE:
|
||||
return "circle";
|
||||
case GLFW_GAMEPAD_BUTTON_SQUARE:
|
||||
return "square";
|
||||
case GLFW_GAMEPAD_BUTTON_TRIANGLE:
|
||||
return "triangle";
|
||||
case GLFW_GAMEPAD_BUTTON_START:
|
||||
return "start";
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||
return "lbump";
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||
return "rbump";
|
||||
case GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||
return "guide";
|
||||
case GLFW_GAMEPAD_BUTTON_BACK:
|
||||
return "back";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP:
|
||||
return "dup";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
return "ddown";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
return "dleft";
|
||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
return "dright";
|
||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
|
||||
return "lthumb";
|
||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
|
||||
return "rthumb";
|
||||
}
|
||||
|
||||
|
||||
return "NOBTN";
|
||||
}
|
||||
|
||||
void register_pawn(struct callee c)
|
||||
{
|
||||
void register_pawn(struct callee c) {
|
||||
pawn_callee = c;
|
||||
}
|
||||
|
||||
void register_gamepad(struct callee c)
|
||||
{
|
||||
void register_gamepad(struct callee c) {
|
||||
gamepad_callee = c;
|
||||
}
|
||||
|
||||
|
@ -108,25 +119,23 @@ void rm_downkey(int key) {
|
|||
}
|
||||
}
|
||||
|
||||
static void cursor_pos_cb(GLFWwindow *w, double xpos, double ypos)
|
||||
{
|
||||
mouse_delta.x = xpos - mouse_pos.x;
|
||||
mouse_delta.y = ypos - mouse_pos.y;
|
||||
static void cursor_pos_cb(GLFWwindow *w, double xpos, double ypos) {
|
||||
mouse_delta.x = xpos - mouse_pos.x;
|
||||
mouse_delta.y = ypos - mouse_pos.y;
|
||||
|
||||
mouse_pos.x = xpos;
|
||||
mouse_pos.y = ypos;
|
||||
mouse_pos.x = xpos;
|
||||
mouse_pos.y = ypos;
|
||||
|
||||
JSValue argv[4];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = jsmouse;
|
||||
argv[2] = jspos;
|
||||
argv[3] = vec2js(mouse_pos);
|
||||
script_callee(pawn_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
JSValue argv[4];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = jsmouse;
|
||||
argv[2] = jspos;
|
||||
argv[3] = vec2js(mouse_pos);
|
||||
script_callee(pawn_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
}
|
||||
|
||||
static void pawn_call_keydown(int key)
|
||||
{
|
||||
static void pawn_call_keydown(int key) {
|
||||
JSValue argv[4];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = jsnum;
|
||||
|
@ -137,48 +146,44 @@ static void pawn_call_keydown(int key)
|
|||
JS_FreeValue(js, argv[3]);
|
||||
}
|
||||
|
||||
static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset)
|
||||
{
|
||||
mouseWheelY = yoffset;
|
||||
mouseWheelX = xoffset;
|
||||
static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset) {
|
||||
mouseWheelY = yoffset;
|
||||
mouseWheelX = xoffset;
|
||||
}
|
||||
|
||||
static void mb_cb(GLFWwindow *w, int button, int action, int mods)
|
||||
{
|
||||
static void mb_cb(GLFWwindow *w, int button, int action, int mods) {
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
switch (action) {
|
||||
case GLFW_PRESS:
|
||||
argv[2] = jsinputstate[2];
|
||||
add_downkey(button);
|
||||
break;
|
||||
case GLFW_PRESS:
|
||||
argv[2] = jsinputstate[2];
|
||||
add_downkey(button);
|
||||
break;
|
||||
|
||||
case GLFW_RELEASE:
|
||||
rm_downkey(button);
|
||||
argv[2] = jsinputstate[0];
|
||||
argv[1] = jsany;
|
||||
script_callee(pawn_callee,3,argv);
|
||||
break;
|
||||
case GLFW_RELEASE:
|
||||
rm_downkey(button);
|
||||
argv[2] = jsinputstate[0];
|
||||
argv[1] = jsany;
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
break;
|
||||
|
||||
case GLFW_REPEAT:
|
||||
argv[2] = jsinputstate[1];
|
||||
break;
|
||||
case GLFW_REPEAT:
|
||||
argv[2] = jsinputstate[1];
|
||||
break;
|
||||
}
|
||||
|
||||
argv[1] = input2js(keyname_extd(button,button));
|
||||
script_callee(pawn_callee,3,argv);
|
||||
argv[1] = input2js(keyname_extd(button, button));
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
}
|
||||
|
||||
void set_mouse_mode(int mousemode)
|
||||
{
|
||||
void set_mouse_mode(int mousemode) {
|
||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, mousemode);
|
||||
}
|
||||
|
||||
void char_cb(GLFWwindow *w, unsigned int codepoint)
|
||||
{
|
||||
void char_cb(GLFWwindow *w, unsigned int codepoint) {
|
||||
static char out[2] = {0};
|
||||
static JSValue argv[2];
|
||||
|
||||
|
||||
out[0] = (char)codepoint;
|
||||
argv[0] = JS_NewString(js, "input_text");
|
||||
argv[1] = JS_NewString(js, out);
|
||||
|
@ -190,76 +195,70 @@ void char_cb(GLFWwindow *w, unsigned int codepoint)
|
|||
|
||||
static GLFWcharfun nukechar;
|
||||
|
||||
void joystick_add(int id)
|
||||
{
|
||||
void joystick_add(int id) {
|
||||
struct joystick joy = {0};
|
||||
joy.id = id;
|
||||
arrpush(joysticks, joy);
|
||||
}
|
||||
|
||||
void joystick_cb(int jid, int event)
|
||||
{
|
||||
void joystick_cb(int jid, int event) {
|
||||
YughWarn("IN joystick cb");
|
||||
if (event == GLFW_CONNECTED) {
|
||||
for (int i = 0; i < arrlen(joysticks); i++)
|
||||
if (joysticks[i].id == jid) return;
|
||||
|
||||
|
||||
joystick_add(jid);
|
||||
} else if (event == GLFW_DISCONNECTED) {
|
||||
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||
if (joysticks[i].id == jid) {
|
||||
arrdelswap(joysticks,i);
|
||||
return;
|
||||
arrdelswap(joysticks, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void input_init() {
|
||||
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
||||
glfwSetScrollCallback(mainwin->window, scroll_cb);
|
||||
glfwSetMouseButtonCallback(mainwin->window, mb_cb);
|
||||
glfwSetJoystickCallback(joystick_cb);
|
||||
nukechar = glfwSetCharCallback(mainwin->window, char_cb);
|
||||
|
||||
void input_init()
|
||||
{
|
||||
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
||||
glfwSetScrollCallback(mainwin->window, scroll_cb);
|
||||
glfwSetMouseButtonCallback(mainwin->window, mb_cb);
|
||||
glfwSetJoystickCallback(joystick_cb);
|
||||
nukechar = glfwSetCharCallback(mainwin->window, char_cb);
|
||||
char *paddb = slurp_text("data/gamecontrollerdb.txt");
|
||||
glfwUpdateGamepadMappings(paddb);
|
||||
free(paddb);
|
||||
|
||||
char *paddb = slurp_text("data/gamecontrollerdb.txt");
|
||||
glfwUpdateGamepadMappings(paddb);
|
||||
free(paddb);
|
||||
for (int b = 0; b < 15; b++)
|
||||
jsgamepadstr[b] = str2js(gamepad2str(b));
|
||||
|
||||
for (int b = 0; b < 15; b++)
|
||||
jsgamepadstr[b] = str2js(gamepad2str(b));
|
||||
jsaxesstr[0] = str2js("ljoy");
|
||||
jsaxesstr[1] = str2js("rjoy");
|
||||
jsaxesstr[2] = str2js("ltrigger");
|
||||
jsaxesstr[3] = str2js("rtrigger");
|
||||
jsaxis = str2js("axis");
|
||||
|
||||
jsaxesstr[0] = str2js("ljoy");
|
||||
jsaxesstr[1] = str2js("rjoy");
|
||||
jsaxesstr[2] = str2js("ltrigger");
|
||||
jsaxesstr[3] = str2js("rtrigger");
|
||||
jsaxis = str2js("axis");
|
||||
/* Grab all joysticks initially present */
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (glfwJoystickPresent(i)) joystick_add(i);
|
||||
|
||||
/* Grab all joysticks initially present */
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (glfwJoystickPresent(i)) joystick_add(i);
|
||||
|
||||
jsinputstate[0] = str2js("released");
|
||||
jsinputstate[1] = str2js("rep");
|
||||
jsinputstate[2] = str2js("pressed");
|
||||
jsinputstate[3] = str2js("pressrep");
|
||||
jsinputstate[4] = str2js("down");
|
||||
jsinput = str2js("input");
|
||||
jsnum = str2js("num");
|
||||
jsany = str2js("any");
|
||||
jsmouse = str2js("mouse");
|
||||
jspos = str2js("pos");
|
||||
jsinputstate[0] = str2js("released");
|
||||
jsinputstate[1] = str2js("rep");
|
||||
jsinputstate[2] = str2js("pressed");
|
||||
jsinputstate[3] = str2js("pressrep");
|
||||
jsinputstate[4] = str2js("down");
|
||||
jsinput = str2js("input");
|
||||
jsnum = str2js("num");
|
||||
jsany = str2js("any");
|
||||
jsmouse = str2js("mouse");
|
||||
jspos = str2js("pos");
|
||||
}
|
||||
|
||||
void input_to_nuke()
|
||||
{
|
||||
void input_to_nuke() {
|
||||
glfwSetCharCallback(mainwin->window, nukechar);
|
||||
}
|
||||
|
||||
void input_to_game()
|
||||
{
|
||||
void input_to_game() {
|
||||
glfwSetCharCallback(mainwin->window, char_cb);
|
||||
}
|
||||
|
||||
|
@ -272,308 +271,303 @@ void call_input_signal(char *signal) {
|
|||
char keybuf[50];
|
||||
|
||||
const char *keyname_extd(int key, int scancode) {
|
||||
const char *kkey = NULL;
|
||||
const char *kkey = NULL;
|
||||
|
||||
if (key > 289 && key < 302) {
|
||||
int num = key-289;
|
||||
sprintf(keybuf, "f%d", num);
|
||||
return keybuf;
|
||||
} else if (key >= 320 && key <= 329) {
|
||||
int num = key-320;
|
||||
sprintf(keybuf, "kp%d",num);
|
||||
return keybuf;
|
||||
} else {
|
||||
switch(key) {
|
||||
case GLFW_KEY_ENTER:
|
||||
kkey = "enter";
|
||||
break;
|
||||
if (key > 289 && key < 302) {
|
||||
int num = key - 289;
|
||||
sprintf(keybuf, "f%d", num);
|
||||
return keybuf;
|
||||
} else if (key >= 320 && key <= 329) {
|
||||
int num = key - 320;
|
||||
sprintf(keybuf, "kp%d", num);
|
||||
return keybuf;
|
||||
} else {
|
||||
switch (key) {
|
||||
case GLFW_KEY_ENTER:
|
||||
kkey = "enter";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_ESCAPE:
|
||||
kkey = "escape";
|
||||
break;
|
||||
case GLFW_KEY_ESCAPE:
|
||||
kkey = "escape";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_DELETE:
|
||||
kkey = "delete";
|
||||
break;
|
||||
case GLFW_KEY_DELETE:
|
||||
kkey = "delete";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_INSERT:
|
||||
kkey = "insert";
|
||||
break;
|
||||
case GLFW_KEY_INSERT:
|
||||
kkey = "insert";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_TAB:
|
||||
kkey = "tab";
|
||||
break;
|
||||
case GLFW_KEY_TAB:
|
||||
kkey = "tab";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT:
|
||||
kkey = "right";
|
||||
break;
|
||||
case GLFW_KEY_RIGHT:
|
||||
kkey = "right";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT:
|
||||
kkey = "left";
|
||||
break;
|
||||
case GLFW_KEY_LEFT:
|
||||
kkey = "left";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_UP:
|
||||
kkey = "up";
|
||||
break;
|
||||
case GLFW_KEY_UP:
|
||||
kkey = "up";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_DOWN:
|
||||
kkey = "down";
|
||||
break;
|
||||
case GLFW_KEY_DOWN:
|
||||
kkey = "down";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
kkey = "lshift";
|
||||
break;
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
kkey = "lshift";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
kkey = "rshift";
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
kkey = "rshift";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
kkey = "lctrl";
|
||||
break;
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
kkey = "lctrl";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
kkey = "lalt";
|
||||
break;
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
kkey = "lalt";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
kkey = "rctrl";
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
kkey = "rctrl";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT_ALT:
|
||||
kkey= "ralt";
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_ALT:
|
||||
kkey = "ralt";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_SPACE:
|
||||
kkey = "space";
|
||||
break;
|
||||
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
kkey = "rmouse";
|
||||
break;
|
||||
case GLFW_KEY_SPACE:
|
||||
kkey = "space";
|
||||
break;
|
||||
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
kkey = "lmouse";
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
kkey = "rmouse";
|
||||
break;
|
||||
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
kkey = "mmouse";
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
kkey = "lmouse";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_KP_ADD:
|
||||
kkey = "plus";
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
kkey = "mmouse";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_KP_SUBTRACT:
|
||||
kkey = "minus";
|
||||
break;
|
||||
case GLFW_KEY_GRAVE_ACCENT:
|
||||
kkey = "backtick";
|
||||
break;
|
||||
case GLFW_KEY_KP_ADD:
|
||||
kkey = "plus";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_BRACKET:
|
||||
kkey = "lbracket";
|
||||
break;
|
||||
case GLFW_KEY_KP_SUBTRACT:
|
||||
kkey = "minus";
|
||||
break;
|
||||
case GLFW_KEY_GRAVE_ACCENT:
|
||||
kkey = "backtick";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT_BRACKET:
|
||||
kkey = "rbracket";
|
||||
break;
|
||||
case GLFW_KEY_LEFT_BRACKET:
|
||||
kkey = "lbracket";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_BACKSPACE:
|
||||
kkey = "backspace";
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_RIGHT_BRACKET:
|
||||
kkey = "rbracket";
|
||||
break;
|
||||
|
||||
if (kkey) return kkey;
|
||||
|
||||
}
|
||||
|
||||
kkey = glfwGetKeyName(key, scancode);
|
||||
case GLFW_KEY_BACKSPACE:
|
||||
kkey = "backspace";
|
||||
break;
|
||||
}
|
||||
|
||||
if (kkey) return kkey;
|
||||
}
|
||||
|
||||
return "NULL";
|
||||
kkey = glfwGetKeyName(key, scancode);
|
||||
|
||||
if (kkey) return kkey;
|
||||
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
void call_input_down(int *key) {
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = input2js(keyname_extd(*key, *key));
|
||||
argv[2] = jsinputstate[4];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = input2js(keyname_extd(*key, *key));
|
||||
argv[2] = jsinputstate[4];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
}
|
||||
|
||||
|
||||
const char *axis2str(int axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_X: return "lx";
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_Y: return "ly";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_X: return "rx";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_Y: return "ry";
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_TRIGGER: return "ltrigger";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER: return "rtrigger";
|
||||
const char *axis2str(int axis) {
|
||||
switch (axis) {
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_X:
|
||||
return "lx";
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_Y:
|
||||
return "ly";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_X:
|
||||
return "rx";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_Y:
|
||||
return "ry";
|
||||
case GLFW_GAMEPAD_AXIS_LEFT_TRIGGER:
|
||||
return "ltrigger";
|
||||
case GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER:
|
||||
return "rtrigger";
|
||||
}
|
||||
|
||||
|
||||
return "NOAXIS";
|
||||
}
|
||||
|
||||
/* This is called once every frame - or more if we want it more! */
|
||||
void input_poll(double wait)
|
||||
{
|
||||
mouse_delta = cpvzero;
|
||||
mouseWheelX = 0;
|
||||
mouseWheelY = 0;
|
||||
void input_poll(double wait) {
|
||||
mouse_delta = cpvzero;
|
||||
mouseWheelX = 0;
|
||||
mouseWheelY = 0;
|
||||
|
||||
glfwPollEvents();
|
||||
glfwPollEvents();
|
||||
|
||||
// glfwWaitEventsTimeout(wait);
|
||||
// glfwWaitEventsTimeout(wait);
|
||||
|
||||
for (int i = 0; i < arrlen(downkeys); i++)
|
||||
call_input_down(&downkeys[i]);
|
||||
for (int i = 0; i < arrlen(downkeys); i++)
|
||||
call_input_down(&downkeys[i]);
|
||||
|
||||
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||
GLFWgamepadstate state;
|
||||
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||
GLFWgamepadstate state;
|
||||
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||
|
||||
JSValue argv[4];
|
||||
argv[0] = num_cache[joysticks[i].id];
|
||||
for (int b = 0; b < 15; b++) {
|
||||
argv[1] = jsgamepadstr[b];
|
||||
|
||||
if (state.buttons[b]) {
|
||||
argv[2] = num_cache[0];
|
||||
script_callee(gamepad_callee,3,argv);
|
||||
|
||||
if (!joysticks[i].state.buttons[b]) {
|
||||
argv[2] = num_cache[1];
|
||||
script_callee(gamepad_callee,3,argv);
|
||||
}
|
||||
}
|
||||
else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
||||
argv[2] = num_cache[2];
|
||||
script_callee(gamepad_callee,3,argv);
|
||||
}
|
||||
JSValue argv[4];
|
||||
argv[0] = num_cache[joysticks[i].id];
|
||||
for (int b = 0; b < 15; b++) {
|
||||
argv[1] = jsgamepadstr[b];
|
||||
|
||||
if (state.buttons[b]) {
|
||||
argv[2] = num_cache[0];
|
||||
script_callee(gamepad_callee, 3, argv);
|
||||
|
||||
if (!joysticks[i].state.buttons[b]) {
|
||||
argv[2] = num_cache[1];
|
||||
script_callee(gamepad_callee, 3, argv);
|
||||
}
|
||||
} else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
||||
argv[2] = num_cache[2];
|
||||
script_callee(gamepad_callee, 3, argv);
|
||||
}
|
||||
|
||||
argv[2] = jsaxis;
|
||||
|
||||
float deadzone = 0.05;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
state.axes[i] = fabs(state.axes[i]) > deadzone ? state.axes[i] : 0;
|
||||
|
||||
argv[1] = jsaxesstr[0];
|
||||
cpVect v;
|
||||
v.x = state.axes[0];
|
||||
v.y = -state.axes[1];
|
||||
argv[3] = vec2js(v);
|
||||
script_callee(gamepad_callee,4,argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[1];
|
||||
v.x = state.axes[2];
|
||||
v.y = -state.axes[3];
|
||||
argv[3] = vec2js(v);
|
||||
script_callee(gamepad_callee,4,argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[2];
|
||||
argv[3] = num2js((state.axes[4]+1)/2);
|
||||
script_callee(gamepad_callee,4,argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[3];
|
||||
argv[3] = num2js((state.axes[5]+1)/2);
|
||||
script_callee(gamepad_callee,4,argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
joysticks[i].state = state;
|
||||
}
|
||||
|
||||
argv[2] = jsaxis;
|
||||
|
||||
float deadzone = 0.05;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
state.axes[i] = fabs(state.axes[i]) > deadzone ? state.axes[i] : 0;
|
||||
|
||||
argv[1] = jsaxesstr[0];
|
||||
cpVect v;
|
||||
v.x = state.axes[0];
|
||||
v.y = -state.axes[1];
|
||||
argv[3] = vec2js(v);
|
||||
script_callee(gamepad_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[1];
|
||||
v.x = state.axes[2];
|
||||
v.y = -state.axes[3];
|
||||
argv[3] = vec2js(v);
|
||||
script_callee(gamepad_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[2];
|
||||
argv[3] = num2js((state.axes[4] + 1) / 2);
|
||||
script_callee(gamepad_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
argv[1] = jsaxesstr[3];
|
||||
argv[3] = num2js((state.axes[5] + 1) / 2);
|
||||
script_callee(gamepad_callee, 4, argv);
|
||||
JS_FreeValue(js, argv[3]);
|
||||
|
||||
joysticks[i].state = state;
|
||||
}
|
||||
}
|
||||
|
||||
int key_is_num(int key) {
|
||||
return key <= 57 && key >= 48;
|
||||
}
|
||||
|
||||
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods)
|
||||
{
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = input2js(keyname_extd(key,scancode));
|
||||
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) {
|
||||
JSValue argv[3];
|
||||
argv[0] = jsinput;
|
||||
argv[1] = input2js(keyname_extd(key, scancode));
|
||||
|
||||
switch (action) {
|
||||
case GLFW_PRESS:
|
||||
argv[2] = jsinputstate[2];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
argv[2] = jsinputstate[3];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
add_downkey(key);
|
||||
argv[1] = jsany;
|
||||
argv[2] = jsinputstate[2];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
|
||||
if (key_is_num(key))
|
||||
pawn_call_keydown(key-48);
|
||||
|
||||
break;
|
||||
switch (action) {
|
||||
case GLFW_PRESS:
|
||||
argv[2] = jsinputstate[2];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
argv[2] = jsinputstate[3];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
add_downkey(key);
|
||||
argv[1] = jsany;
|
||||
argv[2] = jsinputstate[2];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
|
||||
case GLFW_RELEASE:
|
||||
argv[2] = jsinputstate[0];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
rm_downkey(key);
|
||||
argv[1] = jsany;
|
||||
script_callee(pawn_callee,3,argv);
|
||||
break;
|
||||
if (key_is_num(key))
|
||||
pawn_call_keydown(key - 48);
|
||||
|
||||
case GLFW_REPEAT:
|
||||
argv[2] = jsinputstate[1];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
argv[2] = jsinputstate[3];
|
||||
script_callee(pawn_callee,3,argv);
|
||||
break;
|
||||
break;
|
||||
|
||||
case GLFW_RELEASE:
|
||||
argv[2] = jsinputstate[0];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
rm_downkey(key);
|
||||
argv[1] = jsany;
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
break;
|
||||
|
||||
case GLFW_REPEAT:
|
||||
argv[2] = jsinputstate[1];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
argv[2] = jsinputstate[3];
|
||||
script_callee(pawn_callee, 3, argv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cursor_hide() {
|
||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
|
||||
void cursor_show() {
|
||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
|
||||
int action_down(int scancode) {
|
||||
for (int i = 0; i < arrlen(downkeys); i++) {
|
||||
if (downkeys[i] == scancode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_up(int scancode) {
|
||||
int found = 0;
|
||||
for (int i = 0; i < arrlen(downkeys); i++) {
|
||||
if (downkeys[i] == scancode) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cursor_hide()
|
||||
{
|
||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
|
||||
void cursor_show()
|
||||
{
|
||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
|
||||
int action_down(int scancode)
|
||||
{
|
||||
for (int i = 0; i < arrlen(downkeys); i++) {
|
||||
if (downkeys[i] == scancode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_up(int scancode)
|
||||
{
|
||||
int found = 0;
|
||||
for (int i = 0; i < arrlen(downkeys); i++) {
|
||||
if (downkeys[i] == scancode) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !found;
|
||||
return !found;
|
||||
}
|
||||
|
||||
int want_quit() {
|
||||
return mquit;
|
||||
return mquit;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
YughInfo("Exiting game.");
|
||||
mquit = 1;
|
||||
YughInfo("Exiting game.");
|
||||
mquit = 1;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "script.h"
|
||||
#include "window.h"
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include "script.h"
|
||||
#include <stdint.h>
|
||||
|
||||
extern int32_t mouseWheelX;
|
||||
extern int32_t mouseWheelY;
|
||||
|
@ -33,9 +33,8 @@ void quit();
|
|||
|
||||
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods);
|
||||
|
||||
struct inputaction
|
||||
{
|
||||
int scancode;
|
||||
struct inputaction {
|
||||
int scancode;
|
||||
};
|
||||
|
||||
void input_to_nuke();
|
||||
|
|
|
@ -1,53 +1,49 @@
|
|||
#include "level.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gameobject.h"
|
||||
#include "resources.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stb_ds.h"
|
||||
|
||||
void save_level(char name[MAXNAME])
|
||||
{
|
||||
FILE *lfile = res_open(name, "wb+");
|
||||
void save_level(char name[MAXNAME]) {
|
||||
FILE *lfile = res_open(name, "wb+");
|
||||
|
||||
if (!lfile) return;
|
||||
if (!lfile) return;
|
||||
|
||||
int objs = arrlen(gameobjects);
|
||||
fwrite(&objs, sizeof(objs), 1, lfile);
|
||||
|
||||
int objs = arrlen(gameobjects);
|
||||
fwrite(&objs, sizeof(objs), 1, lfile);
|
||||
|
||||
fclose(lfile);
|
||||
fclose(lfile);
|
||||
}
|
||||
|
||||
void load_level(char name[MAXNAME])
|
||||
{
|
||||
/*
|
||||
FILE *lfile = fopen(name, "rb");
|
||||
void load_level(char name[MAXNAME]) {
|
||||
/*
|
||||
FILE *lfile = fopen(name, "rb");
|
||||
|
||||
if (!lfile) return;
|
||||
if (!lfile) return;
|
||||
|
||||
new_level();
|
||||
new_level();
|
||||
|
||||
int objs;
|
||||
fread(&objs, sizeof(objs), 1, lfile);
|
||||
int objs;
|
||||
fread(&objs, sizeof(objs), 1, lfile);
|
||||
|
||||
arraddn(gameobjects, objs);
|
||||
arraddn(gameobjects, objs);
|
||||
|
||||
for (int i = 0; i < objs; i++) {
|
||||
struct gameobject *go = &gameobjects[i];
|
||||
fread(go, sizeof(struct gameobject), 1, lfile);
|
||||
go->components = NULL;
|
||||
gameobject_init(go, lfile);
|
||||
}
|
||||
for (int i = 0; i < objs; i++) {
|
||||
struct gameobject *go = &gameobjects[i];
|
||||
fread(go, sizeof(struct gameobject), 1, lfile);
|
||||
go->components = NULL;
|
||||
gameobject_init(go, lfile);
|
||||
}
|
||||
|
||||
fclose(lfile);
|
||||
*/
|
||||
fclose(lfile);
|
||||
*/
|
||||
}
|
||||
|
||||
void new_level()
|
||||
{
|
||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||
gameobject_delete(i);
|
||||
void new_level() {
|
||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||
gameobject_delete(i);
|
||||
|
||||
arrfree(gameobjects);
|
||||
arrfree(gameobjects);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
// This class holds all of the entities and options for a level. Really it's nothing more than a container and access point for all the entities currently loaded into the game.
|
||||
|
||||
struct level {
|
||||
char name[MAXNAME];
|
||||
char name[MAXNAME];
|
||||
};
|
||||
|
||||
void save_level(char name[MAXNAME]);
|
||||
void load_level(char name[MAXNAME]);
|
||||
void new_level();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
10632
source/engine/mathc.c
10632
source/engine/mathc.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,155 +1,147 @@
|
|||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_INCLUDE_STANDARD_BOOL
|
||||
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_GLFW_GL3_IMPLEMENTATION
|
||||
#define NK_KEYSTATE_BASED_INPUT
|
||||
|
||||
#define STBTT_STATIC
|
||||
|
||||
#include "nuke.h"
|
||||
#include "nuklear_glfw_gl3.h"
|
||||
|
||||
#define SOKOL_GLCORE33
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
#define SOKOL_NUKLEAR_NO_SOKOL_APP
|
||||
#define SOKOL_NUKLEAR_IMPL
|
||||
|
||||
#include "sokol/sokol_nuklear.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "window.h"
|
||||
#include "texture.h"
|
||||
#include "log.h"
|
||||
#include "texture.h"
|
||||
#include "window.h"
|
||||
|
||||
#define MAX_VERTEX_BUFFER 512 * 1024
|
||||
#define MAX_ELEMENT_BUFFER 128 * 1024
|
||||
|
||||
struct nk_context *ctx;
|
||||
static struct nk_glfw nkglfw = {0};
|
||||
|
||||
//static struct nk_glfw nkglfw = {0};
|
||||
|
||||
void nuke_init(struct window *win) {
|
||||
window_makecurrent(win);
|
||||
|
||||
ctx = nk_glfw3_init(&nkglfw, win->window, NK_GLFW3_INSTALL_CALLBACKS);
|
||||
|
||||
struct nk_font_atlas *atlas;
|
||||
nk_glfw3_font_stash_begin(&nkglfw, &atlas);
|
||||
struct nk_font *noto = nk_font_atlas_add_from_file(atlas, "fonts/teenytinypixels.tff", 14, 0);
|
||||
nk_glfw3_font_stash_end(&nkglfw);
|
||||
window_makecurrent(win);
|
||||
|
||||
snk_setup(&(snk_desc_t){
|
||||
.no_default_font = false
|
||||
});
|
||||
}
|
||||
|
||||
void nuke_start()
|
||||
{
|
||||
nk_glfw3_new_frame(&nkglfw);
|
||||
void nuke_start() {
|
||||
ctx = snk_new_frame();
|
||||
}
|
||||
|
||||
void nuke_end()
|
||||
{
|
||||
nk_glfw3_render(&nkglfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER);
|
||||
void nuke_end() {
|
||||
snk_render(1200,720);
|
||||
}
|
||||
|
||||
|
||||
int nuke_begin(const char *lbl, struct nk_rect rect, int flags) {
|
||||
return nk_begin(ctx, lbl, rect, flags);
|
||||
return nk_begin(ctx, lbl, rect, flags);
|
||||
}
|
||||
|
||||
int nuke_begin_win(const char *lbl)
|
||||
{
|
||||
int nuke_begin_win(const char *lbl) {
|
||||
return nk_begin(ctx, lbl, nk_rect(10, 10, 400, 600), NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_TITLE);
|
||||
}
|
||||
|
||||
void nuke_stop() {
|
||||
nk_end(ctx);
|
||||
nk_end(ctx);
|
||||
}
|
||||
|
||||
struct nk_rect nuke_win_get_bounds() {
|
||||
return nk_window_get_bounds(ctx);
|
||||
return nk_window_get_bounds(ctx);
|
||||
}
|
||||
|
||||
void nuke_row(int height)
|
||||
{
|
||||
void nuke_row(int height) {
|
||||
nk_layout_row_dynamic(ctx, height, 1);
|
||||
}
|
||||
|
||||
void nuke_property_float3(const char *label, float min, float *val, float max, float step, float dragstep) {
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 3);
|
||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
||||
nuke_property_float("#Z", min, &val[2], max, step, dragstep);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 3);
|
||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
||||
nuke_property_float("#Z", min, &val[2], max, step, dragstep);
|
||||
}
|
||||
|
||||
void nuke_property_float2(const char *label, float min, float *val, float max, float step, float dragstep) {
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 2);
|
||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 2);
|
||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
||||
}
|
||||
|
||||
void nuke_property_float(const char *lbl, float min, float *val, float max, float step, float dragstep) {
|
||||
nk_property_float(ctx, lbl, min, val, max, step, dragstep);
|
||||
nk_property_float(ctx, lbl, min, val, max, step, dragstep);
|
||||
}
|
||||
|
||||
int nuke_btn(const char *lbl) {
|
||||
return nk_button_label(ctx, lbl);
|
||||
return nk_button_label(ctx, lbl);
|
||||
}
|
||||
|
||||
void nuke_img(char *path) {
|
||||
/*
|
||||
struct Texture *t = texture_pullfromfile(path);
|
||||
nk_layout_row_static(ctx, t->height, t->width, 1);
|
||||
nk_image(ctx, nk_image_id(t->id));
|
||||
*/
|
||||
/*
|
||||
struct Texture *t = texture_pullfromfile(path);
|
||||
nk_layout_row_static(ctx, t->height, t->width, 1);
|
||||
nk_image(ctx, nk_image_id(t->id));
|
||||
*/
|
||||
}
|
||||
|
||||
void nuke_property_int(const char *lbl, int min, int *val, int max, int step) {
|
||||
nk_property_int(ctx, lbl, min, val, max, step, step);
|
||||
nk_property_int(ctx, lbl, min, val, max, step, step);
|
||||
}
|
||||
|
||||
void nuke_radio_btn(const char *lbl, int *val, int cmp) {
|
||||
if (nk_option_label(ctx, lbl, *val==cmp)) *val = cmp;
|
||||
if (nk_option_label(ctx, lbl, *val == cmp)) *val = cmp;
|
||||
}
|
||||
|
||||
void nuke_checkbox(const char *lbl, int *val) {
|
||||
nk_checkbox_label(ctx, lbl, val);
|
||||
nk_checkbox_label(ctx, lbl, val);
|
||||
}
|
||||
|
||||
void nuke_scrolltext(char *str)
|
||||
{
|
||||
nk_edit_string_zero_terminated(ctx, NK_EDIT_MULTILINE|NK_EDIT_GOTO_END_ON_ACTIVATE, str, 1024*1024*5, NULL);
|
||||
void nuke_scrolltext(char *str) {
|
||||
nk_edit_string_zero_terminated(ctx, NK_EDIT_MULTILINE | NK_EDIT_GOTO_END_ON_ACTIVATE, str, 1024 * 1024 * 5, NULL);
|
||||
}
|
||||
|
||||
void nuke_nel(int cols) {
|
||||
nk_layout_row_dynamic(ctx, 25, cols);
|
||||
nk_layout_row_dynamic(ctx, 25, cols);
|
||||
}
|
||||
|
||||
void nuke_nel_h(int cols, int h) {
|
||||
nk_layout_row_dynamic(ctx, h, cols);
|
||||
nk_layout_row_dynamic(ctx, h, cols);
|
||||
}
|
||||
|
||||
void nuke_label(const char *s) {
|
||||
nk_label(ctx, s, NK_TEXT_LEFT);
|
||||
nk_label(ctx, s, NK_TEXT_LEFT);
|
||||
}
|
||||
|
||||
void nuke_edit_str(char *str) {
|
||||
nk_edit_string_zero_terminated(ctx, NK_EDIT_BOX|NK_EDIT_NO_HORIZONTAL_SCROLL, str, 130, nk_filter_ascii);
|
||||
nk_edit_string_zero_terminated(ctx, NK_EDIT_BOX | NK_EDIT_NO_HORIZONTAL_SCROLL, str, 130, nk_filter_ascii);
|
||||
}
|
||||
|
||||
int nuke_push_tree_id(const char *name, int id) {
|
||||
return nk_tree_push_id(ctx, NK_TREE_NODE, name, NK_MINIMIZED, id);
|
||||
return nk_tree_push_id(ctx, NK_TREE_NODE, name, NK_MINIMIZED, id);
|
||||
}
|
||||
|
||||
void nuke_tree_pop() {
|
||||
nk_tree_pop(ctx);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
|
||||
void nuke_labelf(const char *fmt, ...) {
|
||||
char buf[512];
|
||||
char buf[512];
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, 512, fmt, args);
|
||||
nuke_label(buf);
|
||||
va_end(args);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, 512, fmt, args);
|
||||
nuke_label(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
#ifndef NUKE_H
|
||||
#define NUKE_H
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_INCLUDE_STANDARD_BOOL
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
|
||||
#include "nuklear.h"
|
||||
|
||||
struct window;
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
#include "openglrender.h"
|
||||
|
||||
#include "sprite.h"
|
||||
#include "shader.h"
|
||||
#include "font.h"
|
||||
#include "config.h"
|
||||
#include "gameobject.h"
|
||||
#include "camera.h"
|
||||
#include "window.h"
|
||||
#include "debugdraw.h"
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "datastream.h"
|
||||
#include "debugdraw.h"
|
||||
#include "font.h"
|
||||
#include "gameobject.h"
|
||||
#include "log.h"
|
||||
#include "nuke.h"
|
||||
#include "shader.h"
|
||||
#include "sprite.h"
|
||||
#include "window.h"
|
||||
#include "model.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
int renderMode = LIT;
|
||||
|
||||
|
@ -19,13 +23,13 @@ struct shader *wireframeShader = NULL;
|
|||
struct shader *animSpriteShader = NULL;
|
||||
static struct shader *textShader;
|
||||
|
||||
mfloat_t editorClearColor[4] = { 0.2f, 0.4f, 0.3f, 1.f };
|
||||
mfloat_t editorClearColor[4] = {0.2f, 0.4f, 0.3f, 1.f};
|
||||
|
||||
float shadowLookahead = 8.5f;
|
||||
|
||||
mfloat_t gridSmallColor[3] = { 0.35f, 1.f, 0.9f };
|
||||
mfloat_t gridSmallColor[3] = {0.35f, 1.f, 0.9f};
|
||||
|
||||
mfloat_t gridBigColor[3] = { 0.92f, 0.92f, 0.68f };
|
||||
mfloat_t gridBigColor[3] = {0.92f, 0.92f, 0.68f};
|
||||
|
||||
float gridScale = 500.f;
|
||||
float smallGridUnit = 1.f;
|
||||
|
@ -50,130 +54,263 @@ bool renderReflection = true;
|
|||
|
||||
///// for editing
|
||||
struct gameobject *selectedobject = NULL;
|
||||
char objectName[200] = { '\0' }; // object name buffer
|
||||
char objectName[200] = {'\0'}; // object name buffer
|
||||
|
||||
struct sprite *tsprite = NULL;
|
||||
|
||||
const char *donquixote;
|
||||
|
||||
static struct model *duck;
|
||||
|
||||
sg_image ddimg;
|
||||
|
||||
void debug_draw_phys(int draw) {
|
||||
debugDrawPhysics = draw;
|
||||
debugDrawPhysics = draw;
|
||||
}
|
||||
|
||||
void opengl_rendermode(enum RenderMode r)
|
||||
{
|
||||
void opengl_rendermode(enum RenderMode r) {
|
||||
renderMode = r;
|
||||
}
|
||||
|
||||
sg_pipeline mainpip;
|
||||
sg_pass_action pass_action = {0};
|
||||
|
||||
void openglInit()
|
||||
{
|
||||
if (!mainwin) {
|
||||
YughError("No window to init OpenGL on.", 1);
|
||||
exit(1);
|
||||
static struct {
|
||||
sg_pass_action pass_action;
|
||||
sg_pass pass;
|
||||
sg_pipeline pipe;
|
||||
sg_shader shader;
|
||||
} sg_shadow;
|
||||
|
||||
static struct {
|
||||
sg_shader shader;
|
||||
sg_pipeline pipe;
|
||||
sg_bindings bind;
|
||||
sg_pass pass;
|
||||
sg_image img;
|
||||
sg_image depth_img;
|
||||
} crt_post;
|
||||
|
||||
|
||||
void openglInit() {
|
||||
if (!mainwin) {
|
||||
YughError("No window to init OpenGL on.", 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
font_init(NULL);
|
||||
debugdraw_init();
|
||||
sprite_initialize();
|
||||
nuke_init(mainwin);
|
||||
|
||||
model_init();
|
||||
// duck = MakeModel("sponza.glb");
|
||||
|
||||
pass_action = (sg_pass_action){
|
||||
.colors[0] = {.action = SG_ACTION_CLEAR, .value = {editorClearColor[1], editorClearColor[2], editorClearColor[3], 1.f}},
|
||||
};
|
||||
|
||||
crt_post.shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/postvert.glsl"),
|
||||
.fs.source = slurp_text("shaders/crtfrag.glsl"),
|
||||
|
||||
.fs.images[0] = {
|
||||
.name = "diffuse_texture",
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.sampler_type = SG_SAMPLERTYPE_FLOAT
|
||||
}
|
||||
});
|
||||
|
||||
// donquixote = slurp_text("quixote.txt");
|
||||
crt_post.pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = crt_post.shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////// MAKE SHADERS
|
||||
spriteShader = MakeShader("spritevert.glsl", "spritefrag.glsl");
|
||||
wireframeShader = MakeShader("spritevert.glsl", "spritewireframefrag.glsl");
|
||||
animSpriteShader = MakeShader("animspritevert.glsl", "animspritefrag.glsl");
|
||||
textShader = MakeShader("textvert.glsl", "textfrag.glsl");
|
||||
crt_post.img = sg_make_image(&(sg_image_desc){
|
||||
.render_target = true,
|
||||
.width = 1200,
|
||||
.height = 720,
|
||||
});
|
||||
|
||||
font_init(textShader);
|
||||
sprite_initialize();
|
||||
debugdraw_init();
|
||||
crt_post.depth_img = sg_make_image(&(sg_image_desc){
|
||||
.render_target = true,
|
||||
.width = 1200,
|
||||
.height = 720,
|
||||
.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL
|
||||
});
|
||||
|
||||
glClearColor(editorClearColor[0], editorClearColor[1], editorClearColor[2], editorClearColor[3]);
|
||||
crt_post.pass = sg_make_pass(&(sg_pass_desc){
|
||||
.color_attachments[0].image = crt_post.img,
|
||||
.depth_stencil_attachment.image = crt_post.depth_img,
|
||||
});
|
||||
|
||||
float crt_quad[] = {
|
||||
-1, 1, 0, 1,
|
||||
-1, -1, 0, 0,
|
||||
1, -1, 1, 0,
|
||||
-1, 1, 0, 1,
|
||||
1, -1, 1, 0,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
|
||||
crt_post.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(crt_quad),
|
||||
.data = crt_quad
|
||||
});
|
||||
|
||||
crt_post.bind.fs_images[0] = crt_post.img;
|
||||
|
||||
/*
|
||||
glCullFace(GL_BACK);
|
||||
sg_image_desc shadow_desc = {
|
||||
.render_target = true,
|
||||
.width = 1024,
|
||||
.height = 1024,
|
||||
.pixel_format = SG_PIXELFORMAT_R32F,
|
||||
};
|
||||
sg_image depth_img = sg_make_image(&shadow_desc);
|
||||
shadow_desc.pixel_format = SG_PIXELFORMAT_DEPTH;
|
||||
ddimg = sg_make_image(&shadow_desc);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
duck = MakeModel("sponza.glb");
|
||||
|
||||
sg_shadow.pass = sg_make_pass(&(sg_pass_desc){
|
||||
.color_attachments[0].image = depth_img,
|
||||
.depth_stencil_attachment.image = ddimg,
|
||||
});
|
||||
|
||||
sg_shadow.pass_action = (sg_pass_action) {
|
||||
.colors[0] = { .action=SG_ACTION_CLEAR, .value = {1,1,1,1} } };
|
||||
|
||||
glGenBuffers(1, &projUBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, projUBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, 64, NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, 0, projUBO, 0, sizeof(float) * 16);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
sg_shadow.shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/shadowvert.glsl"),
|
||||
.fs.source = slurp_text("shaders/shadowfrag.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = sizeof(float) * 16 * 2,
|
||||
.uniforms = {
|
||||
[0] = {.name = "lightSpaceMatrix", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[1] = {.name = "model", .type = SG_UNIFORMTYPE_MAT4},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
shader_setUBO(spriteShader, "Projection", 0);
|
||||
shader_setUBO(textShader, "Projection", 0);
|
||||
shader_setUBO(animSpriteShader, "Projection", 0);
|
||||
sg_shadow.pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = sg_shadow.shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
}
|
||||
},
|
||||
.depth = {
|
||||
.compare = SG_COMPAREFUNC_LESS_EQUAL,
|
||||
.write_enabled = true,
|
||||
.pixel_format = SG_PIXELFORMAT_DEPTH
|
||||
},
|
||||
.colors[0].pixel_format = SG_PIXELFORMAT_R32F,
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_BACK,
|
||||
});
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
static cpBody *camera = NULL;
|
||||
void set_cam_body(cpBody *body) {
|
||||
camera = body;
|
||||
camera = body;
|
||||
}
|
||||
|
||||
cpVect cam_pos() {
|
||||
return camera ? cpBodyGetPosition(camera) : cpvzero;
|
||||
return camera ? cpBodyGetPosition(camera) : cpvzero;
|
||||
}
|
||||
|
||||
static float zoom = 1.f;
|
||||
float cam_zoom() { return zoom; }
|
||||
|
||||
|
||||
void add_zoom(float val) { zoom = val; }
|
||||
|
||||
mfloat_t projection[16] = {0.f};
|
||||
|
||||
void openglRender(struct window *window)
|
||||
{
|
||||
sg_begin_default_pass(&pass_action, window->width, window->height);
|
||||
HMM_Vec3 dirl_pos = {4, 100, 20};
|
||||
|
||||
//////////// 2D projection
|
||||
cpVect pos = cam_pos();
|
||||
void openglRender(struct window *window) {
|
||||
/*
|
||||
HMM_Mat4 model = HMM_M4D(1.f);
|
||||
float scale = 0.08;
|
||||
model = HMM_MulM4(model, HMM_Scale((HMM_Vec3){scale,scale,scale}));
|
||||
|
||||
mat4_ortho(projection, pos.x - zoom*window->width/2,
|
||||
pos.x + zoom*window->width/2,
|
||||
pos.y - zoom*window->height/2,
|
||||
pos.y + zoom*window->height/2, -1.f, 1.f);
|
||||
|
||||
mfloat_t ui_projection[16] = { 0.f };
|
||||
mat4_ortho(ui_projection, 0,
|
||||
window->width,
|
||||
0,
|
||||
window->height, -1.f, 1.f);
|
||||
// Shadow pass
|
||||
sg_begin_pass(sg_shadow.pass, &sg_shadow.pass_action);
|
||||
sg_apply_pipeline(sg_shadow.pipe);
|
||||
|
||||
sprite_draw_all();
|
||||
gui_draw_img("pill1.png", 200, 200);
|
||||
float a[2] = {100,100};
|
||||
float w[3] = {1.f,1.f,1.f};
|
||||
renderText("TEST RENDER", a, 1.f, w, 0,-1);
|
||||
|
||||
float b[2] = {50,50};
|
||||
renderText("TEST @@@@ RENDER", b, 1.f, w, 0,-1);
|
||||
HMM_Mat4 light_proj = HMM_Orthographic_RH_ZO(-100.f, 100.f, -100.f, 100.f, 1.f, 100.f);
|
||||
HMM_Mat4 light_view = HMM_LookAt_RH(dirl_pos, (HMM_Vec3){0,0,0}, (HMM_Vec3){0,1,0});
|
||||
|
||||
/* UI Elements & Debug elements */
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
// glDisable(GL_DEPTH_TEST);
|
||||
//// DEBUG
|
||||
// if (debugDrawPhysics)
|
||||
// gameobject_draw_debugs();
|
||||
HMM_Mat4 lsm = HMM_MulM4(light_proj, light_view);
|
||||
|
||||
// call_debugs();
|
||||
HMM_Mat4 subo[2];
|
||||
subo[0] = lsm;
|
||||
subo[1] = model;
|
||||
|
||||
////// TEXT && GUI
|
||||
// glBindBuffer(GL_UNIFORM_BUFFER, projUBO);
|
||||
// glBufferSubData(GL_UNIFORM_BUFFER, 0, 64, ui_projection);
|
||||
text_flush();
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(subo));
|
||||
|
||||
for (int i = 0; i < arrlen(duck->meshes); i++) {
|
||||
sg_bindings sbind = {0};
|
||||
sbind.vertex_buffers[0] = duck->meshes[i].bind.vertex_buffers[0];
|
||||
sbind.index_buffer = duck->meshes[i].bind.index_buffer;
|
||||
sg_apply_bindings(&sbind);
|
||||
sg_draw(0,duck->meshes[i].face_count,1);
|
||||
}
|
||||
sg_end_pass();
|
||||
|
||||
// call_gui();
|
||||
draw_model(duck,model, lsm);
|
||||
*/
|
||||
|
||||
// nuke_start();
|
||||
// call_nk_gui();
|
||||
// nuke_end();
|
||||
// sg_begin_default_pass(&pass_action, window->width, window->height);
|
||||
sg_begin_pass(crt_post.pass, &pass_action);
|
||||
|
||||
//////////// 2D projection
|
||||
cpVect pos = cam_pos();
|
||||
|
||||
mat4_ortho(projection, pos.x - zoom * window->width / 2,
|
||||
pos.x + zoom * window->width / 2,
|
||||
pos.y - zoom * window->height / 2,
|
||||
pos.y + zoom * window->height / 2, -1.f, 1.f);
|
||||
|
||||
mfloat_t ui_projection[16] = {0.f};
|
||||
mat4_ortho(ui_projection, 0, window->width, 0, window->height, -1.f, 1.f);
|
||||
|
||||
sprite_draw_all();
|
||||
sprite_flush();
|
||||
|
||||
//// DEBUG
|
||||
if (debugDrawPhysics)
|
||||
gameobject_draw_debugs();
|
||||
|
||||
call_debugs();
|
||||
debug_flush();
|
||||
|
||||
////// TEXT && GUI
|
||||
call_gui();
|
||||
|
||||
text_flush();
|
||||
|
||||
nuke_start();
|
||||
call_nk_gui();
|
||||
nuke_end();
|
||||
|
||||
sg_end_pass();
|
||||
sg_commit();
|
||||
|
||||
sg_begin_default_pass(&pass_action, window->width, window->height);
|
||||
sg_apply_pipeline(crt_post.pipe);
|
||||
sg_apply_bindings(&crt_post.bind);
|
||||
sg_draw(0,6,1);
|
||||
sg_end_pass();
|
||||
|
||||
|
||||
sprite_flush();
|
||||
sg_commit();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
#ifndef OPENGL_RENDER_H
|
||||
#define OPENGL_RENDER_H
|
||||
|
||||
#include "sokol/sokol_gfx.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
struct mCamera;
|
||||
struct window;
|
||||
|
||||
extern struct shader *spriteShader;
|
||||
extern struct shader *animSpriteShader;
|
||||
|
||||
extern sg_image ddimg;
|
||||
|
||||
extern struct sprite *tsprite;
|
||||
|
||||
extern int renderMode;
|
||||
|
||||
extern HMM_Vec3 dirl_pos;
|
||||
|
||||
extern float projection[16];
|
||||
|
||||
extern float gridScale;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,8 +27,7 @@
|
|||
#define parson_parson_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
} /* unconfuse xcode */
|
||||
|
@ -40,32 +39,32 @@ extern "C"
|
|||
|
||||
#define PARSON_VERSION_STRING "1.4.0"
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
/* Types and enums */
|
||||
typedef struct json_object_t JSON_Object;
|
||||
typedef struct json_array_t JSON_Array;
|
||||
typedef struct json_value_t JSON_Value;
|
||||
typedef struct json_array_t JSON_Array;
|
||||
typedef struct json_value_t JSON_Value;
|
||||
|
||||
enum json_value_type {
|
||||
JSONError = -1,
|
||||
JSONNull = 1,
|
||||
JSONString = 2,
|
||||
JSONNumber = 3,
|
||||
JSONObject = 4,
|
||||
JSONArray = 5,
|
||||
JSONBoolean = 6
|
||||
JSONError = -1,
|
||||
JSONNull = 1,
|
||||
JSONString = 2,
|
||||
JSONNumber = 3,
|
||||
JSONObject = 4,
|
||||
JSONArray = 5,
|
||||
JSONBoolean = 6
|
||||
};
|
||||
typedef int JSON_Value_Type;
|
||||
|
||||
enum json_result_t {
|
||||
JSONSuccess = 0,
|
||||
JSONFailure = -1
|
||||
JSONSuccess = 0,
|
||||
JSONFailure = -1
|
||||
};
|
||||
typedef int JSON_Status;
|
||||
|
||||
typedef void * (*JSON_Malloc_Function)(size_t);
|
||||
typedef void (*JSON_Free_Function)(void *);
|
||||
typedef void *(*JSON_Malloc_Function)(size_t);
|
||||
typedef void (*JSON_Free_Function)(void *);
|
||||
|
||||
/* Call only once, before calling any other function from parson API. If not called, malloc and free
|
||||
from stdlib will be used for all allocations */
|
||||
|
@ -81,35 +80,35 @@ void json_set_escape_slashes(int escape_slashes);
|
|||
void json_set_float_serialization_format(const char *format);
|
||||
|
||||
/* Parses first JSON value in a file, returns NULL in case of error */
|
||||
JSON_Value * json_parse_file(const char *filename);
|
||||
JSON_Value *json_parse_file(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a file and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_file_with_comments(const char *filename);
|
||||
JSON_Value *json_parse_file_with_comments(const char *filename);
|
||||
|
||||
/* Parses first JSON value in a string, returns NULL in case of error */
|
||||
JSON_Value * json_parse_string(const char *string);
|
||||
JSON_Value *json_parse_string(const char *string);
|
||||
|
||||
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_Value * json_parse_string_with_comments(const char *string);
|
||||
JSON_Value *json_parse_string_with_comments(const char *string);
|
||||
|
||||
/* Serialization */
|
||||
size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */
|
||||
size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */
|
||||
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename);
|
||||
char * json_serialize_to_string(const JSON_Value *value);
|
||||
char *json_serialize_to_string(const JSON_Value *value);
|
||||
|
||||
/* Pretty serialization */
|
||||
size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */
|
||||
size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */
|
||||
JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||
JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename);
|
||||
char * json_serialize_to_string_pretty(const JSON_Value *value);
|
||||
char *json_serialize_to_string_pretty(const JSON_Value *value);
|
||||
|
||||
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
|
||||
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
|
||||
|
||||
/* Comparing */
|
||||
int json_value_equals(const JSON_Value *a, const JSON_Value *b);
|
||||
int json_value_equals(const JSON_Value *a, const JSON_Value *b);
|
||||
|
||||
/* Validation
|
||||
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
||||
|
@ -126,45 +125,45 @@ JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value);
|
|||
/*
|
||||
* JSON Object
|
||||
*/
|
||||
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name);
|
||||
const char * json_object_get_string (const JSON_Object *object, const char *name);
|
||||
size_t json_object_get_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object * json_object_get_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_get_array (const JSON_Object *object, const char *name);
|
||||
double json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
JSON_Value *json_object_get_value(const JSON_Object *object, const char *name);
|
||||
const char *json_object_get_string(const JSON_Object *object, const char *name);
|
||||
size_t json_object_get_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object *json_object_get_object(const JSON_Object *object, const char *name);
|
||||
JSON_Array *json_object_get_array(const JSON_Object *object, const char *name);
|
||||
double json_object_get_number(const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* dotget functions enable addressing values with dot notation in nested objects,
|
||||
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
|
||||
Because valid names in JSON can contain dots, some values may be inaccessible
|
||||
this way. */
|
||||
JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *name);
|
||||
const char * json_object_dotget_string (const JSON_Object *object, const char *name);
|
||||
size_t json_object_dotget_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name);
|
||||
JSON_Array * json_object_dotget_array (const JSON_Object *object, const char *name);
|
||||
double json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
JSON_Value *json_object_dotget_value(const JSON_Object *object, const char *name);
|
||||
const char *json_object_dotget_string(const JSON_Object *object, const char *name);
|
||||
size_t json_object_dotget_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */
|
||||
JSON_Object *json_object_dotget_object(const JSON_Object *object, const char *name);
|
||||
JSON_Array *json_object_dotget_array(const JSON_Object *object, const char *name);
|
||||
double json_object_dotget_number(const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||
|
||||
/* Functions to get available names */
|
||||
size_t json_object_get_count (const JSON_Object *object);
|
||||
const char * json_object_get_name (const JSON_Object *object, size_t index);
|
||||
JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index);
|
||||
JSON_Value * json_object_get_wrapping_value(const JSON_Object *object);
|
||||
size_t json_object_get_count(const JSON_Object *object);
|
||||
const char *json_object_get_name(const JSON_Object *object, size_t index);
|
||||
JSON_Value *json_object_get_value_at(const JSON_Object *object, size_t index);
|
||||
JSON_Value *json_object_get_wrapping_value(const JSON_Object *object);
|
||||
|
||||
/* Functions to check if object has a value with a specific name. Returned value is 1 if object has
|
||||
* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */
|
||||
int json_object_has_value (const JSON_Object *object, const char *name);
|
||||
int json_object_has_value(const JSON_Object *object, const char *name);
|
||||
int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
|
||||
|
||||
int json_object_dothas_value (const JSON_Object *object, const char *name);
|
||||
int json_object_dothas_value(const JSON_Object *object, const char *name);
|
||||
int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type);
|
||||
|
||||
/* Creates new name-value pair or frees and replaces old value with a new one.
|
||||
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string);
|
||||
JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number);
|
||||
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean);
|
||||
JSON_Status json_object_set_null(JSON_Object *object, const char *name);
|
||||
|
@ -190,15 +189,15 @@ JSON_Status json_object_clear(JSON_Object *object);
|
|||
/*
|
||||
*JSON Array
|
||||
*/
|
||||
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index);
|
||||
const char * json_array_get_string (const JSON_Array *array, size_t index);
|
||||
size_t json_array_get_string_len(const JSON_Array *array, size_t index); /* doesn't account for last null character */
|
||||
JSON_Object * json_array_get_object (const JSON_Array *array, size_t index);
|
||||
JSON_Array * json_array_get_array (const JSON_Array *array, size_t index);
|
||||
double json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */
|
||||
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
|
||||
size_t json_array_get_count (const JSON_Array *array);
|
||||
JSON_Value * json_array_get_wrapping_value(const JSON_Array *array);
|
||||
JSON_Value *json_array_get_value(const JSON_Array *array, size_t index);
|
||||
const char *json_array_get_string(const JSON_Array *array, size_t index);
|
||||
size_t json_array_get_string_len(const JSON_Array *array, size_t index); /* doesn't account for last null character */
|
||||
JSON_Object *json_array_get_object(const JSON_Array *array, size_t index);
|
||||
JSON_Array *json_array_get_array(const JSON_Array *array, size_t index);
|
||||
double json_array_get_number(const JSON_Array *array, size_t index); /* returns 0 on fail */
|
||||
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
|
||||
size_t json_array_get_count(const JSON_Array *array);
|
||||
JSON_Value *json_array_get_wrapping_value(const JSON_Array *array);
|
||||
|
||||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
||||
* Order of values in array may change during execution. */
|
||||
|
@ -208,7 +207,7 @@ JSON_Status json_array_remove(JSON_Array *array, size_t i);
|
|||
* Does nothing and returns JSONFailure if index doesn't exist.
|
||||
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value);
|
||||
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string);
|
||||
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char *string);
|
||||
JSON_Status json_array_replace_string_with_len(JSON_Array *array, size_t i, const char *string, size_t len); /* length shouldn't include last null character */
|
||||
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number);
|
||||
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
|
||||
|
@ -229,33 +228,33 @@ JSON_Status json_array_append_null(JSON_Array *array);
|
|||
/*
|
||||
*JSON Value
|
||||
*/
|
||||
JSON_Value * json_value_init_object (void);
|
||||
JSON_Value * json_value_init_array (void);
|
||||
JSON_Value * json_value_init_string (const char *string); /* copies passed string */
|
||||
JSON_Value * json_value_init_string_with_len(const char *string, size_t length); /* copies passed string, length shouldn't include last null character */
|
||||
JSON_Value * json_value_init_number (double number);
|
||||
JSON_Value * json_value_init_boolean(int boolean);
|
||||
JSON_Value * json_value_init_null (void);
|
||||
JSON_Value * json_value_deep_copy (const JSON_Value *value);
|
||||
void json_value_free (JSON_Value *value);
|
||||
JSON_Value *json_value_init_object(void);
|
||||
JSON_Value *json_value_init_array(void);
|
||||
JSON_Value *json_value_init_string(const char *string); /* copies passed string */
|
||||
JSON_Value *json_value_init_string_with_len(const char *string, size_t length); /* copies passed string, length shouldn't include last null character */
|
||||
JSON_Value *json_value_init_number(double number);
|
||||
JSON_Value *json_value_init_boolean(int boolean);
|
||||
JSON_Value *json_value_init_null(void);
|
||||
JSON_Value *json_value_deep_copy(const JSON_Value *value);
|
||||
void json_value_free(JSON_Value *value);
|
||||
|
||||
JSON_Value_Type json_value_get_type (const JSON_Value *value);
|
||||
JSON_Object * json_value_get_object (const JSON_Value *value);
|
||||
JSON_Array * json_value_get_array (const JSON_Value *value);
|
||||
const char * json_value_get_string (const JSON_Value *value);
|
||||
size_t json_value_get_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_value_get_number (const JSON_Value *value);
|
||||
int json_value_get_boolean(const JSON_Value *value);
|
||||
JSON_Value * json_value_get_parent (const JSON_Value *value);
|
||||
JSON_Value_Type json_value_get_type(const JSON_Value *value);
|
||||
JSON_Object *json_value_get_object(const JSON_Value *value);
|
||||
JSON_Array *json_value_get_array(const JSON_Value *value);
|
||||
const char *json_value_get_string(const JSON_Value *value);
|
||||
size_t json_value_get_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_value_get_number(const JSON_Value *value);
|
||||
int json_value_get_boolean(const JSON_Value *value);
|
||||
JSON_Value *json_value_get_parent(const JSON_Value *value);
|
||||
|
||||
/* Same as above, but shorter */
|
||||
JSON_Value_Type json_type (const JSON_Value *value);
|
||||
JSON_Object * json_object (const JSON_Value *value);
|
||||
JSON_Array * json_array (const JSON_Value *value);
|
||||
const char * json_string (const JSON_Value *value);
|
||||
size_t json_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_number (const JSON_Value *value);
|
||||
int json_boolean(const JSON_Value *value);
|
||||
JSON_Value_Type json_type(const JSON_Value *value);
|
||||
JSON_Object *json_object(const JSON_Value *value);
|
||||
JSON_Array *json_array(const JSON_Value *value);
|
||||
const char *json_string(const JSON_Value *value);
|
||||
size_t json_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||
double json_number(const JSON_Value *value);
|
||||
int json_boolean(const JSON_Value *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,58 +1,48 @@
|
|||
#include "particle.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
struct emitter make_emitter()
|
||||
{
|
||||
struct emitter e = { 0 };
|
||||
return e;
|
||||
struct emitter make_emitter() {
|
||||
struct emitter e = {0};
|
||||
return e;
|
||||
}
|
||||
|
||||
struct emitter set_emitter(struct emitter e)
|
||||
{
|
||||
arrsetlen(e.particles, e.max);
|
||||
struct emitter set_emitter(struct emitter e) {
|
||||
arrsetlen(e.particles, e.max);
|
||||
|
||||
e.first = &e.particles[0];
|
||||
e.first = &e.particles[0];
|
||||
|
||||
for (int i = 0; i < arrlen(e.particles)-1; i++) {
|
||||
e.particles[i].next = &e.particles[i+1];
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void free_emitter(struct emitter e)
|
||||
{
|
||||
arrfree(e.particles);
|
||||
}
|
||||
|
||||
void start_emitter(struct emitter e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pause_emitter(struct emitter e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void stop_emitter(struct emitter e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void emitter_step(struct emitter e, double dt)
|
||||
{
|
||||
for (int i = 0; i < arrlen(e.particles); i++) {
|
||||
if (e.particles[i].life <= 0)
|
||||
continue;
|
||||
|
||||
e.particles[i].pos = cpvadd(e.particles[i].pos, cpvmult(e.particles[i].v, dt));
|
||||
e.particles[i].angle += e.particles[i].av * dt;
|
||||
e.particles[i].life -= dt;
|
||||
|
||||
if (e.particles[i].life <= 0) {
|
||||
e.particles[i].next = e.first;
|
||||
e.first = &e.particles[i];
|
||||
}
|
||||
for (int i = 0; i < arrlen(e.particles) - 1; i++) {
|
||||
e.particles[i].next = &e.particles[i + 1];
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void free_emitter(struct emitter e) {
|
||||
arrfree(e.particles);
|
||||
}
|
||||
|
||||
void start_emitter(struct emitter e) {
|
||||
}
|
||||
|
||||
void pause_emitter(struct emitter e) {
|
||||
}
|
||||
|
||||
void stop_emitter(struct emitter e) {
|
||||
}
|
||||
|
||||
void emitter_step(struct emitter e, double dt) {
|
||||
for (int i = 0; i < arrlen(e.particles); i++) {
|
||||
if (e.particles[i].life <= 0)
|
||||
continue;
|
||||
|
||||
e.particles[i].pos = cpvadd(e.particles[i].pos, cpvmult(e.particles[i].v, dt));
|
||||
e.particles[i].angle += e.particles[i].av * dt;
|
||||
e.particles[i].life -= dt;
|
||||
|
||||
if (e.particles[i].life <= 0) {
|
||||
e.particles[i].next = e.first;
|
||||
e.first = &e.particles[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#include "resources.h"
|
||||
|
||||
#include "config.h"
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "vec.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "log.h"
|
||||
#include "vec.h"
|
||||
#include <dirent.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ftw.h>
|
||||
|
||||
|
@ -31,111 +31,101 @@ static const char *cur_ext = NULL;
|
|||
struct dirent *c_dirent = NULL;
|
||||
struct vec *c_vec = NULL;
|
||||
|
||||
char pathbuf[MAXPATH+1];
|
||||
char pathbuf[MAXPATH + 1];
|
||||
|
||||
void resources_init()
|
||||
{
|
||||
prefabs = vec_make(MAXNAME, 25);
|
||||
void resources_init() {
|
||||
prefabs = vec_make(MAXNAME, 25);
|
||||
|
||||
DATA_PATH = malloc(MAXPATH);
|
||||
getcwd(DATA_PATH, MAXPATH);
|
||||
strncat(DATA_PATH, "/", MAXPATH);
|
||||
DATA_PATH = malloc(MAXPATH);
|
||||
getcwd(DATA_PATH, MAXPATH);
|
||||
strncat(DATA_PATH, "/", MAXPATH);
|
||||
|
||||
if (!PREF_PATH)
|
||||
PREF_PATH = strdup("./tmp/");
|
||||
if (!PREF_PATH)
|
||||
PREF_PATH = strdup("./tmp/");
|
||||
}
|
||||
|
||||
char *get_filename_from_path(char *path, int extension)
|
||||
{
|
||||
char *dirpos = strrchr(path, '/');
|
||||
if (!dirpos)
|
||||
dirpos = path;
|
||||
char *get_filename_from_path(char *path, int extension) {
|
||||
char *dirpos = strrchr(path, '/');
|
||||
if (!dirpos)
|
||||
dirpos = path;
|
||||
|
||||
char *end = strrchr(path, '\0');
|
||||
char *end = strrchr(path, '\0');
|
||||
|
||||
int offset = 0;
|
||||
if (!extension) {
|
||||
char *ext = strrchr(path, '.');
|
||||
offset = end - ext;
|
||||
YughInfo("Making %s without extension ...");
|
||||
}
|
||||
int offset = 0;
|
||||
if (!extension) {
|
||||
char *ext = strrchr(path, '.');
|
||||
offset = end - ext;
|
||||
YughInfo("Making %s without extension ...");
|
||||
}
|
||||
|
||||
char *filename = malloc(sizeof(char) * (end - dirpos - offset + 1));
|
||||
strncpy(filename, dirpos, end - dirpos - offset);
|
||||
return filename;
|
||||
char *filename = malloc(sizeof(char) * (end - dirpos - offset + 1));
|
||||
strncpy(filename, dirpos, end - dirpos - offset);
|
||||
return filename;
|
||||
}
|
||||
|
||||
char *get_directory_from_path(char *path)
|
||||
{
|
||||
const char *dirpos = strrchr(path, '/');
|
||||
char *directory = (char *) malloc(sizeof(char) * (dirpos - path + 1));
|
||||
strncpy(directory, path, dirpos - path);
|
||||
return directory;
|
||||
char *get_directory_from_path(char *path) {
|
||||
const char *dirpos = strrchr(path, '/');
|
||||
char *directory = (char *)malloc(sizeof(char) * (dirpos - path + 1));
|
||||
strncpy(directory, path, dirpos - path);
|
||||
return directory;
|
||||
}
|
||||
|
||||
FILE *res_open(char *path, const char *tag)
|
||||
{
|
||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||
strncat(pathbuf, path, MAXPATH);
|
||||
FILE *f = fopen(pathbuf, tag);
|
||||
return f;
|
||||
FILE *res_open(char *path, const char *tag) {
|
||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||
strncat(pathbuf, path, MAXPATH);
|
||||
FILE *f = fopen(pathbuf, tag);
|
||||
return f;
|
||||
}
|
||||
|
||||
static int ext_check(const char *path, const struct stat *sb, int typeflag)
|
||||
{
|
||||
if (typeflag == FTW_F) {
|
||||
const char *ext = strrchr(path, '.');
|
||||
if (ext != NULL && !strcmp(ext, cur_ext))
|
||||
vec_add(c_vec, path);
|
||||
}
|
||||
static int ext_check(const char *path, const struct stat *sb, int typeflag) {
|
||||
if (typeflag == FTW_F) {
|
||||
const char *ext = strrchr(path, '.');
|
||||
if (ext != NULL && !strcmp(ext, cur_ext))
|
||||
vec_add(c_vec, path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fill_extensions(struct vec *vec, const char *path, const char *ext)
|
||||
{
|
||||
c_vec = vec;
|
||||
cur_ext = ext;
|
||||
vec_clear(c_vec);
|
||||
ftw(".", ext_check, 10);
|
||||
void fill_extensions(struct vec *vec, const char *path, const char *ext) {
|
||||
c_vec = vec;
|
||||
cur_ext = ext;
|
||||
vec_clear(c_vec);
|
||||
ftw(".", ext_check, 10);
|
||||
}
|
||||
|
||||
void findPrefabs()
|
||||
{
|
||||
fill_extensions(prefabs, DATA_PATH, EXT_PREFAB);
|
||||
void findPrefabs() {
|
||||
fill_extensions(prefabs, DATA_PATH, EXT_PREFAB);
|
||||
}
|
||||
|
||||
char *str_replace_ext(const char *s, const char *newext) {
|
||||
static char ret[256];
|
||||
static char ret[256];
|
||||
|
||||
strncpy(ret, s, 256);
|
||||
char *ext = strrchr(ret, '.');
|
||||
strncpy(ext, newext, 10);
|
||||
strncpy(ret, s, 256);
|
||||
char *ext = strrchr(ret, '.');
|
||||
strncpy(ext, newext, 10);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE *path_open(const char *tag, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(pathbuf, fmt, args);
|
||||
va_end(args);
|
||||
FILE *path_open(const char *tag, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(pathbuf, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
FILE *f = fopen(pathbuf, tag);
|
||||
return f;
|
||||
FILE *f = fopen(pathbuf, tag);
|
||||
return f;
|
||||
}
|
||||
|
||||
char *make_path(const char *file)
|
||||
{
|
||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||
strncat(pathbuf, file, MAXPATH);
|
||||
return pathbuf;
|
||||
char *make_path(const char *file) {
|
||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||
strncat(pathbuf, file, MAXPATH);
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
char *new = malloc(sizeof(char)*(strlen(s)+1));
|
||||
strcpy(new, s);
|
||||
return new;
|
||||
char *strdup(const char *s) {
|
||||
char *new = malloc(sizeof(char) * (strlen(s) + 1));
|
||||
strcpy(new, s);
|
||||
return new;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef RESOURCES_H
|
||||
#define RESOURCES_H
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct vec;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "script.h"
|
||||
|
||||
#include "stdio.h"
|
||||
#include "log.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "ffi.h"
|
||||
#include "font.h"
|
||||
|
@ -10,39 +10,38 @@
|
|||
|
||||
#include "stb_ds.h"
|
||||
|
||||
#include "time.h"
|
||||
#include "sys/stat.h"
|
||||
#include "sys/types.h"
|
||||
#include "time.h"
|
||||
|
||||
JSContext *js = NULL;
|
||||
JSRuntime *rt = NULL;
|
||||
|
||||
static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) {
|
||||
if (typeflag != FTW_F)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(".prefab", strrchr(fpath, '.')))
|
||||
script_dofile(fpath);
|
||||
|
||||
if (typeflag != FTW_F)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(".prefab", strrchr(fpath, '.')))
|
||||
script_dofile(fpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void script_startup()
|
||||
{
|
||||
rt = JS_NewRuntime();
|
||||
JS_SetMaxStackSize(rt,0);
|
||||
js = JS_NewContext(rt);
|
||||
ffi_load();
|
||||
void script_startup() {
|
||||
rt = JS_NewRuntime();
|
||||
JS_SetMaxStackSize(rt, 0);
|
||||
js = JS_NewContext(rt);
|
||||
ffi_load();
|
||||
}
|
||||
|
||||
JSValue num_cache[100] = {0};
|
||||
|
||||
void script_init() {
|
||||
/* Load all prefabs into memory */
|
||||
script_dofile("scripts/engine.js");
|
||||
/* Load all prefabs into memory */
|
||||
script_dofile("scripts/engine.js");
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
num_cache[i] = int2js(i);
|
||||
for (int i = 0; i < 100; i++)
|
||||
num_cache[i] = int2js(i);
|
||||
}
|
||||
|
||||
void script_run(const char *script) {
|
||||
|
@ -52,72 +51,68 @@ void script_run(const char *script) {
|
|||
struct callee stacktrace_callee;
|
||||
|
||||
time_t file_mod_secs(const char *file) {
|
||||
struct stat attr;
|
||||
stat(file, &attr);
|
||||
return attr.st_mtime;
|
||||
struct stat attr;
|
||||
stat(file, &attr);
|
||||
return attr.st_mtime;
|
||||
}
|
||||
|
||||
void js_stacktrace()
|
||||
{
|
||||
void js_stacktrace() {
|
||||
call_callee(&stacktrace_callee);
|
||||
return;
|
||||
}
|
||||
|
||||
void js_dump_stack()
|
||||
{
|
||||
void js_dump_stack() {
|
||||
js_stacktrace();
|
||||
return;
|
||||
|
||||
|
||||
JSValue exception = JS_GetException(js);
|
||||
if (JS_IsNull(exception)) return;
|
||||
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
||||
const char *stack = JS_ToCString(js, val);
|
||||
YughError("%s :: %s\n%s", name, msg, stack);
|
||||
const char *stack = JS_ToCString(js, val);
|
||||
YughError("%s :: %s\n%s", name, msg, stack);
|
||||
|
||||
JS_FreeCString(js, name);
|
||||
JS_FreeCString(js, msg);
|
||||
JS_FreeCString(js, stack);
|
||||
}
|
||||
JS_FreeCString(js, name);
|
||||
JS_FreeCString(js, msg);
|
||||
JS_FreeCString(js, stack);
|
||||
}
|
||||
}
|
||||
|
||||
int js_print_exception(JSValue v) {
|
||||
if (JS_IsException(v)) {
|
||||
JSValue exception = JS_GetException(js);
|
||||
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
||||
const char *stack = JS_ToCString(js, val);
|
||||
YughWarn("%s :: %s\n%s", name, msg, stack);
|
||||
|
||||
int js_print_exception(JSValue v)
|
||||
{
|
||||
if (JS_IsException(v)) {
|
||||
JSValue exception = JS_GetException(js);
|
||||
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
||||
const char *stack = JS_ToCString(js, val);
|
||||
YughWarn("%s :: %s\n%s", name, msg, stack);
|
||||
JS_FreeCString(js, name);
|
||||
JS_FreeCString(js, msg);
|
||||
JS_FreeCString(js, stack);
|
||||
}
|
||||
|
||||
JS_FreeCString(js, name);
|
||||
JS_FreeCString(js, msg);
|
||||
JS_FreeCString(js, stack);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int script_dofile(const char *file) {
|
||||
YughInfo("Doing script %s", file);
|
||||
const char *script = slurp_text(file);
|
||||
if (!script) {
|
||||
YughError("Can't find file %s.", file);
|
||||
return 0;
|
||||
}
|
||||
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
||||
js_print_exception(obj);
|
||||
JS_FreeValue(js, obj);
|
||||
YughInfo("Doing script %s", file);
|
||||
const char *script = slurp_text(file);
|
||||
if (!script) {
|
||||
YughError("Can't find file %s.", file);
|
||||
return 0;
|
||||
}
|
||||
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
||||
js_print_exception(obj);
|
||||
JS_FreeValue(js, obj);
|
||||
|
||||
return file_mod_secs(file);
|
||||
return file_mod_secs(file);
|
||||
}
|
||||
|
||||
/* env is an object in the scripting environment;
|
||||
|
@ -129,17 +124,14 @@ void script_eval_w_env(const char *s, JSValue env) {
|
|||
JS_FreeValue(js, v);
|
||||
}
|
||||
|
||||
void script_call_sym(JSValue sym)
|
||||
{
|
||||
void script_call_sym(JSValue sym) {
|
||||
struct callee c;
|
||||
c.fn = sym;
|
||||
c.obj = JS_GetGlobalObject(js);
|
||||
call_callee(&c);
|
||||
}
|
||||
|
||||
|
||||
JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv)
|
||||
{
|
||||
JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv) {
|
||||
JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv);
|
||||
js_print_exception(ret);
|
||||
JS_FreeValue(js, ret);
|
||||
|
@ -150,29 +142,25 @@ void call_callee(struct callee *c) {
|
|||
js_callee_exec(c, 0, NULL);
|
||||
}
|
||||
|
||||
void callee_dbl(struct callee c, double d)
|
||||
{
|
||||
void callee_dbl(struct callee c, double d) {
|
||||
JSValue v = num2js(d);
|
||||
js_callee_exec(&c, 1, &v);
|
||||
JS_FreeValue(js, v);
|
||||
}
|
||||
|
||||
void callee_int(struct callee c, int i)
|
||||
{
|
||||
void callee_int(struct callee c, int i) {
|
||||
JSValue v = int2js(i);
|
||||
js_callee_exec(&c, 1, &v);
|
||||
JS_FreeValue(js, v);
|
||||
}
|
||||
|
||||
void callee_vec2(struct callee c, cpVect vec)
|
||||
{
|
||||
void callee_vec2(struct callee c, cpVect vec) {
|
||||
JSValue v = vec2js(vec);
|
||||
js_callee_exec(&c, 1, &v);
|
||||
JS_FreeValue(js, v);
|
||||
}
|
||||
|
||||
void script_callee(struct callee c, int argc, JSValue *argv)
|
||||
{
|
||||
void script_callee(struct callee c, int argc, JSValue *argv) {
|
||||
js_callee_exec(&c, argc, argv);
|
||||
}
|
||||
|
||||
|
@ -193,7 +181,7 @@ void register_nk_gui(struct callee c) { nk_gui_callee = c; }
|
|||
void call_nk_gui() { js_callee_exec(&nk_gui_callee, 0, NULL); }
|
||||
|
||||
static struct callee physupdate_callee;
|
||||
void register_physics(struct callee c) { physupdate_callee = c;}
|
||||
void register_physics(struct callee c) { physupdate_callee = c; }
|
||||
void call_physics(double dt) { callee_dbl(physupdate_callee, dt); }
|
||||
|
||||
struct callee debug_callee;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#include "shader.h"
|
||||
|
||||
#include "render.h"
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "font.h"
|
||||
#include "log.h"
|
||||
#include "render.h"
|
||||
#include "resources.h"
|
||||
#include "stb_ds.h"
|
||||
#include "timer.h"
|
||||
#include "font.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "time.h"
|
||||
|
||||
|
@ -17,110 +17,104 @@
|
|||
|
||||
static struct shader *shaders;
|
||||
|
||||
struct shader *MakeShader(const char *vertpath, const char *fragpath)
|
||||
{
|
||||
if (arrcap(shaders) == 0)
|
||||
arrsetcap(shaders, 20);
|
||||
struct shader *MakeShader(const char *vertpath, const char *fragpath) {
|
||||
if (arrcap(shaders) == 0)
|
||||
arrsetcap(shaders, 20);
|
||||
|
||||
struct shader init = {
|
||||
.vertpath = vertpath,
|
||||
.fragpath = fragpath };
|
||||
shader_compile(&init);
|
||||
arrput(shaders, init);
|
||||
return &arrlast(shaders);
|
||||
struct shader init = {
|
||||
.vertpath = vertpath,
|
||||
.fragpath = fragpath};
|
||||
shader_compile(&init);
|
||||
arrput(shaders, init);
|
||||
return &arrlast(shaders);
|
||||
}
|
||||
|
||||
int shader_compile_error(int shader)
|
||||
{
|
||||
/*
|
||||
GLint success = 0;
|
||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||
int shader_compile_error(int shader) {
|
||||
/*
|
||||
GLint success = 0;
|
||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (success) return 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (success) return 0;
|
||||
|
||||
glGetShaderInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||
YughLog(0, LOG_ERROR, "Shader compilation error.\nLog: %s", infoLog);
|
||||
glGetShaderInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||
YughLog(0, LOG_ERROR, "Shader compilation error.\nLog: %s", infoLog);
|
||||
|
||||
return 1;
|
||||
*/
|
||||
return 1;
|
||||
*/
|
||||
}
|
||||
|
||||
int shader_link_error(int shader)
|
||||
{
|
||||
/*
|
||||
GLint success = 0;
|
||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||
int shader_link_error(int shader) {
|
||||
/*
|
||||
GLint success = 0;
|
||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if (success) return 0;
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if (success) return 0;
|
||||
|
||||
glGetProgramInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||
YughLog(0, LOG_ERROR, "Shader link error.\nLog: %s", infoLog);
|
||||
glGetProgramInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||
YughLog(0, LOG_ERROR, "Shader link error.\nLog: %s", infoLog);
|
||||
|
||||
return 1;
|
||||
*/
|
||||
return 1;
|
||||
*/
|
||||
}
|
||||
|
||||
int load_shader_from_file(const char *path, int type)
|
||||
{
|
||||
char spath[MAXPATH] = {'\0'};
|
||||
int load_shader_from_file(const char *path, int type) {
|
||||
char spath[MAXPATH] = {'\0'};
|
||||
|
||||
sprintf(spath, "%s%s", "shaders/", path);
|
||||
FILE *f = fopen(make_path(spath), "r'");
|
||||
if (!path)
|
||||
perror(spath), exit(1);
|
||||
sprintf(spath, "%s%s", "shaders/", path);
|
||||
FILE *f = fopen(make_path(spath), "r'");
|
||||
if (!path)
|
||||
perror(spath), exit(1);
|
||||
|
||||
char *buf;
|
||||
long int fsize;
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
buf = malloc(fsize+1);
|
||||
rewind(f);
|
||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||
buf[r] = '\0';
|
||||
char *buf;
|
||||
long int fsize;
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
buf = malloc(fsize + 1);
|
||||
rewind(f);
|
||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||
buf[r] = '\0';
|
||||
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
|
||||
/*
|
||||
GLuint id = glCreateShader(type);
|
||||
const char *code = buf;
|
||||
glShaderSource(id, 1, &code, NULL);
|
||||
glCompileShader(id);
|
||||
if (shader_compile_error(id)) {
|
||||
YughError("Error with shader %s.", path);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
GLuint id = glCreateShader(type);
|
||||
const char *code = buf;
|
||||
glShaderSource(id, 1, &code, NULL);
|
||||
glCompileShader(id);
|
||||
if (shader_compile_error(id)) {
|
||||
YughError("Error with shader %s.", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
free(buf);
|
||||
|
||||
return id;
|
||||
*/
|
||||
|
||||
return id;
|
||||
*/
|
||||
}
|
||||
|
||||
void shader_compile(struct shader *shader)
|
||||
{
|
||||
YughInfo("Making shader with %s and %s.", shader->vertpath, shader->fragpath);
|
||||
char spath[MAXPATH];
|
||||
sprintf(spath,"%s%s", "shaders/", shader->vertpath);
|
||||
const char *vsrc = slurp_text(spath);
|
||||
sprintf(spath, "%s%s", "shaders/", shader->fragpath);
|
||||
const char *fsrc = slurp_text(spath);
|
||||
void shader_compile(struct shader *shader) {
|
||||
YughInfo("Making shader with %s and %s.", shader->vertpath, shader->fragpath);
|
||||
char spath[MAXPATH];
|
||||
sprintf(spath, "%s%s", "shaders/", shader->vertpath);
|
||||
const char *vsrc = slurp_text(spath);
|
||||
sprintf(spath, "%s%s", "shaders/", shader->fragpath);
|
||||
const char *fsrc = slurp_text(spath);
|
||||
|
||||
shader->shd = sg_make_shader(&(sg_shader_desc){
|
||||
shader->shd = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = vsrc,
|
||||
.fs.source = fsrc,
|
||||
.label = shader->vertpath,
|
||||
});
|
||||
|
||||
free(vsrc);
|
||||
free(fsrc);
|
||||
});
|
||||
|
||||
free(vsrc);
|
||||
free(fsrc);
|
||||
}
|
||||
|
||||
void shader_use(struct shader *shader)
|
||||
{
|
||||
// glUseProgram(shader->id);
|
||||
void shader_use(struct shader *shader) {
|
||||
// glUseProgram(shader->id);
|
||||
}
|
||||
/*
|
||||
void shader_setbool(struct shader *shader, const char *name, int val)
|
||||
|
@ -171,16 +165,13 @@ void shader_setUBO(struct shader *shader, const char *name, unsigned int index)
|
|||
|
||||
*/
|
||||
|
||||
void shader_compile_all()
|
||||
{
|
||||
for (int i = 0; i < arrlen(shaders); i++)
|
||||
shader_compile(&shaders[i]);
|
||||
void shader_compile_all() {
|
||||
for (int i = 0; i < arrlen(shaders); i++)
|
||||
shader_compile(&shaders[i]);
|
||||
}
|
||||
void shader_setvec3(struct shader *shader, const char *name, mfloat_t val[3])
|
||||
{
|
||||
// glUniform3fv(glGetUniformLocation(shader->id, name), 1, val);
|
||||
void shader_setvec3(struct shader *shader, const char *name, mfloat_t val[3]) {
|
||||
// glUniform3fv(glGetUniformLocation(shader->id, name), 1, val);
|
||||
}
|
||||
void shader_setmat4(struct shader *shader, const char *name, mfloat_t val[16])
|
||||
{
|
||||
// glUniformMatrix4fv(glGetUniformLocation(shader->id, name), 1, GL_FALSE, val);
|
||||
void shader_setmat4(struct shader *shader, const char *name, mfloat_t val[16]) {
|
||||
// glUniformMatrix4fv(glGetUniformLocation(shader->id, name), 1, GL_FALSE, val);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
struct shader {
|
||||
sg_shader shd;
|
||||
const char *vertpath;
|
||||
const char *fragpath;
|
||||
sg_shader shd;
|
||||
const char *vertpath;
|
||||
const char *fragpath;
|
||||
};
|
||||
|
||||
void shader_compile_all();
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#include "sound.h"
|
||||
#include "resources.h"
|
||||
#include <stdlib.h>
|
||||
#include "log.h"
|
||||
#include "string.h"
|
||||
#include "math.h"
|
||||
#include "limits.h"
|
||||
#include "time.h"
|
||||
#include "log.h"
|
||||
#include "math.h"
|
||||
#include "music.h"
|
||||
#include "resources.h"
|
||||
#include "stb_vorbis.h"
|
||||
#include "string.h"
|
||||
#include "time.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "samplerate.h"
|
||||
|
||||
#include "stb_ds.h"
|
||||
|
||||
#include "mix.h"
|
||||
#include "dsp.h"
|
||||
#include "mix.h"
|
||||
|
||||
#include "miniaudio.h"
|
||||
|
||||
|
@ -25,85 +25,81 @@
|
|||
#include "tml.h"
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
struct wav *value;
|
||||
char *key;
|
||||
struct wav *value;
|
||||
} *wavhash = NULL;
|
||||
|
||||
static struct wav change_channels(struct wav w, int ch)
|
||||
{
|
||||
short *data = w.data;
|
||||
int samples = ch * w.frames;
|
||||
short *new = malloc(sizeof(short)*samples);
|
||||
static struct wav change_channels(struct wav w, int ch) {
|
||||
short *data = w.data;
|
||||
int samples = ch * w.frames;
|
||||
short *new = malloc(sizeof(short) * samples);
|
||||
|
||||
if (ch > w.ch) {
|
||||
/* Sets all new channels equal to the first one */
|
||||
for (int i = 0; i < w.frames; i++) {
|
||||
for (int j = 0; j < ch; j++)
|
||||
new[i*ch+j] = data[i];
|
||||
}
|
||||
} else {
|
||||
/* Simple method; just use first N channels present in wav */
|
||||
for (int i = 0; i < w.frames; i++)
|
||||
for (int j = 0; j < ch; j++)
|
||||
new[i*ch+j] = data[i*ch+j];
|
||||
if (ch > w.ch) {
|
||||
/* Sets all new channels equal to the first one */
|
||||
for (int i = 0; i < w.frames; i++) {
|
||||
for (int j = 0; j < ch; j++)
|
||||
new[i * ch + j] = data[i];
|
||||
}
|
||||
} else {
|
||||
/* Simple method; just use first N channels present in wav */
|
||||
for (int i = 0; i < w.frames; i++)
|
||||
for (int j = 0; j < ch; j++)
|
||||
new[i * ch + j] = data[i * ch + j];
|
||||
}
|
||||
|
||||
free (w.data);
|
||||
w.data = new;
|
||||
return w;
|
||||
free(w.data);
|
||||
w.data = new;
|
||||
return w;
|
||||
}
|
||||
|
||||
static struct wav change_samplerate(struct wav w, int rate)
|
||||
{
|
||||
float ratio = (float)rate/w.samplerate;
|
||||
int outframes = w.frames * ratio;
|
||||
SRC_DATA ssrc;
|
||||
float floatdata[w.frames*w.ch];
|
||||
src_short_to_float_array(w.data, floatdata, w.frames*w.ch);
|
||||
float resampled[w.ch*outframes];
|
||||
static struct wav change_samplerate(struct wav w, int rate) {
|
||||
float ratio = (float)rate / w.samplerate;
|
||||
int outframes = w.frames * ratio;
|
||||
SRC_DATA ssrc;
|
||||
float floatdata[w.frames * w.ch];
|
||||
src_short_to_float_array(w.data, floatdata, w.frames * w.ch);
|
||||
float resampled[w.ch * outframes];
|
||||
|
||||
ssrc.data_in = floatdata;
|
||||
ssrc.data_out = resampled;
|
||||
ssrc.input_frames = w.frames;
|
||||
ssrc.output_frames = outframes;
|
||||
ssrc.src_ratio = ratio;
|
||||
ssrc.data_in = floatdata;
|
||||
ssrc.data_out = resampled;
|
||||
ssrc.input_frames = w.frames;
|
||||
ssrc.output_frames = outframes;
|
||||
ssrc.src_ratio = ratio;
|
||||
|
||||
src_simple(&ssrc, SRC_SINC_BEST_QUALITY, w.ch);
|
||||
src_simple(&ssrc, SRC_SINC_BEST_QUALITY, w.ch);
|
||||
|
||||
short *newdata = malloc(sizeof(short)*outframes*w.ch);
|
||||
src_float_to_short_array(resampled, newdata, outframes*w.ch);
|
||||
short *newdata = malloc(sizeof(short) * outframes * w.ch);
|
||||
src_float_to_short_array(resampled, newdata, outframes * w.ch);
|
||||
|
||||
free(w.data);
|
||||
w.data = newdata;
|
||||
w.samplerate = rate;
|
||||
free(w.data);
|
||||
w.data = newdata;
|
||||
w.samplerate = rate;
|
||||
|
||||
return w;
|
||||
return w;
|
||||
}
|
||||
|
||||
void wav_norm_gain(struct wav *w, double lv)
|
||||
{
|
||||
short tarmax = db2short(lv);
|
||||
short max = 0;
|
||||
short *s = w->data;
|
||||
for (int i = 0; i < w->frames; i++) {
|
||||
for (int j = 0; j < w->ch; j++) {
|
||||
max = (abs(s[i*w->ch + j]) > max) ? abs(s[i*w->ch + j]) : max;
|
||||
}
|
||||
void wav_norm_gain(struct wav *w, double lv) {
|
||||
short tarmax = db2short(lv);
|
||||
short max = 0;
|
||||
short *s = w->data;
|
||||
for (int i = 0; i < w->frames; i++) {
|
||||
for (int j = 0; j < w->ch; j++) {
|
||||
max = (abs(s[i * w->ch + j]) > max) ? abs(s[i * w->ch + j]) : max;
|
||||
}
|
||||
}
|
||||
|
||||
float mult = (float)max / tarmax;
|
||||
float mult = (float)max / tarmax;
|
||||
|
||||
for (int i = 0; i < w->frames; i++) {
|
||||
for (int j = 0; j < w->ch; j++) {
|
||||
s[i*w->ch + j] *= mult;
|
||||
}
|
||||
for (int i = 0; i < w->frames; i++) {
|
||||
for (int j = 0; j < w->ch; j++) {
|
||||
s[i * w->ch + j] *= mult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ma_engine *engine;
|
||||
|
||||
void sound_init()
|
||||
{
|
||||
void sound_init() {
|
||||
ma_result result;
|
||||
engine = malloc(sizeof(*engine));
|
||||
result = ma_engine_init(NULL, engine);
|
||||
|
@ -111,66 +107,61 @@ void sound_init()
|
|||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
|
||||
mixer_init();
|
||||
}
|
||||
|
||||
struct wav *make_sound(const char *wav)
|
||||
{
|
||||
int index = shgeti(wavhash, wav);
|
||||
if (index != -1) return wavhash[index].value;
|
||||
struct wav *make_sound(const char *wav) {
|
||||
int index = shgeti(wavhash, wav);
|
||||
if (index != -1) return wavhash[index].value;
|
||||
|
||||
struct wav mwav;
|
||||
// mwav.data = drwav_open_file_and_read_pcm_frames_s16(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||
struct wav mwav;
|
||||
// mwav.data = drwav_open_file_and_read_pcm_frames_s16(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||
|
||||
if (mwav.samplerate != SAMPLERATE) {
|
||||
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
||||
// mwav = change_samplerate(mwav, SAMPLERATE);
|
||||
}
|
||||
if (mwav.samplerate != SAMPLERATE) {
|
||||
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
||||
// mwav = change_samplerate(mwav, SAMPLERATE);
|
||||
}
|
||||
|
||||
if (mwav.ch != CHANNELS) {
|
||||
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
||||
mwav = change_channels(mwav, CHANNELS);
|
||||
}
|
||||
if (mwav.ch != CHANNELS) {
|
||||
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
||||
mwav = change_channels(mwav, CHANNELS);
|
||||
}
|
||||
|
||||
mwav.gain = 1.f;
|
||||
mwav.gain = 1.f;
|
||||
|
||||
struct wav *newwav = malloc(sizeof(*newwav));
|
||||
*newwav = mwav;
|
||||
struct wav *newwav = malloc(sizeof(*newwav));
|
||||
*newwav = mwav;
|
||||
|
||||
if (shlen(wavhash) == 0) sh_new_arena(wavhash);
|
||||
if (shlen(wavhash) == 0) sh_new_arena(wavhash);
|
||||
|
||||
shput(wavhash, wav, newwav);
|
||||
shput(wavhash, wav, newwav);
|
||||
|
||||
return newwav;
|
||||
return newwav;
|
||||
}
|
||||
|
||||
void free_sound(const char *wav)
|
||||
{
|
||||
struct wav *w = shget(wavhash, wav);
|
||||
if (w == NULL) return;
|
||||
void free_sound(const char *wav) {
|
||||
struct wav *w = shget(wavhash, wav);
|
||||
if (w == NULL) return;
|
||||
|
||||
free(w->data);
|
||||
free(w);
|
||||
shdel(wavhash, wav);
|
||||
free(w->data);
|
||||
free(w);
|
||||
shdel(wavhash, wav);
|
||||
}
|
||||
|
||||
struct soundstream *soundstream_make()
|
||||
{
|
||||
struct soundstream *new = malloc(sizeof(*new));
|
||||
new->buf = circbuf_make(sizeof(short), BUF_FRAMES*CHANNELS*2);
|
||||
return new;
|
||||
struct soundstream *soundstream_make() {
|
||||
struct soundstream *new = malloc(sizeof(*new));
|
||||
new->buf = circbuf_make(sizeof(short), BUF_FRAMES * CHANNELS * 2);
|
||||
return new;
|
||||
}
|
||||
|
||||
void mini_sound(char *path)
|
||||
{
|
||||
void mini_sound(char *path) {
|
||||
ma_engine_play_sound(engine, path, NULL);
|
||||
}
|
||||
|
||||
static ma_sound music_sound;
|
||||
|
||||
void mini_music_play(char *path)
|
||||
{
|
||||
void mini_music_play(char *path) {
|
||||
ma_sound_uninit(&music_sound);
|
||||
int result = ma_sound_init_from_file(engine, path, MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, NULL, &music_sound);
|
||||
if (result != MA_SUCCESS) {
|
||||
|
@ -181,163 +172,139 @@ void mini_music_play(char *path)
|
|||
ma_sound_start(&music_sound);
|
||||
}
|
||||
|
||||
void mini_music_pause()
|
||||
{
|
||||
void mini_music_pause() {
|
||||
ma_sound_stop(&music_sound);
|
||||
}
|
||||
|
||||
void mini_music_stop()
|
||||
{
|
||||
void mini_music_stop() {
|
||||
ma_sound_stop(&music_sound);
|
||||
}
|
||||
|
||||
void mini_master(float v)
|
||||
{
|
||||
void mini_master(float v) {
|
||||
ma_engine_set_volume(engine, v);
|
||||
}
|
||||
|
||||
void kill_oneshot(struct sound *s)
|
||||
{
|
||||
free(s);
|
||||
void kill_oneshot(struct sound *s) {
|
||||
free(s);
|
||||
}
|
||||
|
||||
void play_oneshot(struct wav *wav) {
|
||||
struct sound *new = malloc(sizeof(*new));
|
||||
new->data = wav;
|
||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||
new->playing=1;
|
||||
new->loop=0;
|
||||
new->frame = 0;
|
||||
new->endcb = kill_oneshot;
|
||||
|
||||
struct sound *new = malloc(sizeof(*new));
|
||||
new->data = wav;
|
||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||
new->playing = 1;
|
||||
new->loop = 0;
|
||||
new->frame = 0;
|
||||
new->endcb = kill_oneshot;
|
||||
}
|
||||
|
||||
struct sound *play_sound(struct wav *wav)
|
||||
{
|
||||
struct sound *new = calloc(1, sizeof(*new));
|
||||
new->data = wav;
|
||||
struct sound *play_sound(struct wav *wav) {
|
||||
struct sound *new = calloc(1, sizeof(*new));
|
||||
new->data = wav;
|
||||
|
||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||
new->playing = 1;
|
||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||
new->playing = 1;
|
||||
|
||||
return new;
|
||||
return new;
|
||||
}
|
||||
|
||||
int sound_playing(const struct sound *s)
|
||||
{
|
||||
return s->playing;
|
||||
int sound_playing(const struct sound *s) {
|
||||
return s->playing;
|
||||
}
|
||||
|
||||
int sound_paused(const struct sound *s)
|
||||
{
|
||||
return (!s->playing && s->frame < s->data->frames);
|
||||
int sound_paused(const struct sound *s) {
|
||||
return (!s->playing && s->frame < s->data->frames);
|
||||
}
|
||||
void sound_pause(struct sound *s)
|
||||
{
|
||||
s->playing = 0;
|
||||
bus_free(s->bus);
|
||||
void sound_pause(struct sound *s) {
|
||||
s->playing = 0;
|
||||
bus_free(s->bus);
|
||||
}
|
||||
|
||||
void sound_resume(struct sound *s)
|
||||
{
|
||||
s->playing = 1;
|
||||
s->bus = first_free_bus(dsp_filter(s, sound_fillbuf));
|
||||
void sound_resume(struct sound *s) {
|
||||
s->playing = 1;
|
||||
s->bus = first_free_bus(dsp_filter(s, sound_fillbuf));
|
||||
}
|
||||
|
||||
void sound_stop(struct sound *s)
|
||||
{
|
||||
s->playing = 0;
|
||||
s->frame = 0;
|
||||
bus_free(s->bus);
|
||||
void sound_stop(struct sound *s) {
|
||||
s->playing = 0;
|
||||
s->frame = 0;
|
||||
bus_free(s->bus);
|
||||
}
|
||||
|
||||
int sound_finished(const struct sound *s)
|
||||
{
|
||||
return !s->playing && s->frame == s->data->frames;
|
||||
int sound_finished(const struct sound *s) {
|
||||
return !s->playing && s->frame == s->data->frames;
|
||||
}
|
||||
|
||||
int sound_stopped(const struct sound *s)
|
||||
{
|
||||
return !s->playing && s->frame == 0;
|
||||
int sound_stopped(const struct sound *s) {
|
||||
return !s->playing && s->frame == 0;
|
||||
}
|
||||
|
||||
struct mp3 make_music(const char *mp3)
|
||||
{
|
||||
// drmp3 new;
|
||||
// if (!drmp3_init_file(&new, mp3, NULL)) {
|
||||
// YughError("Could not open mp3 file %s.", mp3);
|
||||
// }
|
||||
struct mp3 make_music(const char *mp3) {
|
||||
// drmp3 new;
|
||||
// if (!drmp3_init_file(&new, mp3, NULL)) {
|
||||
// YughError("Could not open mp3 file %s.", mp3);
|
||||
// }
|
||||
|
||||
struct mp3 newmp3 = {};
|
||||
return newmp3;
|
||||
struct mp3 newmp3 = {};
|
||||
return newmp3;
|
||||
}
|
||||
|
||||
void close_audio_device(int device)
|
||||
{
|
||||
void close_audio_device(int device) {
|
||||
}
|
||||
|
||||
int open_device(const char *adriver)
|
||||
{
|
||||
return 0;
|
||||
int open_device(const char *adriver) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sound_fillbuf(struct sound *s, short *buf, int n)
|
||||
{
|
||||
float gainmult = pct2mult(s->data->gain);
|
||||
void sound_fillbuf(struct sound *s, short *buf, int n) {
|
||||
float gainmult = pct2mult(s->data->gain);
|
||||
|
||||
short *in = s->data->data;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < CHANNELS; j++) buf[i*CHANNELS+j] = in[s->frame+j] * gainmult;
|
||||
s->frame++;
|
||||
if (s->frame == s->data->frames) {
|
||||
short *in = s->data->data;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < CHANNELS; j++)
|
||||
buf[i * CHANNELS + j] = in[s->frame + j] * gainmult;
|
||||
s->frame++;
|
||||
if (s->frame == s->data->frames) {
|
||||
|
||||
bus_free(s->bus);
|
||||
s->bus = NULL;
|
||||
s->endcb(s);
|
||||
return;
|
||||
}
|
||||
bus_free(s->bus);
|
||||
s->bus = NULL;
|
||||
s->endcb(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp3_fillbuf(struct sound *s, short *buf, int n)
|
||||
{
|
||||
|
||||
void mp3_fillbuf(struct sound *s, short *buf, int n) {
|
||||
}
|
||||
|
||||
void soundstream_fillbuf(struct soundstream *s, short *buf, int n)
|
||||
{
|
||||
int max = s->buf->write - s->buf->read;
|
||||
int lim = (max < n*CHANNELS) ? max : n*CHANNELS;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
buf[i] = cbuf_shift(s->buf);
|
||||
}
|
||||
void soundstream_fillbuf(struct soundstream *s, short *buf, int n) {
|
||||
int max = s->buf->write - s->buf->read;
|
||||
int lim = (max < n * CHANNELS) ? max : n * CHANNELS;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
buf[i] = cbuf_shift(s->buf);
|
||||
}
|
||||
}
|
||||
|
||||
float short2db(short val)
|
||||
{
|
||||
return 20*log10(abs(val) / SHRT_MAX);
|
||||
float short2db(short val) {
|
||||
return 20 * log10(abs(val) / SHRT_MAX);
|
||||
}
|
||||
|
||||
short db2short(float db)
|
||||
{
|
||||
return pow(10, db/20.f) * SHRT_MAX;
|
||||
short db2short(float db) {
|
||||
return pow(10, db / 20.f) * SHRT_MAX;
|
||||
}
|
||||
|
||||
short short_gain(short val, float db)
|
||||
{
|
||||
return (short)(pow(10, db/20.f) * val);
|
||||
short short_gain(short val, float db) {
|
||||
return (short)(pow(10, db / 20.f) * val);
|
||||
}
|
||||
|
||||
float pct2db(float pct)
|
||||
{
|
||||
if (pct <= 0) return -72.f;
|
||||
float pct2db(float pct) {
|
||||
if (pct <= 0) return -72.f;
|
||||
|
||||
return 10*log2(pct);
|
||||
return 10 * log2(pct);
|
||||
}
|
||||
|
||||
float pct2mult(float pct)
|
||||
{
|
||||
if (pct <= 0) return 0.f;
|
||||
float pct2mult(float pct) {
|
||||
if (pct <= 0) return 0.f;
|
||||
|
||||
return pow(10, 0.5*log2(pct));
|
||||
return pow(10, 0.5 * log2(pct));
|
||||
}
|
||||
|
|
|
@ -1,263 +1,240 @@
|
|||
#include "sprite.h"
|
||||
|
||||
#include "timer.h"
|
||||
#include "render.h"
|
||||
#include "openglrender.h"
|
||||
#include "texture.h"
|
||||
#include "shader.h"
|
||||
#include "datastream.h"
|
||||
#include "gameobject.h"
|
||||
#include <string.h>
|
||||
#include "stb_ds.h"
|
||||
#include "log.h"
|
||||
#include "font.h"
|
||||
#include "gameobject.h"
|
||||
#include "log.h"
|
||||
#include "openglrender.h"
|
||||
#include "render.h"
|
||||
#include "shader.h"
|
||||
#include "stb_ds.h"
|
||||
#include "texture.h"
|
||||
#include "timer.h"
|
||||
#include <string.h>
|
||||
|
||||
struct TextureOptions TEX_SPRITE = { 1, 0, 0 };
|
||||
struct TextureOptions TEX_SPRITE = {1, 0, 0};
|
||||
|
||||
static struct sprite *sprites;
|
||||
static int first = -1;
|
||||
|
||||
sg_pipeline pip_sprite;
|
||||
sg_bindings bind_sprite;
|
||||
static sg_pipeline pip_sprite;
|
||||
static sg_bindings bind_sprite;
|
||||
static int sprite_c = 0;
|
||||
|
||||
int make_sprite(int go)
|
||||
{
|
||||
struct sprite sprite = {
|
||||
.color = {1.f, 1.f, 1.f},
|
||||
.size = {1.f, 1.f},
|
||||
.tex = texture_loadfromfile(NULL),
|
||||
.go = go,
|
||||
.next = -1,
|
||||
.layer = 0,
|
||||
.enabled = 1 };
|
||||
int make_sprite(int go) {
|
||||
struct sprite sprite = {
|
||||
.color = {1.f, 1.f, 1.f},
|
||||
.size = {1.f, 1.f},
|
||||
.tex = texture_loadfromfile(NULL),
|
||||
.go = go,
|
||||
.next = -1,
|
||||
.layer = 0,
|
||||
.enabled = 1};
|
||||
|
||||
if (first<0) {
|
||||
arrput(sprites, sprite);
|
||||
arrlast(sprites).id = arrlen(sprites)-1;
|
||||
return arrlen(sprites)-1;
|
||||
} else {
|
||||
int slot = first;
|
||||
first = id2sprite(first)->next;
|
||||
*id2sprite(slot) = sprite;
|
||||
if (first < 0) {
|
||||
arrput(sprites, sprite);
|
||||
arrlast(sprites).id = arrlen(sprites) - 1;
|
||||
return arrlen(sprites) - 1;
|
||||
} else {
|
||||
int slot = first;
|
||||
first = id2sprite(first)->next;
|
||||
*id2sprite(slot) = sprite;
|
||||
|
||||
return slot;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
void sprite_delete(int id)
|
||||
{
|
||||
struct sprite *sp = id2sprite(id);
|
||||
sp->go = -1;
|
||||
sp->next = first;
|
||||
first = id;
|
||||
void sprite_delete(int id) {
|
||||
struct sprite *sp = id2sprite(id);
|
||||
sp->go = -1;
|
||||
sp->next = first;
|
||||
first = id;
|
||||
}
|
||||
|
||||
void sprite_enabled(int id, int e)
|
||||
{
|
||||
sprites[id].enabled = e;
|
||||
void sprite_enabled(int id, int e) {
|
||||
sprites[id].enabled = e;
|
||||
}
|
||||
|
||||
struct sprite *id2sprite(int id) {
|
||||
if (id < 0) return NULL;
|
||||
return &sprites[id];
|
||||
if (id < 0) return NULL;
|
||||
return &sprites[id];
|
||||
}
|
||||
|
||||
static sprite_count = 0;
|
||||
|
||||
void sprite_flush()
|
||||
{
|
||||
void sprite_flush() {
|
||||
sprite_count = 0;
|
||||
}
|
||||
|
||||
void sprite_io(struct sprite *sprite, FILE *f, int read)
|
||||
{
|
||||
char path[100];
|
||||
if (read) {
|
||||
//fscanf(f, "%s", &path);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
path[i] = fgetc(f);
|
||||
void sprite_io(struct sprite *sprite, FILE *f, int read) {
|
||||
char path[100];
|
||||
if (read) {
|
||||
// fscanf(f, "%s", &path);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
path[i] = fgetc(f);
|
||||
|
||||
if (path[i] == '\0') break;
|
||||
}
|
||||
fread(sprite, sizeof(*sprite), 1, f);
|
||||
sprite_loadtex(sprite, path, ST_UNIT);
|
||||
} else {
|
||||
fputs(tex_get_path(sprite->tex), f);
|
||||
fputc('\0', f);
|
||||
fwrite(sprite, sizeof(*sprite), 1, f);
|
||||
if (path[i] == '\0') break;
|
||||
}
|
||||
fread(sprite, sizeof(*sprite), 1, f);
|
||||
sprite_loadtex(sprite, path, ST_UNIT);
|
||||
} else {
|
||||
fputs(tex_get_path(sprite->tex), f);
|
||||
fputc('\0', f);
|
||||
fwrite(sprite, sizeof(*sprite), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
void sprite_draw_all()
|
||||
{
|
||||
sg_apply_pipeline(pip_sprite);
|
||||
|
||||
static struct sprite **layers[5];
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
arrfree(layers[i]);
|
||||
|
||||
for (int i = 0; i < arrlen(sprites); i++) {
|
||||
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers[sprites[i].layer], &sprites[i]);
|
||||
}
|
||||
void sprite_draw_all() {
|
||||
sg_apply_pipeline(pip_sprite);
|
||||
|
||||
for (int i = 4; i >= 0; i--)
|
||||
for (int j = 0; j < arrlen(layers[i]); j++)
|
||||
sprite_draw(layers[i][j]);
|
||||
static struct sprite **layers[5];
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
arrfree(layers[i]);
|
||||
|
||||
for (int i = 0; i < arrlen(sprites); i++) {
|
||||
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers[sprites[i].layer], &sprites[i]);
|
||||
}
|
||||
|
||||
for (int i = 4; i >= 0; i--)
|
||||
for (int j = 0; j < arrlen(layers[i]); j++)
|
||||
sprite_draw(layers[i][j]);
|
||||
}
|
||||
|
||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame)
|
||||
{
|
||||
sprite->tex = texture_loadfromfile(path);
|
||||
sprite_setframe(sprite, &frame);
|
||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
|
||||
sprite->tex = texture_loadfromfile(path);
|
||||
sprite_setframe(sprite, &frame);
|
||||
}
|
||||
|
||||
void sprite_settex(struct sprite *sprite, struct Texture *tex)
|
||||
{
|
||||
sprite->tex = tex;
|
||||
sprite_setframe(sprite, &ST_UNIT);
|
||||
void sprite_settex(struct sprite *sprite, struct Texture *tex) {
|
||||
sprite->tex = tex;
|
||||
sprite_setframe(sprite, &ST_UNIT);
|
||||
}
|
||||
|
||||
sg_shader shader_sprite;
|
||||
|
||||
void sprite_initialize()
|
||||
{
|
||||
shader_sprite = sg_make_shader(&(sg_shader_desc){
|
||||
void sprite_initialize() {
|
||||
shader_sprite = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/spritevert.glsl"),
|
||||
.fs.source = slurp_text("shaders/spritefrag.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = 64,
|
||||
.layout = SG_UNIFORMLAYOUT_STD140,
|
||||
.uniforms = { [0] = { .name = "mpv", .type = SG_UNIFORMTYPE_MAT4 }}
|
||||
},
|
||||
.size = 64,
|
||||
.layout = SG_UNIFORMLAYOUT_STD140,
|
||||
.uniforms = {[0] = {.name = "mpv", .type = SG_UNIFORMTYPE_MAT4}}},
|
||||
|
||||
.fs.images[0] = {
|
||||
.name = "image",
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.sampler_type = SG_SAMPLERTYPE_FLOAT,
|
||||
.name = "image",
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.sampler_type = SG_SAMPLERTYPE_FLOAT,
|
||||
},
|
||||
|
||||
.fs.uniform_blocks[0] = {
|
||||
.size = 12,
|
||||
.uniforms = { [0] = { .name = "spriteColor", .type = SG_UNIFORMTYPE_FLOAT3 }}
|
||||
}
|
||||
});
|
||||
.fs.uniform_blocks[0] = {.size = 12, .uniforms = {[0] = {.name = "spriteColor", .type = SG_UNIFORMTYPE_FLOAT3}}}});
|
||||
|
||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = shader_sprite,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format=SG_VERTEXFORMAT_FLOAT4
|
||||
}
|
||||
},
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT4}},
|
||||
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||
.label = "sprite pipeline"
|
||||
});
|
||||
.label = "sprite pipeline"});
|
||||
|
||||
bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float)*16*500,
|
||||
bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.size = sizeof(float) * 16 * 500,
|
||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||
.usage = SG_USAGE_STREAM,
|
||||
.label = "sprite vertex buffer",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], float offset[2], struct glrect r, float color[3]) {
|
||||
float model[16] = { 0.f };
|
||||
mfloat_t r_model[16] = { 0.f };
|
||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||
memcpy(r_model, UNITMAT4, sizeof(UNITMAT4));
|
||||
float model[16] = {0.f};
|
||||
mfloat_t r_model[16] = {0.f};
|
||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||
memcpy(r_model, UNITMAT4, sizeof(UNITMAT4));
|
||||
|
||||
mfloat_t t_scale[2] = { tex->width * st_s_w(r) * size[0], tex->height * st_s_h(r) * size[1] };
|
||||
mfloat_t t_offset[2] = { offset[0] * t_scale[0] * size[0], offset[1] * t_scale[1] * size[1]};
|
||||
mfloat_t t_scale[2] = {tex->width * st_s_w(r) * size[0], tex->height * st_s_h(r) * size[1]};
|
||||
mfloat_t t_offset[2] = {offset[0] * t_scale[0] * size[0], offset[1] * t_scale[1] * size[1]};
|
||||
|
||||
mat4_translate_vec2(model, t_offset);
|
||||
mat4_translate_vec2(model, t_offset);
|
||||
|
||||
mat4_scale_vec2(model, t_scale);
|
||||
mat4_rotation_z(r_model, angle);
|
||||
mat4_scale_vec2(model, t_scale);
|
||||
mat4_rotation_z(r_model, angle);
|
||||
|
||||
mat4_multiply(model, r_model, model);
|
||||
mat4_multiply(model, r_model, model);
|
||||
|
||||
mat4_translate_vec2(model, pos);
|
||||
mat4_multiply(model, projection,model);
|
||||
|
||||
float vertices[] = {
|
||||
0.f, 0.f, r.s0, r.t1,
|
||||
1, 0.f, r.s1, r.t1,
|
||||
0.f, 1, r.s0, r.t0,
|
||||
1.f, 1.f, r.s1, r.t0
|
||||
};
|
||||
mat4_translate_vec2(model, pos);
|
||||
mat4_multiply(model, projection, model);
|
||||
|
||||
bind_sprite.fs_images[0] = tex->id;
|
||||
sg_append_buffer(bind_sprite.vertex_buffers[0], SG_RANGE_REF(vertices));
|
||||
float vertices[] = {
|
||||
0.f, 0.f, r.s0, r.t1,
|
||||
1, 0.f, r.s1, r.t1,
|
||||
0.f, 1, r.s0, r.t0,
|
||||
1.f, 1.f, r.s1, r.t0};
|
||||
|
||||
sg_apply_bindings(&bind_sprite);
|
||||
bind_sprite.fs_images[0] = tex->id;
|
||||
sg_append_buffer(bind_sprite.vertex_buffers[0], SG_RANGE_REF(vertices));
|
||||
sg_apply_bindings(&bind_sprite);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(model));
|
||||
|
||||
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(model));
|
||||
float c[3];
|
||||
for (int i = 0; i < 3; i++) c[i] = color[i];
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(c));
|
||||
sg_range c = {
|
||||
.ptr = color,
|
||||
.size = sizeof(float) * 3};
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, &c);
|
||||
|
||||
sg_draw(sprite_count*4,4,1);
|
||||
sprite_count++;
|
||||
sg_draw(sprite_count * 4, 4, 1);
|
||||
sprite_count++;
|
||||
}
|
||||
|
||||
void sprite_draw(struct sprite *sprite)
|
||||
{
|
||||
struct gameobject *go = id2go(sprite->go);
|
||||
void sprite_draw(struct sprite *sprite) {
|
||||
struct gameobject *go = id2go(sprite->go);
|
||||
|
||||
if (sprite->tex) {
|
||||
cpVect cpos = cpBodyGetPosition(go->body);
|
||||
float pos[2] = {cpos.x, cpos.y};
|
||||
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
|
||||
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame, sprite->color);
|
||||
}
|
||||
if (sprite->tex) {
|
||||
cpVect cpos = cpBodyGetPosition(go->body);
|
||||
float pos[2] = {cpos.x, cpos.y};
|
||||
float size[2] = {sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy};
|
||||
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame, sprite->color);
|
||||
}
|
||||
}
|
||||
|
||||
void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame)
|
||||
{
|
||||
if (!sprite) return;
|
||||
sprite->tex = anim->tex;
|
||||
sprite->frame = anim->st_frames[frame];
|
||||
void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame) {
|
||||
if (!sprite) return;
|
||||
sprite->tex = anim->tex;
|
||||
sprite->frame = anim->st_frames[frame];
|
||||
}
|
||||
|
||||
void gui_draw_img(const char *img, float x, float y) {
|
||||
sg_apply_pipeline(pip_sprite);
|
||||
struct Texture *tex = texture_loadfromfile(img);
|
||||
float pos[2] = {x, y};
|
||||
float size[2] = {1.f, 1.f};
|
||||
float offset[2] = { 0.f, 0.f };
|
||||
float white[3] = {0.3f,1.f,1.f};
|
||||
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
|
||||
sg_apply_pipeline(pip_sprite);
|
||||
struct Texture *tex = texture_loadfromfile(img);
|
||||
float pos[2] = {x, y};
|
||||
float size[2] = {1.f, 1.f};
|
||||
float offset[2] = {0.f, 0.f};
|
||||
float white[3] = {1.f, 1.f, 1.f};
|
||||
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
|
||||
}
|
||||
|
||||
void sprite_setframe(struct sprite *sprite, struct glrect *frame)
|
||||
{
|
||||
sprite->frame = *frame;
|
||||
void sprite_setframe(struct sprite *sprite, struct glrect *frame) {
|
||||
sprite->frame = *frame;
|
||||
}
|
||||
|
||||
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3])
|
||||
{
|
||||
shader_use(vid_shader);
|
||||
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3]) {
|
||||
shader_use(vid_shader);
|
||||
|
||||
static mfloat_t model[16];
|
||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||
mat4_translate_vec2(model, position);
|
||||
mat4_scale_vec2(model, size);
|
||||
static mfloat_t model[16];
|
||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||
mat4_translate_vec2(model, position);
|
||||
mat4_scale_vec2(model, size);
|
||||
|
||||
shader_setmat4(vid_shader, "model", model);
|
||||
shader_setvec3(vid_shader, "spriteColor", color);
|
||||
/*
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_y);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cb);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cr);
|
||||
shader_setmat4(vid_shader, "model", model);
|
||||
shader_setvec3(vid_shader, "spriteColor", color);
|
||||
/*
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_y);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cb);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cr);
|
||||
|
||||
// TODO: video bind VAO
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
*/
|
||||
// TODO: video bind VAO
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -1,208 +1,184 @@
|
|||
#include "texture.h"
|
||||
|
||||
#include "render.h"
|
||||
#include <stdio.h>
|
||||
#include <stb_image.h>
|
||||
#include <stb_ds.h>
|
||||
#include "log.h"
|
||||
#include <math.h>
|
||||
#include "util.h"
|
||||
#include "render.h"
|
||||
#include "sokol/sokol_gfx.h"
|
||||
#include "util.h"
|
||||
#include <math.h>
|
||||
#include <stb_ds.h>
|
||||
#include <stb_image.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct glrect ST_UNIT = { 0.f, 1.f, 0.f, 1.f };
|
||||
struct glrect ST_UNIT = {0.f, 1.f, 0.f, 1.f};
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
struct Texture *value;
|
||||
char *key;
|
||||
struct Texture *value;
|
||||
} *texhash = NULL;
|
||||
|
||||
struct Texture *tex_default;
|
||||
|
||||
struct Texture *texture_notex()
|
||||
{
|
||||
struct Texture *texture_notex() {
|
||||
return texture_pullfromfile("./icons/no_tex.png");
|
||||
}
|
||||
|
||||
/* If an empty string or null is put for path, loads default texture */
|
||||
struct Texture *texture_pullfromfile(const char *path)
|
||||
{
|
||||
if (!path) return texture_notex();
|
||||
|
||||
int index = shgeti(texhash, path);
|
||||
if (index != -1)
|
||||
return texhash[index].value;
|
||||
struct Texture *texture_pullfromfile(const char *path) {
|
||||
if (!path) return texture_notex();
|
||||
|
||||
YughInfo("Loading texture %s.", path);
|
||||
struct Texture *tex = calloc(1, sizeof(*tex));
|
||||
tex->opts.sprite = 1;
|
||||
tex->opts.mips = 0;
|
||||
tex->opts.gamma = 0;
|
||||
|
||||
int n;
|
||||
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||
int index = shgeti(texhash, path);
|
||||
if (index != -1)
|
||||
return texhash[index].value;
|
||||
|
||||
if (data == NULL) {
|
||||
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
||||
return texture_notex();
|
||||
}
|
||||
tex->data = data;
|
||||
YughInfo("Loading texture %s.", path);
|
||||
struct Texture *tex = calloc(1, sizeof(*tex));
|
||||
tex->opts.sprite = 1;
|
||||
tex->opts.mips = 0;
|
||||
tex->opts.gamma = 0;
|
||||
|
||||
int filter;
|
||||
if (tex->opts.sprite) {
|
||||
if (tex->opts.mips)
|
||||
filter = SG_FILTER_NEAREST_MIPMAP_NEAREST;
|
||||
else
|
||||
filter = SG_FILTER_NEAREST;
|
||||
} else {
|
||||
if (tex->opts.mips)
|
||||
filter = SG_FILTER_LINEAR_MIPMAP_LINEAR;
|
||||
else
|
||||
filter = SG_FILTER_LINEAR;
|
||||
}
|
||||
int n;
|
||||
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||
|
||||
tex->id = sg_make_image(&(sg_image_desc){
|
||||
if (data == NULL) {
|
||||
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
||||
return texture_notex();
|
||||
}
|
||||
tex->data = data;
|
||||
|
||||
int filter;
|
||||
if (tex->opts.sprite) {
|
||||
filter = SG_FILTER_NEAREST;
|
||||
} else {
|
||||
filter = SG_FILTER_LINEAR;
|
||||
}
|
||||
|
||||
tex->id = sg_make_image(&(sg_image_desc){
|
||||
.type = SG_IMAGETYPE_2D,
|
||||
.width = tex->width,
|
||||
.height = tex->height,
|
||||
.usage = SG_USAGE_IMMUTABLE,
|
||||
.min_filter = filter,
|
||||
.mag_filter = filter,
|
||||
.max_anisotropy = 16,
|
||||
.data.subimage[0][0] = {
|
||||
.ptr = data,
|
||||
.size = tex->width*tex->height*4
|
||||
}
|
||||
});
|
||||
|
||||
.ptr = data,
|
||||
.size = tex->width * tex->height * 4}});
|
||||
|
||||
if (shlen(texhash) == 0)
|
||||
sh_new_arena(texhash);
|
||||
if (shlen(texhash) == 0)
|
||||
sh_new_arena(texhash);
|
||||
|
||||
shput(texhash, path, tex);
|
||||
shput(texhash, path, tex);
|
||||
|
||||
return tex;
|
||||
return tex;
|
||||
}
|
||||
|
||||
void texture_sync(const char *path)
|
||||
{
|
||||
void texture_sync(const char *path) {
|
||||
YughWarn("Need to implement texture sync.");
|
||||
}
|
||||
|
||||
char *tex_get_path(struct Texture *tex) {
|
||||
for (int i = 0; i < shlen(texhash); i++) {
|
||||
if (tex == texhash[i].value) {
|
||||
YughInfo("Found key %s", texhash[i].key);
|
||||
return texhash[i].key;
|
||||
}
|
||||
for (int i = 0; i < shlen(texhash); i++) {
|
||||
if (tex == texhash[i].value) {
|
||||
YughInfo("Found key %s", texhash[i].key);
|
||||
return texhash[i].key;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Texture *texture_loadfromfile(const char *path)
|
||||
{
|
||||
struct Texture *new = texture_pullfromfile(path);
|
||||
/*
|
||||
if (new->id == 0) {
|
||||
glGenTextures(1, &new->id);
|
||||
struct Texture *texture_loadfromfile(const char *path) {
|
||||
struct Texture *new = texture_pullfromfile(path);
|
||||
/*
|
||||
if (new->id == 0) {
|
||||
glGenTextures(1, &new->id);
|
||||
|
||||
//tex_gpu_load(new);
|
||||
//tex_gpu_load(new);
|
||||
|
||||
YughInfo("Loaded texture path %s", path);
|
||||
}
|
||||
*/
|
||||
return new;
|
||||
YughInfo("Loaded texture path %s", path);
|
||||
}
|
||||
*/
|
||||
return new;
|
||||
}
|
||||
|
||||
void tex_gpu_reload(struct Texture *tex)
|
||||
{
|
||||
tex_gpu_free(tex);
|
||||
void tex_gpu_reload(struct Texture *tex) {
|
||||
tex_gpu_free(tex);
|
||||
|
||||
//tex_gpu_load(tex);
|
||||
// tex_gpu_load(tex);
|
||||
}
|
||||
|
||||
void anim_calc(struct anim2d *anim)
|
||||
{
|
||||
anim->size[0] = anim->anim->tex->width * st_s_w(anim->anim->st_frames[anim->frame]);
|
||||
anim->size[1] = anim->anim->tex->height * st_s_h(anim->anim->st_frames[anim->frame]);
|
||||
void anim_calc(struct anim2d *anim) {
|
||||
anim->size[0] = anim->anim->tex->width * st_s_w(anim->anim->st_frames[anim->frame]);
|
||||
anim->size[1] = anim->anim->tex->height * st_s_h(anim->anim->st_frames[anim->frame]);
|
||||
}
|
||||
|
||||
void anim_incr(struct anim2d *anim)
|
||||
{
|
||||
anim->frame = (anim->frame + 1) % arrlen(anim->anim->st_frames);
|
||||
void anim_incr(struct anim2d *anim) {
|
||||
anim->frame = (anim->frame + 1) % arrlen(anim->anim->st_frames);
|
||||
|
||||
if (!anim->anim->loop && anim->frame == arrlen(anim->anim->st_frames))
|
||||
anim_pause(anim);
|
||||
if (!anim->anim->loop && anim->frame == arrlen(anim->anim->st_frames))
|
||||
anim_pause(anim);
|
||||
|
||||
anim_calc(anim);
|
||||
anim_calc(anim);
|
||||
}
|
||||
|
||||
void anim_decr(struct anim2d *anim)
|
||||
{
|
||||
anim->frame = (anim->frame + arrlen(anim->anim->st_frames) - 1) % arrlen(anim->anim->st_frames);
|
||||
anim_calc(anim);
|
||||
void anim_decr(struct anim2d *anim) {
|
||||
anim->frame = (anim->frame + arrlen(anim->anim->st_frames) - 1) % arrlen(anim->anim->st_frames);
|
||||
anim_calc(anim);
|
||||
}
|
||||
|
||||
struct glrect anim_get_rect(struct anim2d *anim)
|
||||
{
|
||||
return anim->anim->st_frames[anim->frame];
|
||||
struct glrect anim_get_rect(struct anim2d *anim) {
|
||||
return anim->anim->st_frames[anim->frame];
|
||||
}
|
||||
|
||||
void anim_setframe(struct anim2d *anim, int frame)
|
||||
{
|
||||
anim->frame = frame;
|
||||
anim_calc(anim);
|
||||
void anim_setframe(struct anim2d *anim, int frame) {
|
||||
anim->frame = frame;
|
||||
anim_calc(anim);
|
||||
}
|
||||
|
||||
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps)
|
||||
{
|
||||
struct TexAnim *anim = malloc(sizeof(*anim));
|
||||
anim->tex = texture_loadfromfile(path);
|
||||
texanim_fromframes(anim, frames);
|
||||
anim->ms = (float)1/fps;
|
||||
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps) {
|
||||
struct TexAnim *anim = malloc(sizeof(*anim));
|
||||
anim->tex = texture_loadfromfile(path);
|
||||
texanim_fromframes(anim, frames);
|
||||
anim->ms = (float)1 / fps;
|
||||
|
||||
return anim;
|
||||
return anim;
|
||||
}
|
||||
|
||||
void texanim_fromframes(struct TexAnim *anim, int frames)
|
||||
{
|
||||
if (anim->st_frames) {
|
||||
free(anim->st_frames);
|
||||
}
|
||||
void texanim_fromframes(struct TexAnim *anim, int frames) {
|
||||
if (anim->st_frames) {
|
||||
free(anim->st_frames);
|
||||
}
|
||||
|
||||
arrsetlen(anim->st_frames, frames);
|
||||
arrsetlen(anim->st_frames, frames);
|
||||
|
||||
float width = (float)1/frames;
|
||||
float width = (float)1 / frames;
|
||||
|
||||
for (int i = 0; i < frames; i++) {
|
||||
anim->st_frames[i].s0 = width*i;
|
||||
anim->st_frames[i].s1 = width*(i+1);
|
||||
anim->st_frames[i].t0 = 0.f;
|
||||
anim->st_frames[i].t1 = 1.f;
|
||||
}
|
||||
for (int i = 0; i < frames; i++) {
|
||||
anim->st_frames[i].s0 = width * i;
|
||||
anim->st_frames[i].s1 = width * (i + 1);
|
||||
anim->st_frames[i].t0 = 0.f;
|
||||
anim->st_frames[i].t1 = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void tex_gpu_free(struct Texture *tex)
|
||||
{
|
||||
/*
|
||||
if (tex->id != 0) {
|
||||
glDeleteTextures(1, &tex->id);
|
||||
tex->id = 0;
|
||||
}
|
||||
*/
|
||||
void tex_gpu_free(struct Texture *tex) {
|
||||
/*
|
||||
if (tex->id != 0) {
|
||||
glDeleteTextures(1, &tex->id);
|
||||
tex->id = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int anim_frames(struct TexAnim *a)
|
||||
{
|
||||
return arrlen(a->st_frames);
|
||||
int anim_frames(struct TexAnim *a) {
|
||||
return arrlen(a->st_frames);
|
||||
}
|
||||
|
||||
struct glrect tex_get_rect(struct Texture *tex)
|
||||
{
|
||||
return ST_UNIT;
|
||||
struct glrect tex_get_rect(struct Texture *tex) {
|
||||
return ST_UNIT;
|
||||
}
|
||||
|
||||
cpVect tex_get_dimensions(struct Texture *tex)
|
||||
{
|
||||
cpVect tex_get_dimensions(struct Texture *tex) {
|
||||
if (!tex) return cpvzero;
|
||||
cpVect d;
|
||||
d.x = tex->width;
|
||||
|
@ -210,78 +186,69 @@ cpVect tex_get_dimensions(struct Texture *tex)
|
|||
return d;
|
||||
}
|
||||
|
||||
void tex_bind(struct Texture *tex)
|
||||
{
|
||||
/* glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex->id);
|
||||
*/
|
||||
void tex_bind(struct Texture *tex) {
|
||||
/* glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex->id);
|
||||
*/
|
||||
}
|
||||
|
||||
/********************** ANIM2D ****************/
|
||||
|
||||
void anim_load(struct anim2d *anim, const char *path)
|
||||
{
|
||||
anim->anim = &texture_pullfromfile(path)->anim;
|
||||
anim->anim->tex->opts.animation = 1;
|
||||
anim_stop(anim);
|
||||
anim_play(anim);
|
||||
void anim_load(struct anim2d *anim, const char *path) {
|
||||
anim->anim = &texture_pullfromfile(path)->anim;
|
||||
anim->anim->tex->opts.animation = 1;
|
||||
anim_stop(anim);
|
||||
anim_play(anim);
|
||||
}
|
||||
|
||||
void anim_play(struct anim2d *anim)
|
||||
{
|
||||
if (anim->playing)
|
||||
return;
|
||||
void anim_play(struct anim2d *anim) {
|
||||
if (anim->playing)
|
||||
return;
|
||||
|
||||
if (anim->frame == anim_frames(anim->anim))
|
||||
anim->frame = 0;
|
||||
|
||||
anim->playing = 1;
|
||||
|
||||
if (anim->timer == NULL)
|
||||
anim->timer = id2timer(timer_make(1.f / anim->anim->ms, anim_incr, anim, 0));
|
||||
else
|
||||
timerr_settime(anim->timer, 1.f/anim->anim->ms);
|
||||
|
||||
timer_start(anim->timer);
|
||||
}
|
||||
|
||||
void anim_stop(struct anim2d *anim)
|
||||
{
|
||||
if (!anim->playing)
|
||||
return;
|
||||
|
||||
anim->playing = 0;
|
||||
if (anim->frame == anim_frames(anim->anim))
|
||||
anim->frame = 0;
|
||||
anim->pausetime = 0;
|
||||
timer_stop(anim->timer);
|
||||
|
||||
anim->playing = 1;
|
||||
|
||||
if (anim->timer == NULL)
|
||||
anim->timer = id2timer(timer_make(1.f / anim->anim->ms, anim_incr, anim, 0));
|
||||
else
|
||||
timerr_settime(anim->timer, 1.f / anim->anim->ms);
|
||||
|
||||
timer_start(anim->timer);
|
||||
}
|
||||
|
||||
void anim_pause(struct anim2d *anim)
|
||||
{
|
||||
if (!anim->playing)
|
||||
return;
|
||||
void anim_stop(struct anim2d *anim) {
|
||||
if (!anim->playing)
|
||||
return;
|
||||
|
||||
anim->playing = 0;
|
||||
timer_pause(anim->timer);
|
||||
anim->playing = 0;
|
||||
anim->frame = 0;
|
||||
anim->pausetime = 0;
|
||||
timer_stop(anim->timer);
|
||||
}
|
||||
|
||||
void anim_fwd(struct anim2d *anim)
|
||||
{
|
||||
anim_incr(anim);
|
||||
void anim_pause(struct anim2d *anim) {
|
||||
if (!anim->playing)
|
||||
return;
|
||||
|
||||
anim->playing = 0;
|
||||
timer_pause(anim->timer);
|
||||
}
|
||||
|
||||
void anim_bkwd(struct anim2d *anim)
|
||||
{
|
||||
anim_decr(anim);
|
||||
void anim_fwd(struct anim2d *anim) {
|
||||
anim_incr(anim);
|
||||
}
|
||||
|
||||
float st_s_w(struct glrect st)
|
||||
{
|
||||
return (st.s1 - st.s0);
|
||||
void anim_bkwd(struct anim2d *anim) {
|
||||
anim_decr(anim);
|
||||
}
|
||||
|
||||
float st_s_h(struct glrect st)
|
||||
{
|
||||
return (st.t1 - st.t0);
|
||||
float st_s_w(struct glrect st) {
|
||||
return (st.s1 - st.s0);
|
||||
}
|
||||
|
||||
float st_s_h(struct glrect st) {
|
||||
return (st.t1 - st.t0);
|
||||
}
|
||||
|
|
73
source/engine/thirdparty/Nuklear/nuklear.h
vendored
73
source/engine/thirdparty/Nuklear/nuklear.h
vendored
|
@ -372,7 +372,7 @@ extern "C" {
|
|||
#elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
|
||||
#define NK_SIZE_TYPE unsigned __int32
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#if defined(__x86_64__) || defined(__ppc64__)
|
||||
#if defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__)
|
||||
#define NK_SIZE_TYPE unsigned long
|
||||
#else
|
||||
#define NK_SIZE_TYPE unsigned int
|
||||
|
@ -387,7 +387,7 @@ extern "C" {
|
|||
#elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
|
||||
#define NK_POINTER_TYPE unsigned __int32
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#if defined(__x86_64__) || defined(__ppc64__)
|
||||
#if defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__)
|
||||
#define NK_POINTER_TYPE unsigned long
|
||||
#else
|
||||
#define NK_POINTER_TYPE unsigned int
|
||||
|
@ -432,8 +432,8 @@ NK_STATIC_ASSERT(sizeof(nk_int) == 4);
|
|||
NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
|
||||
NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
|
||||
NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
|
||||
//NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
|
||||
//NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
|
||||
NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
|
||||
NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
|
||||
#ifdef NK_INCLUDE_STANDARD_BOOL
|
||||
NK_STATIC_ASSERT(sizeof(nk_bool) == sizeof(bool));
|
||||
#else
|
||||
|
@ -1127,7 +1127,7 @@ NK_API void nk_input_end(struct nk_context*);
|
|||
/// cfg.curve_segment_count = 22;
|
||||
/// cfg.arc_segment_count = 22;
|
||||
/// cfg.global_alpha = 1.0f;
|
||||
/// cfg.null = dev->null;
|
||||
/// cfg.tex_null = dev->tex_null;
|
||||
/// //
|
||||
/// // setup buffers and convert
|
||||
/// struct nk_buffer cmds, verts, idx;
|
||||
|
@ -1177,7 +1177,7 @@ struct nk_convert_config {
|
|||
unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
|
||||
unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
|
||||
unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
|
||||
struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
|
||||
struct nk_draw_null_texture tex_null; /* handle to texture with a white pixel for shape drawing */
|
||||
const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
|
||||
nk_size vertex_size; /* sizeof one vertex for vertex packing */
|
||||
nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
|
||||
|
@ -6078,7 +6078,6 @@ NK_LIB void nk_property(struct nk_context *ctx, const char *name, struct nk_prop
|
|||
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STBTT_STATIC
|
||||
|
||||
/* Allow consumer to define own STBTT_malloc/STBTT_free, and use the font atlas' allocator otherwise */
|
||||
#ifndef STBTT_malloc
|
||||
|
@ -8440,7 +8439,6 @@ nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
|
|||
NK_API int
|
||||
nk_str_append_str_utf8(struct nk_str *str, const char *text)
|
||||
{
|
||||
int runes = 0;
|
||||
int byte_len = 0;
|
||||
int num_runes = 0;
|
||||
int glyph_len = 0;
|
||||
|
@ -8454,7 +8452,7 @@ nk_str_append_str_utf8(struct nk_str *str, const char *text)
|
|||
num_runes++;
|
||||
}
|
||||
nk_str_append_text_char(str, text, byte_len);
|
||||
return runes;
|
||||
return num_runes;
|
||||
}
|
||||
NK_API int
|
||||
nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
|
||||
|
@ -8569,7 +8567,6 @@ nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
|
|||
NK_API int
|
||||
nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
|
||||
{
|
||||
int runes = 0;
|
||||
int byte_len = 0;
|
||||
int num_runes = 0;
|
||||
int glyph_len = 0;
|
||||
|
@ -8583,7 +8580,7 @@ nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
|
|||
num_runes++;
|
||||
}
|
||||
nk_str_insert_at_rune(str, pos, text, byte_len);
|
||||
return runes;
|
||||
return num_runes;
|
||||
}
|
||||
NK_API int
|
||||
nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
|
||||
|
@ -9564,7 +9561,7 @@ nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
|
|||
NK_ASSERT(list);
|
||||
if (!list) return;
|
||||
if (!list->cmd_count) {
|
||||
nk_draw_list_push_command(list, rect, list->config.null.texture);
|
||||
nk_draw_list_push_command(list, rect, list->config.tex_null.texture);
|
||||
} else {
|
||||
struct nk_draw_command *prev = nk_draw_list_command_last(list);
|
||||
if (prev->elem_count == 0)
|
||||
|
@ -9919,7 +9916,7 @@ nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *p
|
|||
|
||||
/* fill vertices */
|
||||
for (i = 0; i < points_count; ++i) {
|
||||
const struct nk_vec2 uv = list->config.null.uv;
|
||||
const struct nk_vec2 uv = list->config.tex_null.uv;
|
||||
vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
|
||||
|
@ -9984,7 +9981,7 @@ nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *p
|
|||
|
||||
/* add vertices */
|
||||
for (i = 0; i < points_count; ++i) {
|
||||
const struct nk_vec2 uv = list->config.null.uv;
|
||||
const struct nk_vec2 uv = list->config.tex_null.uv;
|
||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
|
||||
|
@ -10005,7 +10002,7 @@ nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *p
|
|||
|
||||
for (i1 = 0; i1 < count; ++i1) {
|
||||
float dx, dy;
|
||||
const struct nk_vec2 uv = list->config.null.uv;
|
||||
const struct nk_vec2 uv = list->config.tex_null.uv;
|
||||
const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
|
||||
const struct nk_vec2 p1 = points[i1];
|
||||
const struct nk_vec2 p2 = points[i2];
|
||||
|
@ -10115,7 +10112,7 @@ nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
|
|||
|
||||
/* add vertices + indexes */
|
||||
for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
|
||||
const struct nk_vec2 uv = list->config.null.uv;
|
||||
const struct nk_vec2 uv = list->config.tex_null.uv;
|
||||
struct nk_vec2 n0 = normals[i0];
|
||||
struct nk_vec2 n1 = normals[i1];
|
||||
struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
|
||||
|
@ -10152,7 +10149,7 @@ nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
|
|||
|
||||
if (!vtx || !ids) return;
|
||||
for (i = 0; i < vtx_count; ++i)
|
||||
vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.tex_null.uv, col);
|
||||
for (i = 2; i < points_count; ++i) {
|
||||
ids[0] = (nk_draw_index)index;
|
||||
ids[1] = (nk_draw_index)(index+ i - 1);
|
||||
|
@ -10181,8 +10178,8 @@ nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
|
|||
nk_draw_list_add_clip(list, nk_null_rect);
|
||||
|
||||
cmd = nk_draw_list_command_last(list);
|
||||
if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
|
||||
nk_draw_list_push_image(list, list->config.null.texture);
|
||||
if (cmd && cmd->texture.ptr != list->config.tex_null.texture.ptr)
|
||||
nk_draw_list_push_image(list, list->config.tex_null.texture);
|
||||
|
||||
points = nk_draw_list_alloc_path(list, 1);
|
||||
if (!points) return;
|
||||
|
@ -10384,7 +10381,7 @@ nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rec
|
|||
NK_ASSERT(list);
|
||||
if (!list) return;
|
||||
|
||||
nk_draw_list_push_image(list, list->config.null.texture);
|
||||
nk_draw_list_push_image(list, list->config.tex_null.texture);
|
||||
index = (nk_draw_index)list->vertex_count;
|
||||
vtx = nk_draw_list_alloc_vertices(list, 4);
|
||||
idx = nk_draw_list_alloc_elements(list, 6);
|
||||
|
@ -10394,10 +10391,10 @@ nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rec
|
|||
idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
|
||||
idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
|
||||
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.tex_null.uv, col_left);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.tex_null.uv, col_top);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.tex_null.uv, col_right);
|
||||
vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.tex_null.uv, col_bottom);
|
||||
}
|
||||
NK_API void
|
||||
nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
|
||||
|
@ -16513,7 +16510,7 @@ nk_font_chinese_glyph_ranges(void)
|
|||
0x3000, 0x30FF,
|
||||
0x31F0, 0x31FF,
|
||||
0xFF00, 0xFFEF,
|
||||
0x4e00, 0x9FAF,
|
||||
0x4E00, 0x9FAF,
|
||||
0
|
||||
};
|
||||
return ranges;
|
||||
|
@ -16622,7 +16619,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
|
|||
struct stbtt_fontinfo *font_info = &baker->build[i++].info;
|
||||
font_info->userdata = alloc;
|
||||
|
||||
if (!stbtt_InitFont(font_info, (const unsigned char*)it->ttf_blob, 0))
|
||||
if (!stbtt_InitFont(font_info, (const unsigned char*)it->ttf_blob, stbtt_GetFontOffsetForIndex((const unsigned char*)it->ttf_blob, 0)))
|
||||
return nk_false;
|
||||
} while ((it = it->n) != config_iter);
|
||||
}
|
||||
|
@ -17704,20 +17701,20 @@ failed:
|
|||
}
|
||||
NK_API void
|
||||
nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
|
||||
struct nk_draw_null_texture *null)
|
||||
struct nk_draw_null_texture *tex_null)
|
||||
{
|
||||
int i = 0;
|
||||
struct nk_font *font_iter;
|
||||
NK_ASSERT(atlas);
|
||||
if (!atlas) {
|
||||
if (!null) return;
|
||||
null->texture = texture;
|
||||
null->uv = nk_vec2(0.5f,0.5f);
|
||||
if (!tex_null) return;
|
||||
tex_null->texture = texture;
|
||||
tex_null->uv = nk_vec2(0.5f,0.5f);
|
||||
}
|
||||
if (null) {
|
||||
null->texture = texture;
|
||||
null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
|
||||
null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
|
||||
if (tex_null) {
|
||||
tex_null->texture = texture;
|
||||
tex_null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
|
||||
tex_null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
|
||||
}
|
||||
for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
|
||||
font_iter->texture = texture;
|
||||
|
@ -26163,7 +26160,7 @@ nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len)
|
|||
text+text_len, 1))
|
||||
{
|
||||
nk_textedit_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
state->cursor = NK_MIN(state->cursor + 1, state->string.len);
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
|
@ -29657,6 +29654,12 @@ nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
|
|||
/// - [y]: Minor version with non-breaking API and library changes
|
||||
/// - [z]: Patch version with no direct changes to the API
|
||||
///
|
||||
/// - 2022/12/17 (4.10.5) - Fix nk_font_bake_pack() using TTC font offset incorrectly
|
||||
/// - 2022/10/24 (4.10.4) - Fix nk_str_{append,insert}_str_utf8 always returning 0
|
||||
/// - 2022/09/03 (4.10.3) - Renamed the `null` texture variable to `tex_null`
|
||||
/// - 2022/08/01 (4.10.2) - Fix Apple Silicon with incorrect NK_SITE_TYPE and NK_POINTER_TYPE
|
||||
/// - 2022/08/01 (4.10.1) - Fix cursor jumping back to beginning of text when typing more than
|
||||
/// nk_edit_xxx limit
|
||||
/// - 2022/05/27 (4.10.0) - Add nk_input_has_mouse_click_in_button_rect() to fix window move bug
|
||||
/// - 2022/04/18 (4.9.7) - Change button behavior when NK_BUTTON_TRIGGER_ON_RELEASE is defined to
|
||||
/// only trigger when the mouse position was inside the same button on down
|
||||
|
|
500
source/engine/thirdparty/Nuklear/nuklear_glfw_gl3.h
vendored
500
source/engine/thirdparty/Nuklear/nuklear_glfw_gl3.h
vendored
|
@ -1,500 +0,0 @@
|
|||
/*
|
||||
* Nuklear - 1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL3_H_
|
||||
#define NK_GLFW_GL3_H_
|
||||
|
||||
#include <glad/gl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT=0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
GLuint vbo, vao, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
GLuint frag_shdr;
|
||||
GLint attrib_pos;
|
||||
GLint attrib_uv;
|
||||
GLint attrib_col;
|
||||
GLint uniform_tex;
|
||||
GLint uniform_proj;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
struct nk_glfw {
|
||||
GLFWwindow *win;
|
||||
int width, height;
|
||||
int display_width, display_height;
|
||||
struct nk_glfw_device ogl;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_vec2 fb_scale;
|
||||
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||
int text_len;
|
||||
struct nk_vec2 scroll;
|
||||
double last_button_click;
|
||||
int is_double_click_down;
|
||||
struct nk_vec2 double_click_pos;
|
||||
};
|
||||
|
||||
NK_API struct nk_context* nk_glfw3_init(struct nk_glfw* glfw, GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_shutdown(struct nk_glfw* glfw);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_glfw* glfw, struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(struct nk_glfw* glfw);
|
||||
NK_API void nk_glfw3_new_frame(struct nk_glfw* glfw);
|
||||
NK_API void nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
|
||||
|
||||
NK_API void nk_glfw3_device_destroy(struct nk_glfw* glfw);
|
||||
NK_API void nk_glfw3_device_create(struct nk_glfw* glfw);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
NK_API void nk_glfw3_mouse_button_callback(GLFWwindow *win, int button, int action, int mods);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL3_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_LO
|
||||
#define NK_GLFW_DOUBLE_CLICK_LO 0.02
|
||||
#endif
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_HI
|
||||
#define NK_GLFW_DOUBLE_CLICK_HI 0.2
|
||||
#endif
|
||||
|
||||
struct nk_glfw_vertex {
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define NK_SHADER_VERSION "#version 150\n"
|
||||
#else
|
||||
#define NK_SHADER_VERSION "#version 300 es\n"
|
||||
#endif
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_device_create(struct nk_glfw* glfw)
|
||||
{
|
||||
GLint status;
|
||||
static const GLchar *vertex_shader =
|
||||
NK_SHADER_VERSION
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 TexCoord;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main() {\n"
|
||||
" Frag_UV = TexCoord;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"
|
||||
"}\n";
|
||||
static const GLchar *fragment_shader =
|
||||
NK_SHADER_VERSION
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"out vec4 Out_Color;\n"
|
||||
"void main(){\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
struct nk_glfw_device *dev = &glfw->ogl;
|
||||
nk_buffer_init_default(&dev->cmds);
|
||||
dev->prog = glCreateProgram();
|
||||
dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER);
|
||||
dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0);
|
||||
glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0);
|
||||
glCompileShader(dev->vert_shdr);
|
||||
glCompileShader(dev->frag_shdr);
|
||||
glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
|
||||
assert(status == GL_TRUE);
|
||||
glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status);
|
||||
assert(status == GL_TRUE);
|
||||
glAttachShader(dev->prog, dev->vert_shdr);
|
||||
glAttachShader(dev->prog, dev->frag_shdr);
|
||||
glLinkProgram(dev->prog);
|
||||
glGetProgramiv(dev->prog, GL_LINK_STATUS, &status);
|
||||
assert(status == GL_TRUE);
|
||||
|
||||
dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture");
|
||||
dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx");
|
||||
dev->attrib_pos = glGetAttribLocation(dev->prog, "Position");
|
||||
dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord");
|
||||
dev->attrib_col = glGetAttribLocation(dev->prog, "Color");
|
||||
|
||||
{
|
||||
/* buffer setup */
|
||||
GLsizei vs = sizeof(struct nk_glfw_vertex);
|
||||
size_t vp = offsetof(struct nk_glfw_vertex, position);
|
||||
size_t vt = offsetof(struct nk_glfw_vertex, uv);
|
||||
size_t vc = offsetof(struct nk_glfw_vertex, col);
|
||||
|
||||
glGenBuffers(1, &dev->vbo);
|
||||
glGenBuffers(1, &dev->ebo);
|
||||
glGenVertexArrays(1, &dev->vao);
|
||||
|
||||
glBindVertexArray(dev->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
|
||||
|
||||
glEnableVertexAttribArray((GLuint)dev->attrib_pos);
|
||||
glEnableVertexAttribArray((GLuint)dev->attrib_uv);
|
||||
glEnableVertexAttribArray((GLuint)dev->attrib_col);
|
||||
|
||||
glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp);
|
||||
glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt);
|
||||
glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_device_upload_atlas(struct nk_glfw* glfw, const void *image, int width, int height)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw->ogl;
|
||||
glGenTextures(1, &dev->font_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_device_destroy(struct nk_glfw* glfw)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw->ogl;
|
||||
glDetachShader(dev->prog, dev->vert_shdr);
|
||||
glDetachShader(dev->prog, dev->frag_shdr);
|
||||
glDeleteShader(dev->vert_shdr);
|
||||
glDeleteShader(dev->frag_shdr);
|
||||
glDeleteProgram(dev->prog);
|
||||
glDeleteTextures(1, &dev->font_tex);
|
||||
glDeleteBuffers(1, &dev->vbo);
|
||||
glDeleteBuffers(1, &dev->ebo);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw->ogl;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
GLfloat ortho[4][4] = {
|
||||
{2.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f,-2.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f,-1.0f, 0.0f},
|
||||
{-1.0f,1.0f, 0.0f, 1.0f},
|
||||
};
|
||||
ortho[0][0] /= (GLfloat)glfw->width;
|
||||
ortho[1][1] /= (GLfloat)glfw->height;
|
||||
|
||||
/* setup global state */
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
/* setup program */
|
||||
glUseProgram(dev->prog);
|
||||
glUniform1i(dev->uniform_tex, 0);
|
||||
glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]);
|
||||
glViewport(0,0,(GLsizei)glfw->display_width,(GLsizei)glfw->display_height);
|
||||
{
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
const struct nk_draw_command *cmd;
|
||||
void *vertices, *elements;
|
||||
const nk_draw_index *offset = NULL;
|
||||
|
||||
/* allocate vertex and element buffer */
|
||||
glBindVertexArray(dev->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW);
|
||||
|
||||
/* load draw vertices & elements directly into vertex + element buffer */
|
||||
vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
{
|
||||
/* fill convert configuration */
|
||||
struct nk_convert_config config;
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
|
||||
/* setup buffers to load vertices and elements */
|
||||
nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer);
|
||||
nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer);
|
||||
nk_convert(&glfw->ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, &glfw->ctx, &dev->cmds)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor(
|
||||
(GLint)(cmd->clip_rect.x * glfw->fb_scale.x),
|
||||
(GLint)((glfw->height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw->fb_scale.y),
|
||||
(GLint)(cmd->clip_rect.w * glfw->fb_scale.x),
|
||||
(GLint)(cmd->clip_rect.h * glfw->fb_scale.y));
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
nk_clear(&glfw->ctx);
|
||||
nk_buffer_clear(&dev->cmds);
|
||||
}
|
||||
|
||||
/* default OpenGL state */
|
||||
glUseProgram(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
|
||||
{
|
||||
struct nk_glfw* glfw = glfwGetWindowUserPointer(win);
|
||||
if (glfw->text_len < NK_GLFW_TEXT_MAX)
|
||||
glfw->text[glfw->text_len++] = codepoint;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||
{
|
||||
struct nk_glfw* glfw = glfwGetWindowUserPointer(win);
|
||||
(void)xoff;
|
||||
glfw->scroll.x += (float)xoff;
|
||||
glfw->scroll.y += (float)yoff;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_mouse_button_callback(GLFWwindow* win, int button, int action, int mods)
|
||||
{
|
||||
struct nk_glfw* glfw = glfwGetWindowUserPointer(win);
|
||||
double x, y;
|
||||
NK_UNUSED(mods);
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
double dt = glfwGetTime() - glfw->last_button_click;
|
||||
if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
|
||||
glfw->is_double_click_down = nk_true;
|
||||
glfw->double_click_pos = nk_vec2((float)x, (float)y);
|
||||
}
|
||||
glfw->last_button_click = glfwGetTime();
|
||||
} else glfw->is_double_click_down = nk_false;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
struct nk_glfw* glfw = (struct nk_glfw*)usr.ptr;
|
||||
const char *text = glfwGetClipboardString(glfw->win);
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
struct nk_glfw* glfw = (struct nk_glfw*)usr.ptr;
|
||||
char *str = 0;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
memcpy(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
glfwSetClipboardString(glfw->win, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_glfw3_init(struct nk_glfw* glfw, GLFWwindow *win, enum nk_glfw_init_state init_state)
|
||||
{
|
||||
glfwSetWindowUserPointer(win, glfw);
|
||||
glfw->win = win;
|
||||
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
||||
}
|
||||
nk_init_default(&glfw->ctx, 0);
|
||||
glfw->ctx.clip.copy = nk_glfw3_clipboard_copy;
|
||||
glfw->ctx.clip.paste = nk_glfw3_clipboard_paste;
|
||||
glfw->ctx.clip.userdata = nk_handle_ptr(&glfw);
|
||||
glfw->last_button_click = 0;
|
||||
nk_glfw3_device_create(glfw);
|
||||
|
||||
glfw->is_double_click_down = nk_false;
|
||||
glfw->double_click_pos = nk_vec2(0, 0);
|
||||
|
||||
return &glfw->ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_begin(struct nk_glfw* glfw, struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&glfw->atlas);
|
||||
nk_font_atlas_begin(&glfw->atlas);
|
||||
*atlas = &glfw->atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_end(struct nk_glfw* glfw)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw->atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(glfw, image, w, h);
|
||||
nk_font_atlas_end(&glfw->atlas, nk_handle_id((int)glfw->ogl.font_tex), &glfw->ogl.null);
|
||||
if (glfw->atlas.default_font)
|
||||
nk_style_set_font(&glfw->ctx, &glfw->atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_new_frame(struct nk_glfw* glfw)
|
||||
{
|
||||
int i;
|
||||
double x, y;
|
||||
struct nk_context *ctx = &glfw->ctx;
|
||||
struct GLFWwindow *win = glfw->win;
|
||||
|
||||
glfwGetWindowSize(win, &glfw->width, &glfw->height);
|
||||
glfwGetFramebufferSize(win, &glfw->display_width, &glfw->display_height);
|
||||
glfw->fb_scale.x = (float)glfw->display_width/(float)glfw->width;
|
||||
glfw->fb_scale.y = (float)glfw->display_height/(float)glfw->height;
|
||||
|
||||
nk_input_begin(ctx);
|
||||
for (i = 0; i < glfw->text_len; ++i)
|
||||
nk_input_unicode(ctx, glfw->text[i]);
|
||||
|
||||
#ifdef NK_GLFW_GL3_MOUSE_GRABBING
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
else if (ctx->input.mouse.ungrab)
|
||||
glfwSetInputMode(glfw->win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
#endif
|
||||
|
||||
nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
|
||||
|
||||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
|
||||
} else {
|
||||
nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_COPY, 0);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, 0);
|
||||
nk_input_key(ctx, NK_KEY_CUT, 0);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, 0);
|
||||
}
|
||||
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
nk_input_motion(ctx, (int)x, (int)y);
|
||||
#ifdef NK_GLFW_GL3_MOUSE_GRABBING
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
glfwSetCursorPos(glfw->win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y);
|
||||
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
|
||||
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
|
||||
}
|
||||
#endif
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw->double_click_pos.x, (int)glfw->double_click_pos.y, glfw->is_double_click_down);
|
||||
nk_input_scroll(ctx, glfw->scroll);
|
||||
nk_input_end(&glfw->ctx);
|
||||
glfw->text_len = 0;
|
||||
glfw->scroll = nk_vec2(0,0);
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_glfw3_shutdown(struct nk_glfw* glfw)
|
||||
{
|
||||
nk_font_atlas_clear(&glfw->atlas);
|
||||
nk_free(&glfw->ctx);
|
||||
nk_glfw3_device_destroy(glfw);
|
||||
memset(glfw, 0, sizeof(*glfw));
|
||||
}
|
||||
|
||||
#endif
|
1148
source/engine/thirdparty/sokol/sokol_color.h
vendored
Normal file
1148
source/engine/thirdparty/sokol/sokol_color.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4644
source/engine/thirdparty/sokol/sokol_debugtext.h
vendored
Normal file
4644
source/engine/thirdparty/sokol/sokol_debugtext.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1904
source/engine/thirdparty/sokol/sokol_fontstash.h
vendored
Normal file
1904
source/engine/thirdparty/sokol/sokol_fontstash.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4226
source/engine/thirdparty/sokol/sokol_gfx_imgui.h
vendored
Normal file
4226
source/engine/thirdparty/sokol/sokol_gfx_imgui.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4318
source/engine/thirdparty/sokol/sokol_gl.h
vendored
Normal file
4318
source/engine/thirdparty/sokol/sokol_gl.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2457
source/engine/thirdparty/sokol/sokol_imgui.h
vendored
Normal file
2457
source/engine/thirdparty/sokol/sokol_imgui.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
167
source/engine/thirdparty/sokol/sokol_memtrack.h
vendored
Normal file
167
source/engine/thirdparty/sokol/sokol_memtrack.h
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
#if defined(SOKOL_IMPL) && !defined(SOKOL_MEMTRACK_IMPL)
|
||||
#define SOKOL_MEMTRACK_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_MEMTRACK_INCLUDED
|
||||
/*
|
||||
sokol_memtrack.h -- memory allocation wrapper to track memory usage
|
||||
of sokol libraries
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
|
||||
SOKOL_MEMTRACK_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_MEMTRACK_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_memtrack.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
USAGE
|
||||
=====
|
||||
Just plug the malloc/free wrapper functions into the desc.allocator
|
||||
struct provided by most sokol header setup functions:
|
||||
|
||||
sg_setup(&(sg_desc){
|
||||
//...
|
||||
.allocator = {
|
||||
.alloc = smemtrack_alloc,
|
||||
.free = smemtrack_free,
|
||||
}
|
||||
});
|
||||
|
||||
Then call smemtrack_info() to get information about current number
|
||||
of allocations and overall allocation size:
|
||||
|
||||
const smemtrack_info_t info = smemtrack_info();
|
||||
const int num_allocs = info.num_allocs;
|
||||
const int num_bytes = info.num_bytes;
|
||||
|
||||
Note the sokol_memtrack.h can only track allocations issued by
|
||||
the sokol headers, not allocations that happen under the hood
|
||||
in system libraries.
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_MEMTRACK_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_MEMTRACK_API_DECL)
|
||||
#define SOKOL_MEMTRACK_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_MEMTRACK_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_MEMTRACK_IMPL)
|
||||
#define SOKOL_MEMTRACK_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_MEMTRACK_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_MEMTRACK_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct smemtrack_info_t {
|
||||
int num_allocs;
|
||||
int num_bytes;
|
||||
} smemtrack_info_t;
|
||||
|
||||
SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);
|
||||
SOKOL_MEMTRACK_API_DECL void* smemtrack_alloc(size_t size, void* user_data);
|
||||
SOKOL_MEMTRACK_API_DECL void smemtrack_free(void* ptr, void* user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* SOKOL_MEMTRACK_INCLUDED */
|
||||
|
||||
/*=== IMPLEMENTATION =========================================================*/
|
||||
#ifdef SOKOL_MEMTRACK_IMPL
|
||||
#define SOKOL_MEMTRACK_IMPL_INCLUDED (1)
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <string.h> // memset
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// per-allocation header used to keep track of the allocation size
|
||||
#define _SMEMTRACK_HEADER_SIZE (16)
|
||||
|
||||
static struct {
|
||||
smemtrack_info_t state;
|
||||
} _smemtrack;
|
||||
|
||||
SOKOL_API_IMPL void* smemtrack_alloc(size_t size, void* user_data) {
|
||||
(void)user_data;
|
||||
uint8_t* ptr = (uint8_t*) malloc(size + _SMEMTRACK_HEADER_SIZE);
|
||||
if (ptr) {
|
||||
// store allocation size (for allocation size tracking)
|
||||
*(size_t*)ptr = size;
|
||||
_smemtrack.state.num_allocs++;
|
||||
_smemtrack.state.num_bytes += (int) size;
|
||||
return ptr + _SMEMTRACK_HEADER_SIZE;
|
||||
}
|
||||
else {
|
||||
// allocation failed, return null pointer
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL void smemtrack_free(void* ptr, void* user_data) {
|
||||
(void)user_data;
|
||||
if (ptr) {
|
||||
uint8_t* alloc_ptr = ((uint8_t*)ptr) - _SMEMTRACK_HEADER_SIZE;
|
||||
size_t size = *(size_t*)alloc_ptr;
|
||||
_smemtrack.state.num_allocs--;
|
||||
_smemtrack.state.num_bytes -= (int) size;
|
||||
free(alloc_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL smemtrack_info_t smemtrack_info(void) {
|
||||
return _smemtrack.state;
|
||||
}
|
||||
|
||||
#endif /* SOKOL_MEMTRACK_IMPL */
|
2180
source/engine/thirdparty/sokol/sokol_nuklear.h
vendored
Normal file
2180
source/engine/thirdparty/sokol/sokol_nuklear.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1437
source/engine/thirdparty/sokol/sokol_shape.h
vendored
Normal file
1437
source/engine/thirdparty/sokol/sokol_shape.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
5759
source/engine/thirdparty/sokol/sokol_spine.h
vendored
Normal file
5759
source/engine/thirdparty/sokol/sokol_spine.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,88 +1,86 @@
|
|||
#include "timer.h"
|
||||
#include <stdlib.h>
|
||||
#include "log.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stb_ds.h>
|
||||
|
||||
struct timer *timers;
|
||||
static int first = -1;
|
||||
|
||||
void check_timer(struct timer *t, double dt)
|
||||
{
|
||||
if (!t->on)
|
||||
return;
|
||||
void check_timer(struct timer *t, double dt) {
|
||||
if (!t->on)
|
||||
return;
|
||||
|
||||
t->remain_time -= dt;
|
||||
t->remain_time -= dt;
|
||||
|
||||
if (t->remain_time <= 0) {
|
||||
t->cb(t->data);
|
||||
if (t->repeat) {
|
||||
t->remain_time = t->interval;
|
||||
return;
|
||||
}
|
||||
|
||||
timer_pause(t);
|
||||
return;
|
||||
if (t->remain_time <= 0) {
|
||||
t->cb(t->data);
|
||||
if (t->repeat) {
|
||||
t->remain_time = t->interval;
|
||||
return;
|
||||
}
|
||||
|
||||
timer_pause(t);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_update(double dt) {
|
||||
for (int i = 0; i < arrlen(timers); i++)
|
||||
check_timer(&timers[i], dt);
|
||||
for (int i = 0; i < arrlen(timers); i++)
|
||||
check_timer(&timers[i], dt);
|
||||
}
|
||||
|
||||
int timer_make(double interval, void (*callback)(void *param), void *param, int own) {
|
||||
struct timer new;
|
||||
new.remain_time = interval;
|
||||
new.interval = interval;
|
||||
new.cb = callback;
|
||||
new.data = param;
|
||||
new.repeat = 1;
|
||||
new.owndata = own;
|
||||
new.next = -1;
|
||||
|
||||
if (first < 0) {
|
||||
timer_start(&new);
|
||||
arrput(timers, new);
|
||||
return arrlen(timers)-1;
|
||||
} else {
|
||||
int retid = first;
|
||||
first = id2timer(first)->next;
|
||||
*id2timer(retid) = new;
|
||||
timer_start(id2timer(retid));
|
||||
return retid;
|
||||
}
|
||||
struct timer new;
|
||||
new.remain_time = interval;
|
||||
new.interval = interval;
|
||||
new.cb = callback;
|
||||
new.data = param;
|
||||
new.repeat = 1;
|
||||
new.owndata = own;
|
||||
new.next = -1;
|
||||
|
||||
if (first < 0) {
|
||||
timer_start(&new);
|
||||
arrput(timers, new);
|
||||
return arrlen(timers) - 1;
|
||||
} else {
|
||||
int retid = first;
|
||||
first = id2timer(first)->next;
|
||||
*id2timer(retid) = new;
|
||||
timer_start(id2timer(retid));
|
||||
return retid;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_pause(struct timer *t) {
|
||||
if (!t->on) return;
|
||||
t->on = 0;
|
||||
if (!t->on) return;
|
||||
t->on = 0;
|
||||
}
|
||||
|
||||
void timer_stop(struct timer *t) {
|
||||
if (!t->on) return;
|
||||
t->on = 0;
|
||||
t->remain_time = t->interval;
|
||||
if (!t->on) return;
|
||||
t->on = 0;
|
||||
t->remain_time = t->interval;
|
||||
}
|
||||
|
||||
void timer_start(struct timer *t) {
|
||||
if (t->on) return;
|
||||
t->on = 1;
|
||||
if (t->on) return;
|
||||
t->on = 1;
|
||||
}
|
||||
|
||||
void timer_remove(int id) {
|
||||
struct timer *t = id2timer(id);
|
||||
if (t->owndata) free(t->data);
|
||||
t->next = first;
|
||||
first = id;
|
||||
struct timer *t = id2timer(id);
|
||||
if (t->owndata) free(t->data);
|
||||
t->next = first;
|
||||
first = id;
|
||||
}
|
||||
|
||||
void timerr_settime(struct timer *t, double interval) {
|
||||
t->remain_time += (interval - t->interval);
|
||||
t->interval = interval;
|
||||
t->remain_time += (interval - t->interval);
|
||||
t->interval = interval;
|
||||
}
|
||||
|
||||
struct timer *id2timer(int id)
|
||||
{
|
||||
return &timers[id];
|
||||
struct timer *id2timer(int id) {
|
||||
return &timers[id];
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,52 +1,44 @@
|
|||
#include "transform.h"
|
||||
#include <string.h>
|
||||
|
||||
struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[4], float scale)
|
||||
{
|
||||
struct mTransform newT;
|
||||
memcpy(newT.position, pos, sizeof(*pos));
|
||||
memcpy(newT.rotation, rotation, sizeof(*rotation));
|
||||
newT.scale = scale;
|
||||
return newT;
|
||||
struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[4], float scale) {
|
||||
struct mTransform newT;
|
||||
memcpy(newT.position, pos, sizeof(*pos));
|
||||
memcpy(newT.rotation, rotation, sizeof(*rotation));
|
||||
newT.scale = scale;
|
||||
return newT;
|
||||
}
|
||||
|
||||
mfloat_t *trans_forward(mfloat_t * res,
|
||||
const struct mTransform *const trans)
|
||||
{
|
||||
// YughLog(0, SDL_LOG_PRIORITY_WARN, "Rotation is %f", trans->rotation[0]);
|
||||
return vec3_rotate_quat(res, FORWARD, trans->rotation);
|
||||
mfloat_t *trans_forward(mfloat_t *res,
|
||||
const struct mTransform *const trans) {
|
||||
// YughLog(0, SDL_LOG_PRIORITY_WARN, "Rotation is %f", trans->rotation[0]);
|
||||
return vec3_rotate_quat(res, FORWARD, trans->rotation);
|
||||
}
|
||||
|
||||
mfloat_t *trans_back(mfloat_t * res, const struct mTransform *trans)
|
||||
{
|
||||
return vec3_rotate_quat(res, BACK, trans->rotation);
|
||||
mfloat_t *trans_back(mfloat_t *res, const struct mTransform *trans) {
|
||||
return vec3_rotate_quat(res, BACK, trans->rotation);
|
||||
}
|
||||
|
||||
mfloat_t *trans_up(mfloat_t * res, const struct mTransform *trans)
|
||||
{
|
||||
return vec3_rotate_quat(res, UP, trans->rotation);
|
||||
mfloat_t *trans_up(mfloat_t *res, const struct mTransform *trans) {
|
||||
return vec3_rotate_quat(res, UP, trans->rotation);
|
||||
}
|
||||
|
||||
mfloat_t *trans_down(mfloat_t * res, const struct mTransform *trans)
|
||||
{
|
||||
return vec3_rotate_quat(res, DOWN, trans->rotation);
|
||||
mfloat_t *trans_down(mfloat_t *res, const struct mTransform *trans) {
|
||||
return vec3_rotate_quat(res, DOWN, trans->rotation);
|
||||
}
|
||||
|
||||
mfloat_t *trans_right(mfloat_t * res, const struct mTransform *trans)
|
||||
{
|
||||
return vec3_rotate_quat(res, RIGHT, trans->rotation);
|
||||
mfloat_t *trans_right(mfloat_t *res, const struct mTransform *trans) {
|
||||
return vec3_rotate_quat(res, RIGHT, trans->rotation);
|
||||
}
|
||||
|
||||
mfloat_t *trans_left(mfloat_t * res, const struct mTransform *trans)
|
||||
{
|
||||
return vec3_rotate_quat(res, LEFT, trans->rotation);
|
||||
mfloat_t *trans_left(mfloat_t *res, const struct mTransform *trans) {
|
||||
return vec3_rotate_quat(res, LEFT, trans->rotation);
|
||||
}
|
||||
|
||||
#include "nuke.h"
|
||||
|
||||
void trans_drawgui(struct mTransform *T)
|
||||
{
|
||||
nuke_property_float3("Position", -1000.f, T->position, 1000.f, 1.f, 1.f);
|
||||
nuke_property_float3("Rotation", 0.f, T->rotation, 360.f, 1.f, 0.1f);
|
||||
nuke_property_float("Scale", 0.f, &T->scale, 1000.f, 0.1f, 0.1f);
|
||||
void trans_drawgui(struct mTransform *T) {
|
||||
nuke_property_float3("Position", -1000.f, T->position, 1000.f, 1.f, 1.f);
|
||||
nuke_property_float3("Rotation", 0.f, T->rotation, 360.f, 1.f, 0.1f);
|
||||
nuke_property_float("Scale", 0.f, &T->scale, 1000.f, 0.1f, 0.1f);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "window.h"
|
||||
#include <string.h>
|
||||
#include "texture.h"
|
||||
#include "log.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "input.h"
|
||||
#include "script.h"
|
||||
#include "log.h"
|
||||
#include "nuke.h"
|
||||
#include "script.h"
|
||||
#include "texture.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
|
@ -18,277 +18,248 @@ static struct window *windows = NULL;
|
|||
|
||||
struct Texture *icon = NULL;
|
||||
|
||||
int is_win(struct window *s, GLFWwindow *w)
|
||||
{
|
||||
return s->window == w;
|
||||
int is_win(struct window *s, GLFWwindow *w) {
|
||||
return s->window == w;
|
||||
}
|
||||
|
||||
void window_size_callback(GLFWwindow *w, int width, int height)
|
||||
{
|
||||
|
||||
void window_size_callback(GLFWwindow *w, int width, int height) {
|
||||
}
|
||||
|
||||
struct window *winfind(GLFWwindow *w)
|
||||
{
|
||||
for (int i = 0; i < arrlen(windows); i++) {
|
||||
if (windows[i].window == w)
|
||||
return &windows[i];
|
||||
}
|
||||
struct window *winfind(GLFWwindow *w) {
|
||||
for (int i = 0; i < arrlen(windows); i++) {
|
||||
if (windows[i].window == w)
|
||||
return &windows[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void window_iconify_callback(GLFWwindow *w, int iconified) {
|
||||
struct window *win = winfind(w);
|
||||
win->iconified = iconified;
|
||||
}
|
||||
|
||||
void window_focus_callback(GLFWwindow *w, int focused) {
|
||||
struct window *win = winfind(w);
|
||||
win->mouseFocus = focused;
|
||||
}
|
||||
|
||||
void window_maximize_callback(GLFWwindow *w, int maximized) {
|
||||
struct window *win = winfind(w);
|
||||
win->minimized = !maximized;
|
||||
}
|
||||
|
||||
void window_framebuffer_size_cb(GLFWwindow *w, int width, int height) {
|
||||
struct window *win = winfind(w);
|
||||
win->width = width;
|
||||
win->height = height;
|
||||
window_makecurrent(win);
|
||||
win->render = 1;
|
||||
}
|
||||
|
||||
void window_close_callback(GLFWwindow *w) {
|
||||
quit();
|
||||
}
|
||||
|
||||
struct window *MakeSDLWindow(const char *name, int width, int height, uint32_t flags) {
|
||||
if (arrcap(windows) == 0)
|
||||
arrsetcap(windows, 5);
|
||||
|
||||
GLFWwindow *sharewin = mainwin == NULL ? NULL : mainwin->window;
|
||||
|
||||
if (sharewin) return sharewin;
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_SAMPLES,1);
|
||||
|
||||
struct window w = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.id = arrlen(windows),
|
||||
.window = glfwCreateWindow(width, height, name, NULL, sharewin)};
|
||||
|
||||
if (!w.window) {
|
||||
YughError("Couldn't make GLFW window\n", 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(w.window);
|
||||
// int version = gladLoadGL(glfwGetProcAddress);
|
||||
// if (!version) {
|
||||
// YughError("Failed to initialize OpenGL context.");
|
||||
// exit(1);
|
||||
// }
|
||||
YughInfo("Loaded OpenGL %d.%d", 3, 3);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// Set callbacks
|
||||
glfwSetWindowCloseCallback(w.window, window_close_callback);
|
||||
glfwSetWindowSizeCallback(w.window, window_size_callback);
|
||||
glfwSetFramebufferSizeCallback(w.window, window_framebuffer_size_cb);
|
||||
glfwSetWindowFocusCallback(w.window, window_focus_callback);
|
||||
glfwSetKeyCallback(w.window, win_key_callback);
|
||||
|
||||
arrput(windows, w);
|
||||
|
||||
if (arrlen(windows) == 1)
|
||||
mainwin = &windows[0];
|
||||
|
||||
return &arrlast(windows);
|
||||
}
|
||||
|
||||
void window_iconify_callback(GLFWwindow *w, int iconified)
|
||||
{
|
||||
struct window *win = winfind(w);
|
||||
win->iconified = iconified;
|
||||
}
|
||||
|
||||
void window_focus_callback(GLFWwindow *w, int focused)
|
||||
{
|
||||
struct window *win = winfind(w);
|
||||
win->mouseFocus = focused;
|
||||
}
|
||||
|
||||
void window_maximize_callback(GLFWwindow *w, int maximized)
|
||||
{
|
||||
struct window *win = winfind(w);
|
||||
win->minimized = !maximized;
|
||||
}
|
||||
|
||||
void window_framebuffer_size_cb(GLFWwindow *w, int width, int height)
|
||||
{
|
||||
struct window *win = winfind(w);
|
||||
win->width = width;
|
||||
win->height = height;
|
||||
window_makecurrent(win);
|
||||
win->render = 1;
|
||||
}
|
||||
|
||||
void window_close_callback(GLFWwindow *w)
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct window *MakeSDLWindow(const char *name, int width, int height, uint32_t flags)
|
||||
{
|
||||
if (arrcap(windows) == 0)
|
||||
arrsetcap(windows, 5);
|
||||
|
||||
GLFWwindow *sharewin = mainwin == NULL ? NULL : mainwin->window;
|
||||
|
||||
if (sharewin) return sharewin;
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
struct window w = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.id = arrlen(windows),
|
||||
.window = glfwCreateWindow(width, height, name, NULL, sharewin) };
|
||||
|
||||
|
||||
if (!w.window) {
|
||||
YughError("Couldn't make GLFW window\n", 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(w.window);
|
||||
// int version = gladLoadGL(glfwGetProcAddress);
|
||||
// if (!version) {
|
||||
// YughError("Failed to initialize OpenGL context.");
|
||||
// exit(1);
|
||||
// }
|
||||
YughInfo("Loaded OpenGL %d.%d", 3,3);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// Set callbacks
|
||||
glfwSetWindowCloseCallback(w.window, window_close_callback);
|
||||
glfwSetWindowSizeCallback(w.window, window_size_callback);
|
||||
glfwSetFramebufferSizeCallback(w.window, window_framebuffer_size_cb);
|
||||
glfwSetWindowFocusCallback(w.window, window_focus_callback);
|
||||
glfwSetKeyCallback(w.window, win_key_callback);
|
||||
|
||||
// nuke_init(&w);
|
||||
|
||||
arrput(windows, w);
|
||||
|
||||
if (arrlen(windows) == 1)
|
||||
mainwin = &windows[0];
|
||||
|
||||
return &arrlast(windows);
|
||||
}
|
||||
|
||||
void window_set_icon(const char *png)
|
||||
{
|
||||
void window_set_icon(const char *png) {
|
||||
icon = texture_pullfromfile(png);
|
||||
window_seticon(mainwin, icon);
|
||||
}
|
||||
|
||||
void window_destroy(struct window *w)
|
||||
{
|
||||
glfwDestroyWindow(w->window);
|
||||
arrdelswap(windows, w->id);
|
||||
void window_destroy(struct window *w) {
|
||||
glfwDestroyWindow(w->window);
|
||||
arrdelswap(windows, w->id);
|
||||
}
|
||||
|
||||
struct window *window_i(int index) {
|
||||
return &windows[index];
|
||||
return &windows[index];
|
||||
}
|
||||
|
||||
void window_handle_event(struct window *w)
|
||||
{
|
||||
/*
|
||||
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
|
||||
switch (e->window.event) {
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
|
||||
w->shown = true;
|
||||
break;
|
||||
void window_handle_event(struct window *w) {
|
||||
/*
|
||||
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
|
||||
switch (e->window.event) {
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
|
||||
w->shown = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_HIDDEN:
|
||||
w->shown = false;
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_HIDDEN:
|
||||
w->shown = false;
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
|
||||
w->width = e->window.data1;
|
||||
w->height = e->window.data2;
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Changed size of window %d: width %d, height %d.",
|
||||
w->id, w->width, w->height);
|
||||
window_makecurrent(w);
|
||||
w->render = true;
|
||||
break;
|
||||
w->width = e->window.data1;
|
||||
w->height = e->window.data2;
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Changed size of window %d: width %d, height %d.",
|
||||
w->id, w->width, w->height);
|
||||
window_makecurrent(w);
|
||||
w->render = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
|
||||
w->render = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
|
||||
w->render = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
|
||||
w->mouseFocus = true;
|
||||
SDL_RaiseWindow(w->window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
|
||||
w->mouseFocus = true;
|
||||
SDL_RaiseWindow(w->window);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
|
||||
w->mouseFocus = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
|
||||
w->mouseFocus = false;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Lost focus on window %d.", w->id);
|
||||
w->keyboardFocus = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Lost focus on window %d.", w->id);
|
||||
w->keyboardFocus = false;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Gained focus on window %d.", w->id);
|
||||
w->keyboardFocus = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Gained focus on window %d.", w->id);
|
||||
w->keyboardFocus = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Minimized window %d.", w->id);
|
||||
w->minimized = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Minimized window %d.", w->id);
|
||||
w->minimized = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Maximized window %d.", w->id);
|
||||
w->minimized = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Maximized window %d.", w->id);
|
||||
w->minimized = false;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Restored window %d.", w->id);
|
||||
w->minimized = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||
"Restored window %d.", w->id);
|
||||
w->minimized = false;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void window_all_handle_events()
|
||||
{
|
||||
for (int i = 0; i < arrlen(windows); i++)
|
||||
window_handle_event(&windows[i]);
|
||||
void window_all_handle_events() {
|
||||
for (int i = 0; i < arrlen(windows); i++)
|
||||
window_handle_event(&windows[i]);
|
||||
}
|
||||
|
||||
void window_makefullscreen(struct window *w)
|
||||
{
|
||||
if (!w->fullscreen)
|
||||
window_togglefullscreen(w);
|
||||
void window_makefullscreen(struct window *w) {
|
||||
if (!w->fullscreen)
|
||||
window_togglefullscreen(w);
|
||||
}
|
||||
|
||||
void window_unfullscreen(struct window *w)
|
||||
{
|
||||
if (w->fullscreen)
|
||||
window_togglefullscreen(w);
|
||||
void window_unfullscreen(struct window *w) {
|
||||
if (w->fullscreen)
|
||||
window_togglefullscreen(w);
|
||||
}
|
||||
|
||||
void window_togglefullscreen(struct window *w)
|
||||
{
|
||||
w->fullscreen = !w->fullscreen;
|
||||
|
||||
if (w->fullscreen) {
|
||||
glfwMaximizeWindow(w->window);
|
||||
} else {
|
||||
glfwRestoreWindow(w->window);
|
||||
}
|
||||
void window_togglefullscreen(struct window *w) {
|
||||
w->fullscreen = !w->fullscreen;
|
||||
|
||||
if (w->fullscreen) {
|
||||
glfwMaximizeWindow(w->window);
|
||||
} else {
|
||||
glfwRestoreWindow(w->window);
|
||||
}
|
||||
}
|
||||
|
||||
void window_makecurrent(struct window *w)
|
||||
{
|
||||
|
||||
if (w->window != glfwGetCurrentContext())
|
||||
glfwMakeContextCurrent(w->window);
|
||||
glViewport(0, 0, w->width, w->height);
|
||||
void window_makecurrent(struct window *w) {
|
||||
|
||||
if (w->window != glfwGetCurrentContext())
|
||||
glfwMakeContextCurrent(w->window);
|
||||
glViewport(0, 0, w->width, w->height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void window_swap(struct window *w)
|
||||
{
|
||||
glfwSwapBuffers(w->window);
|
||||
void window_swap(struct window *w) {
|
||||
glfwSwapBuffers(w->window);
|
||||
}
|
||||
|
||||
void window_seticon(struct window *w, struct Texture *icon)
|
||||
{
|
||||
void window_seticon(struct window *w, struct Texture *icon) {
|
||||
|
||||
static GLFWimage images[1];
|
||||
images[0].width = icon->width;
|
||||
images[0].height = icon->height;
|
||||
images[0].pixels = icon->data;
|
||||
glfwSetWindowIcon(w->window, 1, images);
|
||||
static GLFWimage images[1];
|
||||
images[0].width = icon->width;
|
||||
images[0].height = icon->height;
|
||||
images[0].pixels = icon->data;
|
||||
glfwSetWindowIcon(w->window, 1, images);
|
||||
}
|
||||
|
||||
int window_hasfocus(struct window *w)
|
||||
{
|
||||
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
|
||||
int window_hasfocus(struct window *w) {
|
||||
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
|
||||
}
|
||||
|
||||
void window_render(struct window *w) {
|
||||
window_makecurrent(w);
|
||||
openglRender(w);
|
||||
window_swap(w);
|
||||
window_makecurrent(w);
|
||||
openglRender(w);
|
||||
window_swap(w);
|
||||
}
|
||||
|
||||
void window_renderall() {
|
||||
//arrwalk(windows, window_render);
|
||||
for (int i = 0; i < arrlen(windows); i++)
|
||||
window_render(&windows[i]);
|
||||
// arrwalk(windows, window_render);
|
||||
for (int i = 0; i < arrlen(windows); i++)
|
||||
window_render(&windows[i]);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#include "yugine.h"
|
||||
|
||||
|
||||
#include "camera.h"
|
||||
#include "window.h"
|
||||
#include "engine.h"
|
||||
#include "font.h"
|
||||
#include "gameobject.h"
|
||||
#include "input.h"
|
||||
#include "openglrender.h"
|
||||
#include "gameobject.h"
|
||||
#include "font.h"
|
||||
#include "window.h"
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
|
@ -16,8 +15,8 @@
|
|||
|
||||
#include "quickjs/quickjs.h"
|
||||
|
||||
#include "script.h"
|
||||
#include "ffi.h"
|
||||
#include "script.h"
|
||||
|
||||
#include "log.h"
|
||||
#include <stdio.h>
|
||||
|
@ -25,28 +24,26 @@
|
|||
|
||||
#include "2dphysics.h"
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
|
||||
#define SOKOL_TRACE_HOOKS
|
||||
#define SOKOL_GFX_IMPL
|
||||
#define SOKOL_GLCORE33
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
|
||||
int physOn = 0;
|
||||
|
||||
double renderlag = 0;
|
||||
double physlag = 0;
|
||||
double updatelag = 0;
|
||||
|
||||
double renderMS = 1/165.f;
|
||||
double physMS = 1/120.f;
|
||||
double updateMS = 1/60.f;
|
||||
double renderMS = 1 / 165.f;
|
||||
double physMS = 1 / 120.f;
|
||||
double updateMS = 1 / 60.f;
|
||||
|
||||
static int ed = 1;
|
||||
static int sim_play = 0;
|
||||
|
@ -65,39 +62,37 @@ int fps;
|
|||
#define SIM_PAUSE 2
|
||||
#define SIM_STEP 3
|
||||
|
||||
void print_stacktrace()
|
||||
{
|
||||
void *ents[512];
|
||||
size_t size;
|
||||
void print_stacktrace() {
|
||||
void *ents[512];
|
||||
size_t size;
|
||||
|
||||
size = backtrace(ents, 512);
|
||||
size = backtrace(ents, 512);
|
||||
|
||||
YughCritical("====================BACKTRACE====================");
|
||||
char **stackstr = backtrace_symbols(ents, size);
|
||||
YughCritical("====================BACKTRACE====================");
|
||||
char **stackstr = backtrace_symbols(ents, size);
|
||||
|
||||
YughInfo("Stack size is %d.", size);
|
||||
YughInfo("Stack size is %d.", size);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
YughCritical(stackstr[i]);
|
||||
for (int i = 0; i < size; i++)
|
||||
YughCritical(stackstr[i]);
|
||||
|
||||
js_stacktrace();
|
||||
js_stacktrace();
|
||||
}
|
||||
|
||||
void seghandle(int sig) {
|
||||
#ifdef __linux__
|
||||
if (strsignal(sig))
|
||||
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
||||
if (strsignal(sig))
|
||||
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
||||
|
||||
print_stacktrace();
|
||||
print_stacktrace();
|
||||
|
||||
exit(1);
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void compile_script(const char *file)
|
||||
{
|
||||
void compile_script(const char *file) {
|
||||
const char *script = slurp_text(file);
|
||||
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY|JS_EVAL_TYPE_GLOBAL);
|
||||
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_GLOBAL);
|
||||
size_t out_len;
|
||||
uint8_t *out;
|
||||
out = JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE);
|
||||
|
@ -107,159 +102,157 @@ void compile_script(const char *file)
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data)
|
||||
{
|
||||
void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data) {
|
||||
mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg);
|
||||
}
|
||||
|
||||
int main(int argc, char **args) {
|
||||
int logout = 1;
|
||||
ed = 1;
|
||||
int logout = 1;
|
||||
ed = 1;
|
||||
|
||||
script_startup();
|
||||
script_startup();
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (args[i][0] == '-') {
|
||||
switch(args[i][1]) {
|
||||
case 'p':
|
||||
ed = 0;
|
||||
break;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (args[i][0] == '-') {
|
||||
switch (args[i][1]) {
|
||||
case 'p':
|
||||
ed = 0;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (i+1 < argc && args[i+1][0] != '-') {
|
||||
log_setfile(args[i+1]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
YughError("Expected a file for command line arg '-l'.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
case 'v':
|
||||
printf("Yugine version %s, %s build.\n", VER, INFO);
|
||||
printf("Copyright 2022-2023 odplot productions LLC.\n");
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
compile_script(args[2]);
|
||||
exit(0);
|
||||
|
||||
case 'm':
|
||||
logLevel = atoi(args[2]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("-l Set log file\n");
|
||||
printf("-p Launch engine in play mode instead of editor mode\n");
|
||||
printf("-v Display engine info\n");
|
||||
printf("-c Redirect logging to console\n");
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
logout = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
case 'l':
|
||||
if (i + 1 < argc && args[i + 1][0] != '-') {
|
||||
log_setfile(args[i + 1]);
|
||||
i++;
|
||||
continue;
|
||||
} else {
|
||||
YughError("Expected a file for command line arg '-l'.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
case 'v':
|
||||
printf("Yugine version %s, %s build.\n", VER, INFO);
|
||||
printf("Copyright 2022-2023 odplot productions LLC.\n");
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
compile_script(args[2]);
|
||||
exit(0);
|
||||
|
||||
case 'm':
|
||||
logLevel = atoi(args[2]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("-l Set log file\n");
|
||||
printf("-p Launch engine in play mode instead of editor mode\n");
|
||||
printf("-v Display engine info\n");
|
||||
printf("-c Redirect logging to console\n");
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
logout = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DBG
|
||||
if (logout) {
|
||||
time_t now = time(NULL);
|
||||
char fname[100];
|
||||
snprintf(fname, 100, "yugine-%d.log", now);
|
||||
log_setfile(fname);
|
||||
}
|
||||
if (logout) {
|
||||
time_t now = time(NULL);
|
||||
char fname[100];
|
||||
snprintf(fname, 100, "yugine-%d.log", now);
|
||||
log_setfile(fname);
|
||||
}
|
||||
|
||||
YughInfo("Starting yugine version %s.", VER);
|
||||
YughInfo("Starting yugine version %s.", VER);
|
||||
|
||||
FILE *sysinfo = NULL;
|
||||
/* sysinfo = popen("uname -a", "r");
|
||||
if (!sysinfo) {
|
||||
YughWarn("Failed to get sys info.");
|
||||
} else {
|
||||
log_cat(sysinfo);
|
||||
pclose(sysinfo);
|
||||
}*/
|
||||
signal(SIGSEGV, seghandle);
|
||||
signal(SIGABRT, seghandle);
|
||||
signal(SIGFPE, seghandle);
|
||||
signal(SIGBUS, seghandle);
|
||||
|
||||
FILE *sysinfo = NULL;
|
||||
/* sysinfo = popen("uname -a", "r");
|
||||
if (!sysinfo) {
|
||||
YughWarn("Failed to get sys info.");
|
||||
} else {
|
||||
log_cat(sysinfo);
|
||||
pclose(sysinfo);
|
||||
}*/
|
||||
signal(SIGSEGV, seghandle);
|
||||
signal(SIGABRT, seghandle);
|
||||
signal(SIGFPE, seghandle);
|
||||
signal(SIGBUS, seghandle);
|
||||
|
||||
#endif
|
||||
|
||||
engine_init();
|
||||
engine_init();
|
||||
|
||||
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
||||
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
||||
|
||||
renderMS = 1.0/vidmode->refreshRate;
|
||||
renderMS = 1.0 / vidmode->refreshRate;
|
||||
|
||||
sg_setup(&(sg_desc){
|
||||
sg_setup(&(sg_desc){
|
||||
.logger = {
|
||||
.func = sg_logging,
|
||||
.user_data = NULL,
|
||||
.func = sg_logging,
|
||||
.user_data = NULL,
|
||||
},
|
||||
});
|
||||
|
||||
input_init();
|
||||
openglInit();
|
||||
.buffer_pool_size = 1024,
|
||||
.context.sample_count = 1,
|
||||
});
|
||||
|
||||
if (ed)
|
||||
script_dofile("scripts/editor.js");
|
||||
else
|
||||
script_dofile("scripts/play.js");
|
||||
input_init();
|
||||
openglInit();
|
||||
|
||||
while (!want_quit()) {
|
||||
double elapsed = glfwGetTime() - lastTick;
|
||||
deltaT = elapsed;
|
||||
lastTick = glfwGetTime();
|
||||
double wait = fmax(0, renderMS-elapsed);
|
||||
input_poll(wait);
|
||||
window_all_handle_events();
|
||||
if (ed)
|
||||
script_dofile("scripts/editor.js");
|
||||
else
|
||||
script_dofile("scripts/play.js");
|
||||
|
||||
framems[framei++] = elapsed;
|
||||
while (!want_quit()) {
|
||||
double elapsed = glfwGetTime() - lastTick;
|
||||
deltaT = elapsed;
|
||||
lastTick = glfwGetTime();
|
||||
double wait = fmax(0, renderMS - elapsed);
|
||||
input_poll(wait);
|
||||
window_all_handle_events();
|
||||
|
||||
if (framei == FPSBUF) framei = 0;
|
||||
framems[framei++] = elapsed;
|
||||
|
||||
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
|
||||
timer_update(elapsed * timescale);
|
||||
physlag += elapsed;
|
||||
call_updates(elapsed * timescale);
|
||||
while (physlag >= physMS) {
|
||||
phys_step = 1;
|
||||
physlag -= physMS;
|
||||
phys2d_update(physMS * timescale);
|
||||
call_physics(physMS * timescale);
|
||||
if (sim_play == SIM_STEP) sim_pause();
|
||||
phys_step = 0;
|
||||
}
|
||||
}
|
||||
if (framei == FPSBUF) framei = 0;
|
||||
|
||||
renderlag += elapsed;
|
||||
|
||||
if (renderlag >= renderMS) {
|
||||
renderlag -= renderMS;
|
||||
window_renderall();
|
||||
}
|
||||
|
||||
gameobjects_cleanup();
|
||||
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
|
||||
timer_update(elapsed * timescale);
|
||||
physlag += elapsed;
|
||||
call_updates(elapsed * timescale);
|
||||
while (physlag >= physMS) {
|
||||
phys_step = 1;
|
||||
physlag -= physMS;
|
||||
phys2d_update(physMS * timescale);
|
||||
call_physics(physMS * timescale);
|
||||
if (sim_play == SIM_STEP) sim_pause();
|
||||
phys_step = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
renderlag += elapsed;
|
||||
|
||||
if (renderlag >= renderMS) {
|
||||
renderlag -= renderMS;
|
||||
window_renderall();
|
||||
}
|
||||
|
||||
gameobjects_cleanup();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int frame_fps()
|
||||
{
|
||||
double fpsms = 0;
|
||||
for (int i = 0; i < FPSBUF; i++) {
|
||||
fpsms += framems[i];
|
||||
}
|
||||
int frame_fps() {
|
||||
double fpsms = 0;
|
||||
for (int i = 0; i < FPSBUF; i++) {
|
||||
fpsms += framems[i];
|
||||
}
|
||||
|
||||
return FPSBUF / fpsms;
|
||||
return FPSBUF / fpsms;
|
||||
}
|
||||
|
||||
int sim_playing() { return sim_play == SIM_PLAY; }
|
||||
|
@ -275,19 +268,19 @@ void sim_pause() {
|
|||
}
|
||||
|
||||
void sim_stop() {
|
||||
/* Revert starting state of everything from sim_start */
|
||||
sim_play = SIM_STOP;
|
||||
/* Revert starting state of everything from sim_start */
|
||||
sim_play = SIM_STOP;
|
||||
}
|
||||
|
||||
int phys_stepping() { return phys_step; }
|
||||
|
||||
void sim_step() {
|
||||
if (sim_paused()) {
|
||||
YughInfo("Step");
|
||||
sim_play = SIM_STEP;
|
||||
YughInfo("Step");
|
||||
sim_play = SIM_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
void set_timescale(float val) {
|
||||
timescale = val;
|
||||
timescale = val;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
void main()
|
||||
{
|
||||
// gl_FragDepth = gl_FragCoord.z;
|
||||
}
|
|
@ -3,24 +3,27 @@ in vec2 coords;
|
|||
|
||||
out vec4 color;
|
||||
|
||||
uniform float radius;
|
||||
uniform int thickness;
|
||||
uniform vec3 dbgColor;
|
||||
uniform bool fill;
|
||||
uniform float zoom;
|
||||
//in int thickness;
|
||||
in float radius;
|
||||
//in bool fill;
|
||||
in vec3 fcolor;
|
||||
in vec2 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
int thickness = 1;
|
||||
bool fill = false;
|
||||
|
||||
// int tt = thickness + 1;
|
||||
float R1 = 1.f;
|
||||
float R2 = 1.f - (thickness*zoom / radius);
|
||||
// float R2 = 1.f - (thickness*zoom / radius);
|
||||
float R2 = 1.f - (thickness/radius);
|
||||
float dist = sqrt(dot(coords, coords));
|
||||
|
||||
if (dist >= R2 && dist <= R1)
|
||||
color = vec4(dbgColor, 1.f);
|
||||
color = vec4(fcolor, 1.f);
|
||||
else if (dist < R2)
|
||||
color = vec4(dbgColor, 0.1f);
|
||||
color = vec4(fcolor, 0.1f);
|
||||
else
|
||||
discard;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec4 vertex;
|
||||
layout (location = 0) in vec2 vertex;
|
||||
layout (location = 1) in vec3 acolor;
|
||||
layout (location = 2) in vec2 apos;
|
||||
layout (location = 3) in float aradius;
|
||||
layout (location = 4) in float afill;
|
||||
|
||||
out vec2 coords;
|
||||
|
||||
out float radius;
|
||||
out vec3 fcolor;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform vec2 res;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = proj * vec4(vertex.xy, 0.0, 1.0);
|
||||
coords = vertex.zw;
|
||||
gl_Position = proj * vec4((vertex * aradius) + apos, 0.0, 1.0);
|
||||
coords = vertex.xy;
|
||||
fcolor = acolor;
|
||||
radius = aradius;
|
||||
}
|
||||
|
|
26
source/shaders/crtfrag.glsl
Normal file
26
source/shaders/crtfrag.glsl
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 330 core
|
||||
in vec2 TexCoords;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
uniform sampler2D diffuse_texture;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(diffuse_texture, TexCoords);
|
||||
// float avg = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
|
||||
// frag_color = vec4(avg,avg,avg,1.0);
|
||||
float lc = 720.0/2.0;
|
||||
float line = TexCoords.y * lc;
|
||||
float line_intensity = mod(float(line),2);
|
||||
|
||||
float off = line_intensity * 0.0005;
|
||||
vec4 shift = vec4(off,0,0,0);
|
||||
vec4 color_shift = vec4(0.001,0,0,0);
|
||||
float r = color.r + color_shift.r + shift.r;
|
||||
float g = color.g - color_shift.g + shift.g;
|
||||
float b = color.b;
|
||||
|
||||
frag_color = vec4(r, g*0.99, b, 1.0) * clamp(line_intensity, 0.85, 1.0);
|
||||
frag_color = texture(diffuse_texture, TexCoords);
|
||||
}
|
104
source/shaders/diffuse_f.glsl
Normal file
104
source/shaders/diffuse_f.glsl
Normal file
|
@ -0,0 +1,104 @@
|
|||
#version 330 core
|
||||
in vec2 tex_coords;
|
||||
in vec3 normal;
|
||||
in vec3 frag_pos;
|
||||
in vec4 frag_pos_light;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
uniform sampler2D diffuse;
|
||||
uniform sampler2D normmap;
|
||||
uniform sampler2D shadow_map;
|
||||
|
||||
uniform vec3 point_pos;
|
||||
uniform vec3 dir_dir;
|
||||
uniform vec3 view_pos;
|
||||
uniform vec3 spot_pos;
|
||||
uniform vec3 spot_dir;
|
||||
|
||||
/* Ambient light */
|
||||
float amb_str = 0.3;
|
||||
|
||||
vec3 amb_color = vec3(1,1,1);
|
||||
|
||||
float spec_str = 0.5;
|
||||
|
||||
/* point */
|
||||
float constant = 1;
|
||||
float linear = 0.09;
|
||||
float quad = 0.032;
|
||||
|
||||
/* spotlight */
|
||||
float cutoff = 12.5; /* cutoff in radians */
|
||||
float outer_cutoff = 17.5;
|
||||
|
||||
vec3 norm = vec3(0,0,0);
|
||||
vec3 view = vec3(0,0,0);
|
||||
|
||||
float light_str(vec3 dir)
|
||||
{
|
||||
float d = max(dot(norm, dir), 0.0);
|
||||
vec3 refl = reflect(-dir, norm);
|
||||
float s = pow(max(dot(view,refl), 0.0), 32);
|
||||
|
||||
return s+d;
|
||||
}
|
||||
|
||||
float shadow_calc(vec4 fg)
|
||||
{
|
||||
vec3 pc = fg.xyz / fg.w;
|
||||
pc = pc * 0.5 + 0.5;
|
||||
|
||||
if (pc.z > 1.0)
|
||||
return 0.0;
|
||||
|
||||
float closest_depth = texture(shadow_map, pc.xy).r;
|
||||
float cur_depth = pc.z;
|
||||
|
||||
vec3 light_dir = normalize(vec3(4,100,20) - frag_pos); /* light pos */
|
||||
float bias = max(0.05 * (1 - dot(norm, light_dir)), 0.005);
|
||||
|
||||
return cur_depth - bias > closest_depth ? 1.0 : 0.0;
|
||||
|
||||
float s;
|
||||
vec2 texel_size = 1 / textureSize(shadow_map, 0);
|
||||
|
||||
for (int x = -1; x <= 1; ++x) {
|
||||
for (int y = -1; y <= 1; ++y) {
|
||||
float pcf_depth = texture(shadow_map, pc.xy + vec2(x,y) * texel_size).r;
|
||||
s += cur_depth - bias > pcf_depth ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
s /= 9.0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void main() {
|
||||
norm = normalize(normal);
|
||||
view = normalize(view_pos - frag_pos);
|
||||
|
||||
float point_amt = light_str(normalize(point_pos-frag_pos));
|
||||
float dist = length(point_pos - frag_pos);
|
||||
float atten = 1.0 / (constant + linear * dist + quad * (dist*dist));
|
||||
point_amt *= atten;
|
||||
|
||||
float dir_amt = light_str(normalize(-dir_dir));
|
||||
|
||||
vec3 spot_dir = normalize(spot_pos - frag_pos);
|
||||
float theta = dot(spot_dir, normalize(-spot_dir));
|
||||
float spot_amt = 0;
|
||||
|
||||
float epsilon = cutoff - outer_cutoff;
|
||||
|
||||
if (theta > cutoff) {
|
||||
float intensity = clamp((theta - outer_cutoff)/epsilon,0.0,1.0);
|
||||
spot_amt = light_str(spot_dir) * intensity;
|
||||
}
|
||||
|
||||
vec4 mm = texture(diffuse,tex_coords);
|
||||
float shadow = shadow_calc(frag_pos_light);
|
||||
vec3 res = mm.rgb * (amb_str + (point_amt + dir_amt) * (1 - shadow));
|
||||
frag_color = vec4(res, mm.a);
|
||||
}
|
23
source/shaders/diffuse_v.glsl
Normal file
23
source/shaders/diffuse_v.glsl
Normal file
|
@ -0,0 +1,23 @@
|
|||
#version 330 core
|
||||
layout (location=0) in vec3 a_pos;
|
||||
layout (location=1) in vec2 a_tex_coords;
|
||||
layout (location=2) in vec3 a_norm;
|
||||
|
||||
out vec2 tex_coords;
|
||||
out vec3 normal;
|
||||
out vec3 frag_pos;
|
||||
out vec4 frag_pos_light;
|
||||
|
||||
|
||||
uniform mat4 vp;
|
||||
uniform mat4 model;
|
||||
uniform mat4 proj;
|
||||
uniform mat4 lsm;
|
||||
|
||||
void main() {
|
||||
frag_pos = vec3(model * vec4(a_pos, 1.0));
|
||||
gl_Position = proj * vp * vec4(frag_pos, 1.0);
|
||||
tex_coords = a_tex_coords;
|
||||
normal = mat3(transpose(inverse(model))) * a_norm;
|
||||
frag_pos_light = lsm * vec4(frag_pos, 1.0);
|
||||
}
|
|
@ -1,19 +1,27 @@
|
|||
#version 330
|
||||
out vec4 color;
|
||||
out vec4 frag_color;
|
||||
|
||||
in vec2 apos;
|
||||
vec2 bpos;
|
||||
uniform int thickness;
|
||||
uniform int span;
|
||||
uniform float thickness; /* thickness in pixels */
|
||||
uniform float span;
|
||||
uniform vec3 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float t = thickness / 2.f;
|
||||
bpos.x = mod(apos.x, span);
|
||||
bpos.y = mod(apos.y, span);
|
||||
float t = thickness / span;
|
||||
t /= 2.0;
|
||||
bpos.x = mod(apos.x, span) / span;
|
||||
bpos.y = mod(apos.y, span) / span;
|
||||
bpos.x -= t;
|
||||
bpos.y -= t;
|
||||
|
||||
if (!(bpos.x <= t || bpos.x >= (span - t) || bpos.y <= t || bpos.y >= (span - t)))
|
||||
discard;
|
||||
float comp = min(bpos.x, bpos.y);
|
||||
|
||||
color = vec4(0.4f, 0.7f, 0.2f, 0.3f);
|
||||
}
|
||||
if (comp > t)
|
||||
discard;
|
||||
|
||||
comp += t;
|
||||
|
||||
frag_color = vec4(color, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
#version 330
|
||||
layout (location = 0) in vec2 pos;
|
||||
out vec2 apos;
|
||||
|
||||
uniform vec2 offset;
|
||||
out vec2 apos;
|
||||
|
||||
layout (std140) uniform Projection {
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
uniform vec2 offset;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 ipos = inverse(projection) * vec4(pos, 0.f, 1.f);
|
||||
apos = ipos.xy + offset;
|
||||
// vec4 ipos = inverse(projection) * vec4(pos, 0.f, 1.f);
|
||||
apos = pos * vec2(600, 360);
|
||||
// apos = pos + offset;
|
||||
|
||||
|
||||
gl_Position = vec4(pos, 0.f, 1.f);
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ uniform float alpha;
|
|||
|
||||
void main()
|
||||
{
|
||||
color = vec4(linecolor, alpha);
|
||||
}
|
||||
color = vec4(1.f,1.f,1.f,1.f);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#version 330
|
||||
layout (location = 0) in vec2 pos;
|
||||
|
||||
layout (std140) uniform Projection {
|
||||
mat4 projection;
|
||||
};
|
||||
uniform mat4 proj;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * vec4(pos, 0.f, 1.f);
|
||||
}
|
||||
gl_Position = proj * vec4(pos, 0.f, 1.f);
|
||||
}
|
||||
|
|
8
source/shaders/shadowfrag.glsl
Normal file
8
source/shaders/shadowfrag.glsl
Normal file
|
@ -0,0 +1,8 @@
|
|||
#version 330 core
|
||||
out float frag_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
// frag_color = encode_depth(gl_FragCoord.z);
|
||||
frag_color = gl_FragCoord.z;
|
||||
}
|
|
@ -8,11 +8,8 @@ uniform sampler2D text;
|
|||
|
||||
void main()
|
||||
{
|
||||
|
||||
// color = vec4(fColor.xyz, texture(text, TexCoords).r);
|
||||
color = vec4(1.f,1.f,1.f, texture(text, TexCoords).r);
|
||||
color = vec4(fColor.xyz, texture(text, TexCoords).r);
|
||||
// color = vec4(1.f, 1.f, 1.f, texture(text, TexCoords).r);
|
||||
if (color.a <= 0.1f)
|
||||
discard;
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue