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
|
#ifndef TWODPHYSICS_H
|
||||||
#define TWODPHYSICS_H
|
#define TWODPHYSICS_H
|
||||||
|
|
||||||
#include <chipmunk/chipmunk.h>
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
#include <chipmunk/chipmunk.h>
|
||||||
|
|
||||||
struct gameobject;
|
struct gameobject;
|
||||||
|
|
||||||
|
@ -18,53 +18,53 @@ extern float kinematic_color[3];
|
||||||
extern float static_color[3];
|
extern float static_color[3];
|
||||||
|
|
||||||
struct phys2d_shape {
|
struct phys2d_shape {
|
||||||
cpShape *shape;
|
cpShape *shape;
|
||||||
int go;
|
int go;
|
||||||
void *data;
|
void *data;
|
||||||
void (*debugdraw)(void *data);
|
void (*debugdraw)(void *data);
|
||||||
float (*moi)(void *data, float mass);
|
float (*moi)(void *data, float mass);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Circles are the fastest collier type */
|
/* Circles are the fastest collier type */
|
||||||
struct phys2d_circle {
|
struct phys2d_circle {
|
||||||
float radius;
|
float radius;
|
||||||
cpVect offset;
|
cpVect offset;
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A single segment */
|
/* A single segment */
|
||||||
struct phys2d_segment {
|
struct phys2d_segment {
|
||||||
float a[2];
|
float a[2];
|
||||||
float b[2];
|
float b[2];
|
||||||
float thickness;
|
float thickness;
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A convex polygon; defined as the convex hull around the given set of points */
|
/* A convex polygon; defined as the convex hull around the given set of points */
|
||||||
struct phys2d_poly {
|
struct phys2d_poly {
|
||||||
cpVect *points;
|
cpVect *points;
|
||||||
float radius;
|
float radius;
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A box shape; a type of a polygon collider */
|
/* A box shape; a type of a polygon collider */
|
||||||
struct phys2d_box {
|
struct phys2d_box {
|
||||||
float w;
|
float w;
|
||||||
float h;
|
float h;
|
||||||
float offset[2];
|
float offset[2];
|
||||||
float rotation;
|
float rotation;
|
||||||
float r;
|
float r;
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An edge with no volume. Cannot collide with each other. Join to make levels. Static only. */
|
/* An edge with no volume. Cannot collide with each other. Join to make levels. Static only. */
|
||||||
struct phys2d_edge {
|
struct phys2d_edge {
|
||||||
cpVect *points;
|
cpVect *points;
|
||||||
float thickness;
|
float thickness;
|
||||||
cpShape **shapes;
|
cpShape **shapes;
|
||||||
int closed; /* True if the first and last points should be connected */
|
int closed; /* True if the first and last points should be connected */
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
int draws;
|
int draws;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct phys2d_circle *Make2DCircle(int go);
|
struct phys2d_circle *Make2DCircle(int go);
|
||||||
|
@ -107,8 +107,8 @@ cpShape *phys2d_query_pos(cpVect pos);
|
||||||
int *phys2d_query_box(cpVect pos, cpVect wh);
|
int *phys2d_query_box(cpVect pos, cpVect wh);
|
||||||
|
|
||||||
struct phys_cbs {
|
struct phys_cbs {
|
||||||
struct callee begin;
|
struct callee begin;
|
||||||
struct callee separate;
|
struct callee separate;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct shape_cb {
|
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);
|
int shape_get_sensor(struct phys2d_shape *shape);
|
||||||
|
|
||||||
struct color {
|
struct color {
|
||||||
unsigned char r;
|
unsigned char r;
|
||||||
unsigned char g;
|
unsigned char g;
|
||||||
unsigned char b;
|
unsigned char b;
|
||||||
};
|
};
|
||||||
|
|
||||||
void color2float(struct color, float *fcolor);
|
void color2float(struct color, float *fcolor);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef THREEDPHYSICS_H
|
#ifndef THREEDPHYSICS_H
|
||||||
#define THREEDPHYSICS_H
|
#define THREEDPHYSICS_H
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,26 +42,26 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
||||||
glm::vec3 p1 = CalculateCenter();
|
glm::vec3 p1 = CalculateCenter();
|
||||||
|
|
||||||
glm::vec3 p2 =
|
glm::vec3 p2 =
|
||||||
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
||||||
FloatWidths.
|
FloatWidths.
|
||||||
x) : GetExtentsOffset(TFOR.Right(),
|
x) : GetExtentsOffset(TFOR.Right(),
|
||||||
FloatWidths.x,
|
FloatWidths.x,
|
||||||
TargetOffset.x,
|
TargetOffset.x,
|
||||||
AnchorWidths.x);
|
AnchorWidths.x);
|
||||||
glm::vec3 p3 =
|
glm::vec3 p3 =
|
||||||
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
||||||
FloatWidths.
|
FloatWidths.
|
||||||
y) : GetExtentsOffset(TFOR.Up(),
|
y) : GetExtentsOffset(TFOR.Up(),
|
||||||
FloatWidths.y,
|
FloatWidths.y,
|
||||||
TargetOffset.y,
|
TargetOffset.y,
|
||||||
AnchorWidths.y);
|
AnchorWidths.y);
|
||||||
glm::vec3 p4 =
|
glm::vec3 p4 =
|
||||||
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
||||||
FloatWidths.
|
FloatWidths.
|
||||||
z) : GetExtentsOffset(TFOR.Back(),
|
z) : GetExtentsOffset(TFOR.Back(),
|
||||||
FloatWidths.z,
|
FloatWidths.z,
|
||||||
TargetOffset.z,
|
TargetOffset.z,
|
||||||
AnchorWidths.z);
|
AnchorWidths.z);
|
||||||
|
|
||||||
return p1 + p2 + p3 + p4;
|
return p1 + p2 + p3 + p4;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
||||||
glm::vec3 ThirdPersonFollow::CalculateCenter()
|
glm::vec3 ThirdPersonFollow::CalculateCenter()
|
||||||
{
|
{
|
||||||
return Target->get_global_translation() +
|
return Target->get_global_translation() +
|
||||||
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 ThirdPersonFollow::
|
glm::vec3 ThirdPersonFollow::
|
||||||
|
@ -82,37 +82,37 @@ GetPostsOffset(const glm::vec3 & DirectionVector, float AnchorWidth)
|
||||||
|
|
||||||
glm::vec3 ThirdPersonFollow::
|
glm::vec3 ThirdPersonFollow::
|
||||||
GetExtentsOffset(const glm::vec3 & DirectionVector, float AnchorWidth,
|
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 negated_offset_sign = ((0 <= TOffset) - (TOffset < 0)) * -1.f;
|
||||||
float TotalWidth = AnchorWidth + Width;
|
float TotalWidth = AnchorWidth + Width;
|
||||||
|
|
||||||
if (glm::abs(TOffset) > TotalWidth
|
if (glm::abs(TOffset) > TotalWidth
|
||||||
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
||||||
return DirectionVector * TotalWidth * negated_offset_sign;
|
return DirectionVector * TotalWidth * negated_offset_sign;
|
||||||
else {
|
else {
|
||||||
if (glm::abs(TOffset) >= AnchorWidth)
|
if (glm::abs(TOffset) >= AnchorWidth)
|
||||||
return DirectionVector * AnchorWidth * negated_offset_sign;
|
return DirectionVector * AnchorWidth * negated_offset_sign;
|
||||||
else
|
else
|
||||||
return DirectionVector * TOffset * -1.f;
|
return DirectionVector * TOffset * -1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return glm::vec3(0.f);
|
return glm::vec3(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
||||||
const glm::vec3 & To,
|
const glm::vec3 & To,
|
||||||
const glm::vec3 & Speeds,
|
const glm::vec3 & Speeds,
|
||||||
float Tick)
|
float Tick)
|
||||||
{
|
{
|
||||||
// Previously "FORTransform.TransformVector(Speeds)
|
// Previously "FORTransform.TransformVector(Speeds)
|
||||||
glm::vec3 TSpeed = glm::abs(TFOR.TransformDirection(Speeds));
|
glm::vec3 TSpeed = glm::abs(TFOR.TransformDirection(Speeds));
|
||||||
glm::vec3 TOffset = glm::abs(TFOR.TransformDirection(TargetOffset));
|
glm::vec3 TOffset = glm::abs(TFOR.TransformDirection(TargetOffset));
|
||||||
glm::vec3 TAnchorWidths =
|
glm::vec3 TAnchorWidths =
|
||||||
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
||||||
glm::vec3 TFloatWidths =
|
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 =
|
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 =
|
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 =
|
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,
|
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)
|
int float_epsilon(mfloat_t a, mfloat_t b, mfloat_t e)
|
||||||
|
@ -165,11 +165,11 @@ void ThirdPersonFollow::CalculateTargets()
|
||||||
// For rotation
|
// For rotation
|
||||||
// TODO: Check of this implementation is the same as UKismetMath FindLookAtRotation
|
// TODO: Check of this implementation is the same as UKismetMath FindLookAtRotation
|
||||||
TargetRotation =
|
TargetRotation =
|
||||||
RemoveLockedRotation(glm::quat
|
RemoveLockedRotation(glm::quat
|
||||||
(mytransform->
|
(mytransform->
|
||||||
get_global_transform()->get_origin() -
|
get_global_transform()->get_origin() -
|
||||||
Target->
|
Target->
|
||||||
get_global_transform()->get_origin()));
|
get_global_transform()->get_origin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
follow_removelockedrot()
|
follow_removelockedrot()
|
||||||
|
@ -185,11 +185,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
||||||
//
|
//
|
||||||
|
|
||||||
NewRotator.x =
|
NewRotator.x =
|
||||||
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
||||||
NewRotator.y =
|
NewRotator.y =
|
||||||
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
||||||
NewRotator.z =
|
NewRotator.z =
|
||||||
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
||||||
|
|
||||||
return glm::quat(NewRotator);
|
return glm::quat(NewRotator);
|
||||||
}
|
}
|
||||||
|
@ -199,11 +199,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
||||||
void ThirdPersonFollow::CalculateTargetOffset()
|
void ThirdPersonFollow::CalculateTargetOffset()
|
||||||
{
|
{
|
||||||
glm::vec3 p1 =
|
glm::vec3 p1 =
|
||||||
(mytransform->Forward() * Distance) +
|
(mytransform->Forward() * Distance) +
|
||||||
TFOR.TransformDirection(Offset) +
|
TFOR.TransformDirection(Offset) +
|
||||||
mytransform->get_global_translation();
|
mytransform->get_global_translation();
|
||||||
glm::vec3 p2 =
|
glm::vec3 p2 =
|
||||||
TFOR.InverseTransformDirection(Target->get_global_translation());
|
TFOR.InverseTransformDirection(Target->get_global_translation());
|
||||||
glm::vec3 p3 = TFOR.InverseTransformDirection(p1);
|
glm::vec3 p3 = TFOR.InverseTransformDirection(p1);
|
||||||
|
|
||||||
TargetOffset = p2 - p3;
|
TargetOffset = p2 - p3;
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
|
|
||||||
struct follow {
|
struct follow {
|
||||||
float distance;
|
float distance;
|
||||||
mfloat_t target_rot[4];
|
mfloat_t target_rot[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
mfloat_t *follow_calccenter();
|
mfloat_t *follow_calccenter();
|
||||||
|
@ -31,45 +31,45 @@ class ThirdPersonFollow {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum CameraType {
|
enum CameraType {
|
||||||
STATIONARY,
|
STATIONARY,
|
||||||
TRANSLATING,
|
TRANSLATING,
|
||||||
ROTATING,
|
ROTATING,
|
||||||
SPLINE
|
SPLINE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CameraTransition {
|
enum CameraTransition {
|
||||||
NONE,
|
NONE,
|
||||||
CROSSDISSOLVE,
|
CROSSDISSOLVE,
|
||||||
WIPE,
|
WIPE,
|
||||||
DIP
|
DIP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FrameOfReference {
|
enum FrameOfReference {
|
||||||
LOCAL,
|
LOCAL,
|
||||||
WORLD,
|
WORLD,
|
||||||
EXTERNAL
|
EXTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
ThirdPersonFollow() {
|
ThirdPersonFollow() {
|
||||||
// Rotation
|
// Rotation
|
||||||
RotationSpeed = 10.0f;
|
RotationSpeed = 10.0f;
|
||||||
LockPitch = LockYaw = LockRoll = true;
|
LockPitch = LockYaw = LockRoll = true;
|
||||||
|
|
||||||
XDirPosts = false;
|
XDirPosts = false;
|
||||||
YDirPosts = false;
|
YDirPosts = false;
|
||||||
ZDirPosts = false;
|
ZDirPosts = false;
|
||||||
|
|
||||||
|
|
||||||
// Translation
|
// Translation
|
||||||
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
||||||
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
||||||
//TranslationScales = glm::vec3(1, 1, 1);
|
//TranslationScales = glm::vec3(1, 1, 1);
|
||||||
|
|
||||||
// Frame settings
|
// Frame settings
|
||||||
Offset = glm::vec3(0.f, 0.f, 0.f);
|
Offset = glm::vec3(0.f, 0.f, 0.f);
|
||||||
Distance = 10;
|
Distance = 10;
|
||||||
|
|
||||||
AnchorSpeed = 80;
|
AnchorSpeed = 80;
|
||||||
} ~ThirdPersonFollow() {
|
} ~ThirdPersonFollow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,14 +81,14 @@ class ThirdPersonFollow {
|
||||||
|
|
||||||
|
|
||||||
void SetExternalFrame(Transform * val) {
|
void SetExternalFrame(Transform * val) {
|
||||||
ExternalFrame = val;
|
ExternalFrame = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The target the camera "looks" at, used for calculations
|
// The target the camera "looks" at, used for calculations
|
||||||
Transform *Target = nullptr;
|
Transform *Target = nullptr;
|
||||||
|
|
||||||
void SetTarget(Transform * val) {
|
void SetTarget(Transform * val) {
|
||||||
Target = val;
|
Target = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset from the target
|
// Offset from the target
|
||||||
|
@ -158,25 +158,25 @@ class ThirdPersonFollow {
|
||||||
|
|
||||||
/// Given a direction and width, find the offsets.
|
/// Given a direction and width, find the offsets.
|
||||||
glm::vec3 GetPostsOffset(const glm::vec3 & DirectionVector,
|
glm::vec3 GetPostsOffset(const glm::vec3 & DirectionVector,
|
||||||
float AnchorWidth);
|
float AnchorWidth);
|
||||||
|
|
||||||
/// Given anchors, what's the anchor width?
|
/// Given anchors, what's the anchor width?
|
||||||
glm::vec3 GetExtentsOffset(const glm::vec3 & DirectionVector,
|
glm::vec3 GetExtentsOffset(const glm::vec3 & DirectionVector,
|
||||||
float AnchorWidth, float TOffset,
|
float AnchorWidth, float TOffset,
|
||||||
float Width);
|
float Width);
|
||||||
|
|
||||||
glm::quat RemoveLockedRotation(const glm::quat & CurrentRotation);
|
glm::quat RemoveLockedRotation(const glm::quat & CurrentRotation);
|
||||||
|
|
||||||
glm::vec3 FrameBasedVectorLerp(const glm::vec3 & From,
|
glm::vec3 FrameBasedVectorLerp(const glm::vec3 & From,
|
||||||
const glm::vec3 & To,
|
const glm::vec3 & To,
|
||||||
const glm::vec3 & Speeds, float Tick);
|
const glm::vec3 & Speeds, float Tick);
|
||||||
|
|
||||||
glm::vec3 VectorLerpPiecewise(const glm::vec3 & From,
|
glm::vec3 VectorLerpPiecewise(const glm::vec3 & From,
|
||||||
const glm::vec3 & To,
|
const glm::vec3 & To,
|
||||||
const glm::vec3 & Alpha);
|
const glm::vec3 & Alpha);
|
||||||
|
|
||||||
bool GetLerpParam(const float Offst, const float AnchorWidth,
|
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
|
/// Set to a value that gives good clamping, smoothly. Activates when
|
||||||
/// the target is out of range.
|
/// the target is out of range.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void Light::serialize(FILE * file)
|
void Light::serialize(FILE * file)
|
||||||
{
|
{
|
||||||
|
@ -30,20 +29,20 @@ struct mDirectionalLight *dLight = NULL;
|
||||||
struct mDirectionalLight *MakeDLight()
|
struct mDirectionalLight *MakeDLight()
|
||||||
{
|
{
|
||||||
if (dLight != NULL) {
|
if (dLight != NULL) {
|
||||||
dLight =
|
dLight =
|
||||||
(struct mDirectionalLight *)
|
(struct mDirectionalLight *)
|
||||||
malloc(sizeof(struct mDirectionalLight));
|
malloc(sizeof(struct mDirectionalLight));
|
||||||
quat_from_euler(dLight->light.obj.transform.rotation,
|
quat_from_euler(dLight->light.obj.transform.rotation,
|
||||||
dlight_init_rot);
|
dlight_init_rot);
|
||||||
|
|
||||||
return dLight;
|
return dLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dLight;
|
return dLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlight_prepshader(struct mDirectionalLight *light,
|
void dlight_prepshader(struct mDirectionalLight *light,
|
||||||
struct shader *shader)
|
struct shader *shader)
|
||||||
{
|
{
|
||||||
mfloat_t fwd[3] = { 0.f };
|
mfloat_t fwd[3] = { 0.f };
|
||||||
trans_forward(fwd, &light->light.obj.transform);
|
trans_forward(fwd, &light->light.obj.transform);
|
||||||
|
@ -61,14 +60,14 @@ static int numLights = 0;
|
||||||
struct mPointLight *MakePointlight()
|
struct mPointLight *MakePointlight()
|
||||||
{
|
{
|
||||||
if (numLights < 4) {
|
if (numLights < 4) {
|
||||||
struct mPointLight *light =
|
struct mPointLight *light =
|
||||||
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
||||||
pointLights[numLights++] = light;
|
pointLights[numLights++] = light;
|
||||||
light->light.strength = 0.2f;
|
light->light.strength = 0.2f;
|
||||||
light->constant = 1.f;
|
light->constant = 1.f;
|
||||||
light->linear = 0.9f;
|
light->linear = 0.9f;
|
||||||
light->quadratic = 0.032f;
|
light->quadratic = 0.032f;
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -82,11 +81,11 @@ static void prepstring(char *buffer, char *prepend, const char *append)
|
||||||
void pointlights_prepshader(struct shader *shader)
|
void pointlights_prepshader(struct shader *shader)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numLights; i++)
|
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,
|
void pointlight_prepshader(struct mPointLight *light,
|
||||||
struct shader *shader, int num)
|
struct shader *shader, int num)
|
||||||
{
|
{
|
||||||
shader_use(shader);
|
shader_use(shader);
|
||||||
char prepend[100] = { '\0' };
|
char prepend[100] = { '\0' };
|
||||||
|
@ -121,10 +120,10 @@ static int numSpots = 0;
|
||||||
struct mSpotLight *MakeSpotlight()
|
struct mSpotLight *MakeSpotlight()
|
||||||
{
|
{
|
||||||
if (numSpots < 4) {
|
if (numSpots < 4) {
|
||||||
struct mSpotLight *light =
|
struct mSpotLight *light =
|
||||||
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
||||||
spotLights[numSpots++] = light;
|
spotLights[numSpots++] = light;
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -135,17 +134,17 @@ struct mSpotLight *MakeSpotlight()
|
||||||
void spotlights_prepshader(struct shader *shader)
|
void spotlights_prepshader(struct shader *shader)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numSpots; i++)
|
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,
|
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||||
int num)
|
int num)
|
||||||
{
|
{
|
||||||
mfloat_t fwd[3] = { 0.f };
|
mfloat_t fwd[3] = { 0.f };
|
||||||
trans_forward(fwd, &light->light.obj.transform);
|
trans_forward(fwd, &light->light.obj.transform);
|
||||||
shader_use(shader);
|
shader_use(shader);
|
||||||
shader_setvec3(shader, "spotLight.position",
|
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.direction", fwd);
|
||||||
shader_setvec3(shader, "spotLight.color", light->light.color);
|
shader_setvec3(shader, "spotLight.color", light->light.color);
|
||||||
shader_setfloat(shader, "spotLight.strength", light->light.strength);
|
shader_setfloat(shader, "spotLight.strength", light->light.strength);
|
||||||
|
@ -165,10 +164,10 @@ void light_gui(struct mLight *light)
|
||||||
object_gui(&light->obj);
|
object_gui(&light->obj);
|
||||||
|
|
||||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Light", NK_MINIMIZED)) {
|
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);
|
nk_property_float(ctx, "Strength", 0.f, &light->strength, 1.f, 0.01f, 0.001f);
|
||||||
// ImGui::ColorEdit3("Color", &light->color[0]);
|
// ImGui::ColorEdit3("Color", &light->color[0]);
|
||||||
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
||||||
nk_tree_pop(ctx);
|
nk_tree_pop(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,10 +177,10 @@ void pointlight_gui(struct mPointLight *light)
|
||||||
light_gui(&light->light);
|
light_gui(&light->light);
|
||||||
|
|
||||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Point Light", NK_MINIMIZED)) {
|
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, "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, "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_property_float(ctx, "Quadratic", 0.f, &light->quadratic, 0.3f, 0.01f, 0.001f);
|
||||||
nk_tree_pop(ctx);
|
nk_tree_pop(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -191,12 +190,12 @@ void spotlight_gui(struct mSpotLight *spot)
|
||||||
light_gui(&spot->light);
|
light_gui(&spot->light);
|
||||||
|
|
||||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Spotlight", NK_MINIMIZED)) {
|
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, "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, "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, "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, "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_property_float(ctx, "Outer Cutoff Degrees", 0.f, &spot->outerCutoff, 0.7f, 0.01f, 0.001f);
|
||||||
nk_tree_pop(ctx);
|
nk_tree_pop(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct mLight {
|
struct mLight {
|
||||||
struct gameobject *go;
|
struct gameobject *go;
|
||||||
uint8_t color[3];
|
uint8_t color[3];
|
||||||
float strength;
|
float strength;
|
||||||
int dynamic;
|
int dynamic;
|
||||||
int on;
|
int on;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -21,7 +21,7 @@ struct mPointLight {
|
||||||
|
|
||||||
struct mPointLight *MakePointlight();
|
struct mPointLight *MakePointlight();
|
||||||
void pointlight_prepshader(struct mPointLight *light,
|
void pointlight_prepshader(struct mPointLight *light,
|
||||||
struct shader *shader, int num);
|
struct shader *shader, int num);
|
||||||
void pointlights_prepshader(struct shader *shader);
|
void pointlights_prepshader(struct shader *shader);
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ struct mSpotLight {
|
||||||
struct mSpotLight *MakeSpotlight();
|
struct mSpotLight *MakeSpotlight();
|
||||||
void spotlight_gui(struct mSpotLight *light);
|
void spotlight_gui(struct mSpotLight *light);
|
||||||
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||||
int num);
|
int num);
|
||||||
void spotlights_prepshader(struct shader *shader);
|
void spotlights_prepshader(struct shader *shader);
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ struct mDirectionalLight {
|
||||||
};
|
};
|
||||||
|
|
||||||
void dlight_prepshader(struct mDirectionalLight *light,
|
void dlight_prepshader(struct mDirectionalLight *light,
|
||||||
struct shader *shader);
|
struct shader *shader);
|
||||||
struct mDirectionalLight *MakeDLight();
|
struct mDirectionalLight *MakeDLight();
|
||||||
|
|
||||||
extern struct mDirectionalLight *dLight;
|
extern struct mDirectionalLight *dLight;
|
||||||
|
|
|
@ -4,122 +4,94 @@
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void DrawMesh(struct mesh *mesh, struct shader *shader)
|
void DrawMesh(struct mesh *mesh, struct shader *shader) {
|
||||||
{
|
// bind appropriate textures
|
||||||
// bind appropriate textures
|
uint32_t diffuseNr = 1;
|
||||||
uint32_t diffuseNr = 1;
|
uint32_t specularNr = 1;
|
||||||
uint32_t specularNr = 1;
|
uint32_t normalNr = 1;
|
||||||
uint32_t normalNr = 1;
|
uint32_t heightNr = 1;
|
||||||
uint32_t heightNr = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
// for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
||||||
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||||
// retrieve texture number (the N in diffuse_textureN)
|
// retrieve texture number (the N in diffuse_textureN)
|
||||||
char number = 0;
|
// char number = 0;
|
||||||
// TODO: malloc every single frame ... nope! Change to stack
|
// TODO: malloc every single frame ... nope! Change to stack
|
||||||
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
||||||
/*
|
/*
|
||||||
if (mesh->textures[i].type == TEX_DIFF)
|
// if (mesh->textures[i].type == TEX_DIFF)
|
||||||
number = diffuseNr++;
|
// number = diffuseNr++;
|
||||||
else if (mesh->textures[i].type == TEX_SPEC)
|
// else if (mesh->textures[i].type == TEX_SPEC)
|
||||||
number = specularNr++;
|
// number = specularNr++;
|
||||||
else if (mesh->textures[i].type == TEX_NORM)
|
// else if (mesh->textures[i].type == TEX_NORM)
|
||||||
number = normalNr++;
|
// number = normalNr++;
|
||||||
else if (mesh->textures[i].type == TEX_HEIGHT)
|
// else if (mesh->textures[i].type == TEX_HEIGHT)
|
||||||
number = heightNr++;
|
// number = heightNr++;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
||||||
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
||||||
free(name);
|
free(name);
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
// draw mesh
|
|
||||||
glBindVertexArray(mesh->VAO);
|
|
||||||
DrawMeshAgain(mesh);
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
// triCount += indices.size() / 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawMeshAgain(struct mesh *mesh) {
|
||||||
void DrawMeshAgain(struct mesh *mesh)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
void setupmesh(struct mesh *mesh) {
|
||||||
uint32_t * indices, uint32_t * ie,
|
/*
|
||||||
struct Texture *textures, struct Texture *te)
|
// create buffers/arrays
|
||||||
{
|
glGenVertexArrays(1, &mesh->VAO);
|
||||||
struct mesh *newmesh = (struct mesh *) malloc(sizeof(struct mesh));
|
glGenBuffers(1, &mesh->VBO);
|
||||||
newmesh->vertices = vertices;
|
glGenBuffers(1, &mesh->EBO);
|
||||||
newmesh->ve = ve;
|
|
||||||
newmesh->indices = indices;
|
|
||||||
newmesh->ie = ie;
|
|
||||||
newmesh->textures = textures;
|
|
||||||
newmesh->te = te;
|
|
||||||
|
|
||||||
setupmesh(newmesh);
|
glBindVertexArray(mesh->VAO);
|
||||||
return newmesh;
|
// load data into vertex buffers
|
||||||
}
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||||
|
|
||||||
void setupmesh(struct mesh *mesh)
|
|
||||||
{
|
// 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.
|
||||||
// create buffers/arrays
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
glGenVertexArrays(1, &mesh->VAO);
|
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
||||||
glGenBuffers(1, &mesh->VBO);
|
&mesh->vertices[0], GL_STATIC_DRAW);
|
||||||
glGenBuffers(1, &mesh->EBO);
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
||||||
glBindVertexArray(mesh->VAO);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||||
// load data into vertex buffers
|
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
&mesh->indices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// set the vertex attribute pointers
|
||||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to vevc array which
|
// vertex Positions
|
||||||
// again translates to 3/2 floats which translates to a byte array.
|
glEnableVertexAttribArray(0);
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
||||||
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
// vertex normals
|
||||||
&mesh->vertices[0], GL_STATIC_DRAW);
|
glEnableVertexAttribArray(1);
|
||||||
|
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
// vertex texture coords
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
glEnableVertexAttribArray(2);
|
||||||
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
||||||
&mesh->indices[0], GL_STATIC_DRAW);
|
// vertex tangent
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
// set the vertex attribute pointers
|
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
||||||
// vertex Positions
|
// vertex bitangent
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(4);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
||||||
// vertex normals
|
|
||||||
glEnableVertexAttribArray(1);
|
// Bone ids
|
||||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
glEnableVertexAttribArray(5);
|
||||||
// vertex texture coords
|
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex,
|
||||||
glEnableVertexAttribArray(2);
|
m_BoneIDs
|
||||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
[MAX_BONE_INFLUENCE]));
|
||||||
// vertex tangent
|
|
||||||
glEnableVertexAttribArray(3);
|
// Weights
|
||||||
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
glEnableVertexAttribArray(6);
|
||||||
// vertex bitangent
|
// glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, m_Weights));
|
||||||
glEnableVertexAttribArray(4);
|
|
||||||
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// 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
|
#define MESH_H
|
||||||
|
|
||||||
#include "mathc.h"
|
#include "mathc.h"
|
||||||
|
#include "sokol/sokol_gfx.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct shader;
|
struct shader;
|
||||||
struct Texture;
|
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 mesh {
|
||||||
struct Vertex *vertices;
|
sg_bindings bind;
|
||||||
struct Vertex *ve;
|
uint32_t face_count;
|
||||||
uint32_t *indices;
|
|
||||||
uint32_t *ie;
|
|
||||||
struct Texture *textures;
|
|
||||||
struct Texture *te;
|
|
||||||
uint32_t VAO, VBO, EBO;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve, uint32_t *indices, uint32_t *ie, struct Texture *textures, struct Texture *te);
|
||||||
uint32_t * indices, uint32_t * ie,
|
void setupmesh(struct mesh *mesh); /* Loads mesh into the GPU */
|
||||||
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 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
|
#endif
|
||||||
|
|
|
@ -5,10 +5,27 @@
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "stb_ds.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 <cgltf.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
#include "mathc.h"
|
||||||
|
|
||||||
|
#include "sokol/sokol_gfx.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *key;
|
char *key;
|
||||||
struct Texture *value;
|
struct Texture *value;
|
||||||
|
@ -18,6 +35,59 @@ static void processnode();
|
||||||
static void processmesh();
|
static void processmesh();
|
||||||
static void processtexture();
|
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) {
|
struct model *GetExistingModel(const char *path) {
|
||||||
if (!path || path[0] == '\0') return NULL;
|
if (!path || path[0] == '\0') return NULL;
|
||||||
|
|
||||||
|
@ -27,8 +97,18 @@ struct model *GetExistingModel(const char *path) {
|
||||||
return MakeModel(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) {
|
struct model *MakeModel(const char *path) {
|
||||||
|
YughWarn("Making the model from %s.", path);
|
||||||
cgltf_options options = {0};
|
cgltf_options options = {0};
|
||||||
cgltf_data *data = NULL;
|
cgltf_data *data = NULL;
|
||||||
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
||||||
|
@ -45,188 +125,166 @@ struct model *MakeModel(const char *path) {
|
||||||
return NULL;
|
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++) {
|
for (int i = 0; i < data->meshes_count; i++) {
|
||||||
|
cgltf_mesh *mesh = &data->meshes[i];
|
||||||
|
struct mesh newmesh = {0};
|
||||||
|
arrput(model->meshes,newmesh);
|
||||||
|
|
||||||
if (data->nodes[i].mesh) {
|
YughWarn("Making mesh %d. It has %d primitives.", i, mesh->primitives_count);
|
||||||
cgltf_mesh *mesh = data->nodes[i].mesh;
|
|
||||||
|
|
||||||
for (int j = 0; j < mesh->primitives_count; j++) {
|
for (int j = 0; j < mesh->primitives_count; j++) {
|
||||||
cgltf_primitive primitive = mesh->primitives[j];
|
cgltf_primitive primitive = mesh->primitives[j];
|
||||||
|
|
||||||
for (int k = 0; k < primitive.attributes_count; k++) {
|
if (primitive.indices) {
|
||||||
cgltf_attribute attribute = primitive.attributes[k];
|
int c = primitive.indices->count;
|
||||||
|
memcpy(idxs, cgltf_buffer_view_data(primitive.indices->buffer_view), sizeof(uint16_t) * c);
|
||||||
|
|
||||||
switch (attribute.type) {
|
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});
|
||||||
|
|
||||||
case cgltf_attribute_type_position:
|
model->meshes[j].face_count = c;
|
||||||
// float *vs = malloc(sizeof(float) * cgltf_accessor_unpack_floats(attribute.accessor, NULL, attribute.accessor.count);
|
} else {
|
||||||
// cgltf_accessor_unpack_floats(attribute.accessor, vs, attribute.accessor.count);
|
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;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_normal:
|
case cgltf_attribute_type_normal:
|
||||||
break;
|
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:
|
case cgltf_attribute_type_texcoord:
|
||||||
break;
|
model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
|
.data.ptr = vs,
|
||||||
case cgltf_attribute_type_texcoord:
|
.data.size = sizeof(float) * n});
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: DELETE
|
HMM_Vec3 eye = {50,10,5};
|
||||||
static void processnode() {
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->mNumMeshes; i++) {
|
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
||||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
HMM_Mat4 proj = HMM_Perspective_RH_ZO(45, 1200.f / 720, 0.1, 10000);
|
||||||
*mp = processMesh(mesh, scene);
|
HMM_Vec3 center = {0.f, 0.f, 0.f};
|
||||||
mp++;
|
HMM_Vec3 up = {0.f, 1.f, 0.f};
|
||||||
}
|
HMM_Mat4 view = HMM_LookAt_RH(eye, center, up);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->mNumChildren; i++) {
|
HMM_Mat4 vp = HMM_MulM4(proj, view);
|
||||||
processnode(node->mChildren[i], scene);
|
HMM_Mat4 mvp = HMM_MulM4(vp, amodel);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
HMM_Vec3 lp = {1, 1, 1};
|
||||||
*/
|
HMM_Vec3 dir_dir = HMM_NormV3(HMM_SubV3(center, dirl_pos));
|
||||||
static void processmesh() {
|
|
||||||
/*
|
HMM_Mat4 m2[4];
|
||||||
Vertex *vertices =
|
m2[0] = view;
|
||||||
(Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices);
|
m2[1] = amodel;
|
||||||
Vertex *vp = vertices + mesh->mNumVertices;
|
m2[2] = proj;
|
||||||
Vertex *p = vertices;
|
m2[3] = lsm;
|
||||||
for (int i = 0; i < mesh->mNumVertices; i++) {
|
|
||||||
// positions
|
HMM_Vec3 f_ubo[5];
|
||||||
(p + i)->Position.x = mesh->mVertices[i][0];
|
f_ubo[0] = lp;
|
||||||
(p + i)->Position.y = mesh->mVertices[i][1];
|
f_ubo[1] = dir_dir;
|
||||||
(p + i)->Position.z = mesh->mVertices[i][2];
|
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));
|
||||||
|
|
||||||
|
|
||||||
// normals
|
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||||
if (mesh->HasNormals()) {
|
sg_apply_bindings(&model->meshes[i].bind);
|
||||||
(p + i)->Normal.x = mesh->mNormals[i][0];
|
sg_draw(0, model->meshes[i].face_count, 1);
|
||||||
(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
|
#ifndef MODEL_H
|
||||||
#define MODEL_H
|
#define MODEL_H
|
||||||
|
|
||||||
struct mesh;
|
#include "mesh.h"
|
||||||
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
|
extern HMM_Vec3 eye;
|
||||||
struct shader;
|
struct shader;
|
||||||
|
|
||||||
struct model {
|
struct model {
|
||||||
struct mesh *meshes;
|
struct mesh *meshes;
|
||||||
struct mesh *mp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get the model at a path, or create and return if it doesn't exist */
|
/* 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 */
|
/* Load a model from memory into the GPU */
|
||||||
void loadmodel(struct model *model);
|
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);
|
void draw_models(struct model *model, struct shader *shader);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "skybox.h"
|
#include "skybox.h"
|
||||||
|
|
||||||
#include "shader.h"
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include <string.h>
|
#include "shader.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "openglrender.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,
|
-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 *MakeSkybox(const char *cubemap) {
|
||||||
{
|
/*
|
||||||
/*
|
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
||||||
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
|
||||||
|
|
||||||
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
||||||
shader_compile(newskybox->shader);
|
shader_compile(newskybox->shader);
|
||||||
|
|
||||||
glGenVertexArrays(1, &newskybox->VAO);
|
glGenVertexArrays(1, &newskybox->VAO);
|
||||||
glGenBuffers(1, &newskybox->VBO);
|
glGenBuffers(1, &newskybox->VBO);
|
||||||
glBindVertexArray(newskybox->VAO);
|
glBindVertexArray(newskybox->VAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
||||||
(void *) 0);
|
(void *) 0);
|
||||||
|
|
||||||
shader_use(newskybox->shader);
|
shader_use(newskybox->shader);
|
||||||
shader_setint(newskybox->shader, "skybox", 0);
|
shader_setint(newskybox->shader, "skybox", 0);
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
const char *faces[6] =
|
const char *faces[6] =
|
||||||
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
||||||
"back.jpg"
|
"back.jpg"
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
glGenTextures(1, &newskybox->id);
|
glGenTextures(1, &newskybox->id);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
||||||
*/
|
*/
|
||||||
/*char buf[100] = { '\0' };*/
|
/*char buf[100] = { '\0' };*/
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
/*
|
/*
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
strcat(buf, cubemap);
|
strcat(buf, cubemap);
|
||||||
strcat(buf, "/");
|
strcat(buf, "/");
|
||||||
strcat(buf, faces[i]);
|
strcat(buf, faces[i]);
|
||||||
IMG_Load(buf);
|
IMG_Load(buf);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
||||||
2048, 0, GL_RGB, GL_UNSIGNED_BYTE, data->pixels);
|
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_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||||
GL_CLAMP_TO_EDGE);
|
GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||||
GL_CLAMP_TO_EDGE);
|
GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
||||||
GL_CLAMP_TO_EDGE);
|
GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
|
||||||
return newskybox;
|
return newskybox;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void skybox_draw(const struct mSkybox *skybox,
|
void skybox_draw(const struct mSkybox *skybox,
|
||||||
const struct mCamera *camera)
|
const struct mCamera *camera) {
|
||||||
{
|
/*
|
||||||
/*
|
shader_use(skybox->shader);
|
||||||
shader_use(skybox->shader);
|
|
||||||
|
|
||||||
mfloat_t view[16] = { 0.f };
|
mfloat_t view[16] = { 0.f };
|
||||||
getviewmatrix(view, camera);
|
getviewmatrix(view, camera);
|
||||||
shader_setmat4(skybox->shader, "skyview", view);
|
shader_setmat4(skybox->shader, "skyview", view);
|
||||||
|
|
||||||
// skybox cube
|
// skybox cube
|
||||||
glBindVertexArray(skybox->VAO);
|
glBindVertexArray(skybox->VAO);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
struct mCamera;
|
struct mCamera;
|
||||||
|
|
||||||
struct mSkybox {
|
struct mSkybox {
|
||||||
unsigned int VAO;
|
unsigned int VAO;
|
||||||
unsigned int VBO;
|
unsigned int VBO;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
struct shader *shader;
|
struct shader *shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mSkybox *MakeSkybox(const char *cubemap);
|
struct mSkybox *MakeSkybox(const char *cubemap);
|
||||||
void skybox_draw(const struct mSkybox *skybox,
|
void skybox_draw(const struct mSkybox *skybox,
|
||||||
const struct mCamera *camera);
|
const struct mCamera *camera);
|
||||||
|
|
||||||
#endif
|
#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 "anim.h"
|
||||||
#include "stb_ds.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "stb_ds.h"
|
||||||
|
|
||||||
struct anim make_anim() {
|
struct anim make_anim() {
|
||||||
struct anim a = {0};
|
struct anim a = {0};
|
||||||
a.interp = 1;
|
a.interp = 1;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_anim(struct anim a) {
|
void free_anim(struct anim a) {
|
||||||
arrfree(a.frames);
|
arrfree(a.frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct anim anim_add_keyframe(struct anim a, struct keyframe key) {
|
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) {
|
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) {
|
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)
|
if (t > anim.frames[i + 1].time)
|
||||||
continue;
|
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) {
|
double lerp_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)
|
if (t > anim.frames[i + 1].time)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double intv = interval(anim.frames[i], anim.frames[i+1], t);
|
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 ((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) {
|
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) {
|
double anim_val(struct anim anim, double t) {
|
||||||
if (anim.interp == 0)
|
if (anim.interp == 0)
|
||||||
return near_val(anim, t);
|
return near_val(anim, t);
|
||||||
|
|
||||||
return lerp_val(anim, t);
|
return lerp_val(anim, t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,18 @@
|
||||||
#define ANIM_H
|
#define ANIM_H
|
||||||
|
|
||||||
struct keyframe {
|
struct keyframe {
|
||||||
double time;
|
double time;
|
||||||
double val;
|
double val;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct anim {
|
struct anim {
|
||||||
struct keyframe *frames;
|
struct keyframe *frames;
|
||||||
int loop;
|
int loop;
|
||||||
int interp;
|
int interp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct anim make_anim();
|
struct anim make_anim();
|
||||||
struct anim anim_add_keyframe(struct anim a, struct keyframe f);
|
struct anim anim_add_keyframe(struct anim a, struct keyframe f);
|
||||||
double anim_val(struct anim anim, double t);
|
double anim_val(struct anim anim, double t);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,70 +3,64 @@
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
|
|
||||||
const float CAMERA_MINSPEED = 1.f;
|
const float CAMERA_MINSPEED = 1.f;
|
||||||
const float CAMERA_MAXSPEED = 300.f;
|
const float CAMERA_MAXSPEED = 300.f;
|
||||||
const float CAMERA_ROTATESPEED = 6.f;
|
const float CAMERA_ROTATESPEED = 6.f;
|
||||||
|
|
||||||
void cam_goto_object(struct mCamera *cam, struct mTransform *transform)
|
void cam_goto_object(struct mCamera *cam, struct mTransform *transform) {
|
||||||
{
|
mfloat_t fwd[3] = {0.f};
|
||||||
mfloat_t fwd[3] = { 0.f };
|
vec3_subtract(cam->transform.position, transform->position,
|
||||||
vec3_subtract(cam->transform.position, transform->position,
|
vec3_multiply_f(fwd, trans_forward(fwd, transform),
|
||||||
vec3_multiply_f(fwd, trans_forward(fwd, transform),
|
10.f));
|
||||||
10.f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cam_inverse_goto(struct mCamera *cam, struct mTransform *transform)
|
void cam_inverse_goto(struct mCamera *cam, struct mTransform *transform) {
|
||||||
{
|
mfloat_t fwd[3] = {0.f};
|
||||||
mfloat_t fwd[3] = { 0.f };
|
vec3_add(transform->position, cam->transform.position,
|
||||||
vec3_add(transform->position, cam->transform.position,
|
vec3_multiply_f(fwd, trans_forward(fwd, &cam->transform),
|
||||||
vec3_multiply_f(fwd, trans_forward(fwd, &cam->transform),
|
10.f));
|
||||||
10.f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *getviewmatrix(mfloat_t view[16],
|
mfloat_t *getviewmatrix(mfloat_t view[16],
|
||||||
const struct mCamera *const camera)
|
const struct mCamera *const camera) {
|
||||||
{
|
mfloat_t fwd[3] = {0.f};
|
||||||
mfloat_t fwd[3] = { 0.f };
|
mfloat_t look[3] = {0.f};
|
||||||
mfloat_t look[3] = { 0.f };
|
vec3_rotate_quat(fwd, FORWARD, camera->transform.rotation);
|
||||||
vec3_rotate_quat(fwd, FORWARD, camera->transform.rotation);
|
vec3_add(look, camera->transform.position, fwd);
|
||||||
vec3_add(look, camera->transform.position, fwd);
|
mat4_look_at(view, camera->transform.position, look, UP);
|
||||||
mat4_look_at(view, camera->transform.position, look, UP);
|
return view;
|
||||||
return view;
|
/*return mat4_look_at(view, ncam.transform.position,
|
||||||
/*return mat4_look_at(view, ncam.transform.position,
|
vec3_add(look, ncam.transform.position,
|
||||||
vec3_add(look, ncam.transform.position,
|
trans_forward(fwd, &ncam.transform)),
|
||||||
trans_forward(fwd, &ncam.transform)),
|
UP); */
|
||||||
UP); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void camera_2d_update(struct mCamera *camera, float deltaT)
|
void camera_2d_update(struct mCamera *camera, float deltaT) {
|
||||||
{
|
static mfloat_t frame[3];
|
||||||
static mfloat_t frame[3];
|
vec3_zero(frame);
|
||||||
vec3_zero(frame);
|
if (action_down(GLFW_KEY_W))
|
||||||
if (action_down(GLFW_KEY_W))
|
vec3_add(frame, frame, UP);
|
||||||
vec3_add(frame, frame, UP);
|
if (action_down(GLFW_KEY_S))
|
||||||
if (action_down(GLFW_KEY_S))
|
vec3_add(frame, frame, DOWN);
|
||||||
vec3_add(frame, frame, DOWN);
|
if (action_down(GLFW_KEY_A))
|
||||||
if (action_down(GLFW_KEY_A))
|
vec3_add(frame, frame, LEFT);
|
||||||
vec3_add(frame, frame, LEFT);
|
if (action_down(GLFW_KEY_D))
|
||||||
if (action_down(GLFW_KEY_D))
|
vec3_add(frame, frame, RIGHT);
|
||||||
vec3_add(frame, frame, RIGHT);
|
|
||||||
|
|
||||||
float speedMult = action_down(GLFW_KEY_LEFT_SHIFT) ? 2.f : 1.f;
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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,
|
void camera_update(struct mCamera * camera, float mouseX, float mouseY,
|
||||||
const uint8_t * keystate, int32_t mouseWheelY,
|
const uint8_t * keystate, int32_t mouseWheelY,
|
||||||
float deltaTime)
|
float deltaTime)
|
||||||
{
|
{
|
||||||
// if (SDL_GetRelativeMouseMode()) vec3_zero(camera->frame_move);
|
// 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);
|
vec3_zero(camera->frame_move);
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_W])
|
if (currentKeystates[SDL_SCANCODE_W])
|
||||||
vec3_add(camera->frame_move, camera->frame_move,
|
vec3_add(camera->frame_move, camera->frame_move,
|
||||||
trans_forward(holdvec, &camera->transform));
|
trans_forward(holdvec, &camera->transform));
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_S])
|
if (currentKeystates[SDL_SCANCODE_S])
|
||||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||||
trans_forward(holdvec, &camera->transform));
|
trans_forward(holdvec, &camera->transform));
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_A])
|
if (currentKeystates[SDL_SCANCODE_A])
|
||||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||||
trans_right(holdvec, &camera->transform));
|
trans_right(holdvec, &camera->transform));
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_D])
|
if (currentKeystates[SDL_SCANCODE_D])
|
||||||
vec3_add(camera->frame_move, camera->frame_move,
|
vec3_add(camera->frame_move, camera->frame_move,
|
||||||
trans_right(holdvec, &camera->transform));
|
trans_right(holdvec, &camera->transform));
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_E])
|
if (currentKeystates[SDL_SCANCODE_E])
|
||||||
vec3_add(camera->frame_move, camera->frame_move,
|
vec3_add(camera->frame_move, camera->frame_move,
|
||||||
trans_up(holdvec, &camera->transform));
|
trans_up(holdvec, &camera->transform));
|
||||||
|
|
||||||
if (currentKeystates[SDL_SCANCODE_Q])
|
if (currentKeystates[SDL_SCANCODE_Q])
|
||||||
vec3_subtract(camera->frame_move, camera->frame_move,
|
vec3_subtract(camera->frame_move, camera->frame_move,
|
||||||
trans_up(holdvec, &camera->transform));
|
trans_up(holdvec, &camera->transform));
|
||||||
|
|
||||||
camera->speedMult = currentKeystates[SDL_SCANCODE_LSHIFT] ? 2.f : 1.f;
|
camera->speedMult = currentKeystates[SDL_SCANCODE_LSHIFT] ? 2.f : 1.f;
|
||||||
|
|
||||||
|
|
||||||
if (!vec3_is_zero(camera->frame_move)) {
|
if (!vec3_is_zero(camera->frame_move)) {
|
||||||
vec3_normalize(camera->frame_move, camera->frame_move);
|
vec3_normalize(camera->frame_move, camera->frame_move);
|
||||||
vec3_add(camera->transform.position, camera->transform.position,
|
vec3_add(camera->transform.position, camera->transform.position,
|
||||||
vec3_multiply_f(camera->frame_move, camera->frame_move,
|
vec3_multiply_f(camera->frame_move, camera->frame_move,
|
||||||
camera->speed * camera->speedMult *
|
camera->speed * camera->speedMult *
|
||||||
deltaTime));
|
deltaTime));
|
||||||
}
|
}
|
||||||
// Adjust speed based on mouse wheel
|
// Adjust speed based on mouse wheel
|
||||||
camera->speed =
|
camera->speed =
|
||||||
clampf(camera->speed + mouseWheelY, CAMERA_MINSPEED,
|
clampf(camera->speed + mouseWheelY, CAMERA_MINSPEED,
|
||||||
CAMERA_MAXSPEED);
|
CAMERA_MAXSPEED);
|
||||||
|
|
||||||
|
|
||||||
// TODO: Handle this as additive quaternions
|
// 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)
|
if (camera->pitch > 89.f)
|
||||||
camera->pitch = 89.f;
|
camera->pitch = 89.f;
|
||||||
if (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 qyaw[4] = {0.f};
|
||||||
mfloat_t qpitch[4] = {0.f};
|
mfloat_t qpitch[4] = {0.f};
|
||||||
|
|
|
@ -8,10 +8,10 @@ extern const float CAMERA_MAXSPEED;
|
||||||
extern const float CAMERA_ROTATESPEED;
|
extern const float CAMERA_ROTATESPEED;
|
||||||
|
|
||||||
struct mCamera {
|
struct mCamera {
|
||||||
struct mTransform transform;
|
struct mTransform transform;
|
||||||
float speed;
|
float speed;
|
||||||
float speedMult;
|
float speedMult;
|
||||||
mfloat_t frame_move[VEC3_SIZE];
|
mfloat_t frame_move[VEC3_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
void camera_2d_update(struct mCamera *camera, float deltaT);
|
void camera_2d_update(struct mCamera *camera, float deltaT);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#define MAXPATH 256 /* 255 chars + null */
|
||||||
#define MAXPATH 256 /* 255 chars + null */
|
|
||||||
#define MAXNAME 50
|
#define MAXNAME 50
|
||||||
|
|
||||||
#define SCREEN_WIDTH 1280
|
#define SCREEN_WIDTH 1280
|
||||||
|
|
|
@ -1,206 +1,189 @@
|
||||||
#include "datastream.h"
|
#include "datastream.h"
|
||||||
|
|
||||||
#include "render.h"
|
|
||||||
#include "config.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 "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;
|
struct shader *vid_shader;
|
||||||
|
|
||||||
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t * plane)
|
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t *plane) {
|
||||||
{
|
/*
|
||||||
/*
|
glActiveTexture(unit);
|
||||||
glActiveTexture(unit);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, plane->width, plane->height, 0, GL_RED, GL_UNSIGNED_BYTE, plane->data);
|
||||||
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)
|
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
|
||||||
{
|
struct datastream *ds = user;
|
||||||
struct datastream *ds = user;
|
shader_use(ds->shader);
|
||||||
shader_use(ds->shader);
|
/*
|
||||||
/*
|
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y);
|
||||||
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y);
|
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb);
|
||||||
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb);
|
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr);
|
||||||
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr);
|
*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_audio(plm_t * mpeg, plm_samples_t * samples, void *user)
|
static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
|
||||||
{
|
struct datastream *ds = user;
|
||||||
struct datastream *ds = user;
|
short t;
|
||||||
short t;
|
|
||||||
|
|
||||||
for (int i = 0; i < samples->count * CHANNELS; i++) {
|
for (int i = 0; i < samples->count * CHANNELS; i++) {
|
||||||
t = (short)(samples->interleaved[i] * SHRT_MAX);
|
t = (short)(samples->interleaved[i] * SHRT_MAX);
|
||||||
cbuf_push(ds->astream->buf, t*5);
|
cbuf_push(ds->astream->buf, t * 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Texture *ds_maketexture(struct datastream *ds)
|
struct Texture *ds_maketexture(struct datastream *ds) {
|
||||||
{
|
/*
|
||||||
/*
|
struct Texture *new = malloc(sizeof(*new));
|
||||||
struct Texture *new = malloc(sizeof(*new));
|
new->id = ds->texture_cb;
|
||||||
new->id = ds->texture_cb;
|
new->width = 500;
|
||||||
new->width = 500;
|
new->height = 500;
|
||||||
new->height = 500;
|
return new;
|
||||||
return new;
|
*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
|
||||||
{
|
// ds_stop(ds);
|
||||||
// ds_stop(ds);
|
char buf[MAXPATH] = {'\0'};
|
||||||
char buf[MAXPATH] = {'\0'};
|
sprintf(buf, "%s%s", "video/", video);
|
||||||
sprintf(buf, "%s%s", "video/", video);
|
ds->plm = plm_create_with_filename(buf);
|
||||||
ds->plm = plm_create_with_filename(buf);
|
|
||||||
|
|
||||||
if (!ds->plm) {
|
if (!ds->plm) {
|
||||||
YughLog(0, 0, "Couldn't open %s", video);
|
YughLog(0, 0, "Couldn't open %s", video);
|
||||||
}
|
}
|
||||||
|
|
||||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||||
video,
|
video,
|
||||||
plm_get_framerate(ds->plm),
|
plm_get_framerate(ds->plm),
|
||||||
plm_get_samplerate(ds->plm),
|
plm_get_samplerate(ds->plm),
|
||||||
plm_get_num_audio_streams(ds->plm),
|
plm_get_num_audio_streams(ds->plm),
|
||||||
plm_get_duration(ds->plm)
|
plm_get_duration(ds->plm));
|
||||||
);
|
|
||||||
|
|
||||||
ds->astream = soundstream_make();
|
ds->astream = soundstream_make();
|
||||||
struct dsp_filter astream_filter;
|
struct dsp_filter astream_filter;
|
||||||
astream_filter.data = &ds->astream;
|
astream_filter.data = &ds->astream;
|
||||||
astream_filter.filter = soundstream_fillbuf;
|
astream_filter.filter = soundstream_fillbuf;
|
||||||
|
|
||||||
//struct dsp_filter lpf = lpf_make(8, 10000);
|
// struct dsp_filter lpf = lpf_make(8, 10000);
|
||||||
struct dsp_filter lpf = lpf_make(1, 200);
|
struct dsp_filter lpf = lpf_make(1, 200);
|
||||||
struct dsp_iir *iir = lpf.data;
|
struct dsp_iir *iir = lpf.data;
|
||||||
iir->in = astream_filter;
|
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;
|
struct dsp_filter llpf = lp_fir_make(20);
|
||||||
hiir->in = astream_filter;
|
struct dsp_fir *fir = llpf.data;
|
||||||
|
fir->in = astream_filter;
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
// first_free_bus(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);
|
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_enabled(ds->plm, true);
|
||||||
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
plm_set_audio_stream(ds->plm, 0);
|
||||||
plm_set_loop(ds->plm, false);
|
|
||||||
|
|
||||||
plm_set_audio_enabled(ds->plm, true);
|
// Adjust the audio lead time according to the audio_spec buffer size
|
||||||
plm_set_audio_stream(ds->plm, 0);
|
plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE);
|
||||||
|
|
||||||
// Adjust the audio lead time according to the audio_spec buffer size
|
ds->playing = true;
|
||||||
plm_set_audio_lead_time(ds->plm, BUF_FRAMES/SAMPLERATE);
|
|
||||||
|
|
||||||
ds->playing = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct datastream *MakeDatastream()
|
struct datastream *MakeDatastream() {
|
||||||
{
|
struct datastream *newds = malloc(sizeof(*newds));
|
||||||
struct datastream *newds = malloc(sizeof(*newds));
|
/*
|
||||||
/*
|
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl");
|
||||||
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl");
|
|
||||||
|
|
||||||
newds->shader = vid_shader;
|
newds->shader = vid_shader;
|
||||||
shader_use(newds->shader);
|
shader_use(newds->shader);
|
||||||
glGenTextures(1, &newds->texture_y);
|
glGenTextures(1, &newds->texture_y);
|
||||||
glBindTexture(GL_TEXTURE_2D, 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_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
shader_setint(newds->shader, "texture_y", 0);
|
shader_setint(newds->shader, "texture_y", 0);
|
||||||
|
|
||||||
glGenTextures(1, &newds->texture_cb);
|
glGenTextures(1, &newds->texture_cb);
|
||||||
glBindTexture(GL_TEXTURE_2D, 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_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
shader_setint(newds->shader, "texture_cb", 1);
|
shader_setint(newds->shader, "texture_cb", 1);
|
||||||
|
|
||||||
glGenTextures(1, &newds->texture_cr);
|
glGenTextures(1, &newds->texture_cr);
|
||||||
glBindTexture(GL_TEXTURE_2D, 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_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
shader_setint(newds->shader, "texture_cr", 2);
|
shader_setint(newds->shader, "texture_cr", 2);
|
||||||
*/
|
*/
|
||||||
return newds;
|
return newds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_advance(struct datastream *ds, double s)
|
void ds_advance(struct datastream *ds, double s) {
|
||||||
{
|
if (ds->playing) {
|
||||||
if (ds->playing) {
|
plm_decode(ds->plm, s);
|
||||||
plm_decode(ds->plm, s);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_seek(struct datastream *ds, double time)
|
void ds_seek(struct datastream *ds, double time) {
|
||||||
{
|
// clear_raw(ds->audio_device);
|
||||||
//clear_raw(ds->audio_device);
|
plm_seek(ds->plm, time, false);
|
||||||
plm_seek(ds->plm, time, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_advanceframes(struct datastream *ds, int frames)
|
void ds_advanceframes(struct datastream *ds, int frames) {
|
||||||
{
|
for (int i = 0; i < frames; i++) {
|
||||||
for (int i = 0; i < frames; i++) {
|
plm_frame_t *frame = plm_decode_video(ds->plm);
|
||||||
plm_frame_t *frame = plm_decode_video(ds->plm);
|
render_frame(ds->plm, frame, ds);
|
||||||
render_frame(ds->plm, frame, ds);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_pause(struct datastream *ds)
|
void ds_pause(struct datastream *ds) {
|
||||||
{
|
ds->playing = false;
|
||||||
ds->playing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ds_stop(struct datastream *ds)
|
void ds_stop(struct datastream *ds) {
|
||||||
{
|
if (ds->plm != NULL) {
|
||||||
if (ds->plm != NULL) {
|
plm_destroy(ds->plm);
|
||||||
plm_destroy(ds->plm);
|
ds->plm = NULL;
|
||||||
ds->plm = NULL;
|
}
|
||||||
}
|
if (ds->audio_device)
|
||||||
if (ds->audio_device)
|
close_audio_device(ds->audio_device);
|
||||||
close_audio_device(ds->audio_device);
|
ds->playing = false;
|
||||||
ds->playing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Must be a better way
|
// TODO: Must be a better way
|
||||||
int ds_videodone(struct datastream *ds)
|
int ds_videodone(struct datastream *ds) {
|
||||||
{
|
return (ds->plm == NULL) || plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
|
||||||
return (ds->plm == NULL)
|
|
||||||
|| plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double ds_remainingtime(struct datastream *ds)
|
double ds_remainingtime(struct datastream *ds) {
|
||||||
{
|
if (ds->plm != NULL)
|
||||||
if (ds->plm != NULL)
|
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
|
||||||
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
|
else
|
||||||
else
|
return 0.f;
|
||||||
return 0.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double ds_length(struct datastream *ds)
|
double ds_length(struct datastream *ds) {
|
||||||
{
|
return plm_get_duration(ds->plm);
|
||||||
return plm_get_duration(ds->plm);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
#ifndef DATASTREAM_H
|
#ifndef DATASTREAM_H
|
||||||
#define DATASTREAM_H
|
#define DATASTREAM_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <pl_mpeg.h>
|
#include <pl_mpeg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct soundstream;
|
struct soundstream;
|
||||||
|
|
||||||
struct datastream {
|
struct datastream {
|
||||||
plm_t *plm;
|
plm_t *plm;
|
||||||
struct shader *shader;
|
struct shader *shader;
|
||||||
double last_time;
|
double last_time;
|
||||||
int playing;
|
int playing;
|
||||||
int audio_device;
|
int audio_device;
|
||||||
uint32_t texture_y;
|
uint32_t texture_y;
|
||||||
uint32_t texture_cb;
|
uint32_t texture_cb;
|
||||||
uint32_t texture_cr;
|
uint32_t texture_cr;
|
||||||
struct soundstream *astream;
|
struct soundstream *astream;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture;
|
struct Texture;
|
||||||
|
@ -24,7 +24,7 @@ extern struct shader *vid_shader;
|
||||||
|
|
||||||
struct datastream *MakeDatastream();
|
struct datastream *MakeDatastream();
|
||||||
void ds_openvideo(struct datastream *ds, const char *path, const char *adriver);
|
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_advance(struct datastream *ds, double);
|
||||||
void ds_seek(struct datastream *ds, double);
|
void ds_seek(struct datastream *ds, double);
|
||||||
void ds_advanceframes(struct datastream *ds, int frames);
|
void ds_advanceframes(struct datastream *ds, int frames);
|
||||||
|
|
|
@ -11,75 +11,163 @@
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
|
|
||||||
static uint32_t circleVBO;
|
#include "font.h"
|
||||||
static uint32_t circleVAO;
|
|
||||||
static struct shader *circleShader;
|
|
||||||
|
|
||||||
static uint32_t gridVBO;
|
static sg_pipeline grid_pipe;
|
||||||
static uint32_t gridVAO;
|
static sg_bindings grid_bind;
|
||||||
static struct shader *gridShader;
|
static sg_shader grid_shader;
|
||||||
|
static int grid_c = 0;
|
||||||
|
|
||||||
static uint32_t rectVBO;
|
static sg_pipeline rect_pipe;
|
||||||
static uint32_t rectVAO;
|
static sg_bindings rect_bind;
|
||||||
static struct shader *rectShader;
|
static sg_shader rect_shader;
|
||||||
|
static int rect_c = 0;
|
||||||
|
|
||||||
typedef struct {
|
static sg_pipeline circle_pipe;
|
||||||
float proj[16];
|
static sg_bindings circle_bind;
|
||||||
float res[2];
|
static sg_shader csg;
|
||||||
} circle_ubo;
|
static int circle_count = 0;
|
||||||
|
static int circle_vert_c = 7;
|
||||||
|
|
||||||
void debug_flush()
|
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()
|
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"),
|
.vs.source = slurp_text("shaders/circlevert.glsl"),
|
||||||
.fs.source = slurp_text("shaders/circlefrag.glsl"),
|
.fs.source = slurp_text("shaders/circlefrag.glsl"),
|
||||||
.vs.uniform_blocks[0] = {
|
.vs.uniform_blocks[0] = projection_ubo,
|
||||||
.size = sizeof(circle_ubo),
|
|
||||||
.uniforms = {
|
|
||||||
[0] = { .name = "proj", .type = SG_UNIFORMTYPE_MAT4 },
|
|
||||||
[1] = { .name = "res", .type = SG_UNIFORMTYPE_FLOAT2 },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
float gridverts[] = {
|
|
||||||
-1.f, -1.f,
|
|
||||||
1.f, -1.f,
|
|
||||||
-1.f, 1.f,
|
|
||||||
1.f, 1.f
|
|
||||||
};
|
|
||||||
|
|
||||||
gridShader = MakeShader("gridvert.glsl", "gridfrag.glsl");
|
circle_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
shader_setUBO(gridShader, "Projection", 0);
|
.shader = csg,
|
||||||
glGenBuffers(1, &gridVBO);
|
.layout = {
|
||||||
glGenVertexArrays(1, &gridVAO);
|
.attrs = {
|
||||||
glBindVertexArray(gridVAO);
|
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, gridVBO);
|
[0].buffer_index = 1,
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gridverts), &gridverts, GL_STATIC_DRAW);
|
[1].format = SG_VERTEXFORMAT_FLOAT3,
|
||||||
glEnableVertexAttribArray(0);
|
[2].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
[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");
|
circle_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
shader_setUBO(rectShader, "Projection", 0);
|
.size = sizeof(float)*circle_vert_c*5000,
|
||||||
glGenBuffers(1, &rectVBO);
|
.usage = SG_USAGE_STREAM,
|
||||||
glGenVertexArrays(1, &rectVAO);
|
});
|
||||||
*/
|
|
||||||
|
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);
|
cpVect verts[2] = {s, e};
|
||||||
float verts[] = {
|
draw_poly(verts, 2, color);
|
||||||
x1, y1,
|
|
||||||
x2, y2
|
|
||||||
};
|
|
||||||
|
|
||||||
draw_poly(verts, 2, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpVect center_of_vects(cpVect *v, int n)
|
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};
|
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
|
||||||
|
|
||||||
shader_use(rectShader);
|
// shader_use(rectShader);
|
||||||
shader_setvec3(rectShader, "linecolor", col);
|
// shader_setvec3(rectShader, "linecolor", col);
|
||||||
/*
|
/*
|
||||||
if (thickness <= 1) {
|
if (thickness <= 1) {
|
||||||
// glLineStipple(1, 0x00FF);
|
// 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)
|
void draw_circle(int x, int y, float radius, int pixels, float *color, int fill)
|
||||||
{
|
{
|
||||||
/* shader_use(circleShader);
|
float cv[circle_vert_c] = {0};
|
||||||
|
cv[0] = color[0];
|
||||||
float verts[] = {
|
cv[1] = color[1];
|
||||||
x - radius, y - radius, -1, -1,
|
cv[2] = color[2];
|
||||||
x + radius, y - radius, 1, -1,
|
cv[3] = x;
|
||||||
x - radius, y + radius, -1, 1,
|
cv[4] = y;
|
||||||
x + radius, y + radius, 1, 1
|
cv[5] = radius;
|
||||||
};
|
cv[6] = fill;
|
||||||
|
sg_append_buffer(circle_bind.vertex_buffers[0], SG_RANGE_REF(cv));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, circleVBO);
|
circle_count++;
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_rect(int x, int y, int w, int h, float *color)
|
void draw_rect(int x, int y, int w, int h, float *color)
|
||||||
|
@ -234,11 +309,11 @@ void draw_rect(int x, int y, int w, int h, float *color)
|
||||||
float hw = w / 2.f;
|
float hw = w / 2.f;
|
||||||
float hh = h / 2.f;
|
float hh = h / 2.f;
|
||||||
|
|
||||||
float verts[] = {
|
cpVect verts[4] = {
|
||||||
x - hw, y - hh,
|
{ .x = x-hw, .y = y-hh },
|
||||||
x + hw, y - hh,
|
{ .x = x+hw, .y = y-hh },
|
||||||
x + hw, y + hh,
|
{ .x = x+hw, .y = y+hh },
|
||||||
x - hw, y + hh
|
{ .x = x-hw, .y = y+hh }
|
||||||
};
|
};
|
||||||
|
|
||||||
draw_poly(verts, 4, color);
|
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)
|
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};
|
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);
|
draw_cppoint(end, capsize, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_grid(int width, int span)
|
void draw_grid(int width, int span)
|
||||||
{
|
{
|
||||||
/* shader_use(gridShader);
|
|
||||||
shader_setint(gridShader, "thickness", width);
|
|
||||||
shader_setint(gridShader, "span", span);
|
|
||||||
|
|
||||||
cpVect offset = cam_pos();
|
cpVect offset = cam_pos();
|
||||||
offset = cpvmult(offset, 1/cam_zoom());
|
offset = cpvmult(offset, 1/cam_zoom());
|
||||||
offset.x -= mainwin->width/2;
|
offset.x -= mainwin->width/2;
|
||||||
offset.y -= mainwin->height/2;
|
offset.y -= mainwin->height/2;
|
||||||
|
|
||||||
shader_setvec2(gridShader, "offset", &offset);
|
sg_apply_pipeline(grid_pipe);
|
||||||
|
sg_apply_bindings(&grid_bind);
|
||||||
|
|
||||||
glBindVertexArray(gridVAO);
|
float col[3] = { 0.3, 0.5, 0.8};
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
*/
|
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)
|
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);
|
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_use(rectShader);
|
||||||
shader_setvec3(rectShader, "linecolor", color);
|
shader_setvec3(rectShader, "linecolor", color);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, rectVBO);
|
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()
|
void debugdraw_flush()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
struct color;
|
struct color;
|
||||||
|
|
||||||
void debugdraw_init();
|
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_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_points(struct cpVect *points, int n, float size, float *color);
|
||||||
void draw_arrow(struct cpVect start, struct cpVect end, struct color, int capsize);
|
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_box(struct cpVect c, struct cpVect wh, struct color color);
|
||||||
void draw_point(int x, int y, float r, float *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_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();
|
void debug_flush();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
|
|
||||||
#include "nuklear.h"
|
#include "nuke.h"
|
||||||
|
|
||||||
#define ASSET_TYPE_NULL 0
|
#define ASSET_TYPE_NULL 0
|
||||||
#define ASSET_TYPE_IMAGE 1
|
#define ASSET_TYPE_IMAGE 1
|
||||||
|
|
|
@ -16,54 +16,51 @@
|
||||||
#define PL_MPEG_IMPLEMENTATION
|
#define PL_MPEG_IMPLEMENTATION
|
||||||
#include <pl_mpeg.h>
|
#include <pl_mpeg.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef EDITOR
|
#ifdef EDITOR
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
#include "openglrender.h"
|
|
||||||
#include "window.h"
|
|
||||||
#include "camera.h"
|
|
||||||
#include "input.h"
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "2dphysics.h"
|
#include "2dphysics.h"
|
||||||
|
#include "camera.h"
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
|
#include "input.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "openglrender.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
#include "sprite.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
void error_callback(int error, const char *description)
|
void error_callback(int error, const char *description) {
|
||||||
{
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
YughError("GLFW Error: %s", description);
|
||||||
YughError("GLFW Error: %s", description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void engine_init()
|
void engine_init() {
|
||||||
{
|
glfwSetErrorCallback(error_callback);
|
||||||
glfwSetErrorCallback(error_callback);
|
/* Initialize GLFW */
|
||||||
/* Initialize GLFW */
|
if (!glfwInit()) {
|
||||||
if (!glfwInit()) {
|
YughError("Could not init GLFW. Exiting.");
|
||||||
YughError("Could not init GLFW. Exiting.");
|
exit(1);
|
||||||
exit(1);
|
} else {
|
||||||
} else {
|
YughInfo("Initted GLFW.");
|
||||||
YughInfo("Initted GLFW.");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
resources_init();
|
resources_init();
|
||||||
|
|
||||||
YughInfo("Starting physics ...");
|
YughInfo("Starting physics ...");
|
||||||
phys2d_init();
|
phys2d_init();
|
||||||
|
|
||||||
YughInfo("Starting sound ...");
|
YughInfo("Starting sound ...");
|
||||||
sound_init();
|
sound_init();
|
||||||
|
|
||||||
YughInfo("Starting scripts ...");
|
YughInfo("Starting scripts ...");
|
||||||
script_init();
|
script_init();
|
||||||
}
|
}
|
||||||
|
|
1945
source/engine/ffi.c
1945
source/engine/ffi.c
File diff suppressed because it is too large
Load diff
|
@ -1,169 +1,153 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include <shader.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <shader.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <window.h>
|
#include <window.h>
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include "openglrender.h"
|
#include "openglrender.h"
|
||||||
|
|
||||||
#include "stb_truetype.h"
|
|
||||||
#include "stb_rect_pack.h"
|
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
|
#include "stb_rect_pack.h"
|
||||||
|
#include "stb_truetype.h"
|
||||||
|
|
||||||
struct sFont *font;
|
struct sFont *font;
|
||||||
static struct shader *shader;
|
|
||||||
static sg_shader fontshader;
|
|
||||||
|
|
||||||
unsigned char *slurp_file(const char *filename) {
|
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);
|
fseek(f, 0, SEEK_END);
|
||||||
long fsize = ftell(f);
|
long fsize = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
unsigned char *slurp = malloc(fsize+1);
|
unsigned char *slurp = malloc(fsize + 1);
|
||||||
fread(slurp,fsize,1,f);
|
fread(slurp, fsize, 1, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return slurp;
|
return slurp;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *slurp_text(const char *filename) {
|
char *slurp_text(const char *filename) {
|
||||||
FILE *f = fopen(filename, "r'");
|
FILE *f = fopen(filename, "r'");
|
||||||
if (!f) return NULL;
|
if (!f) return NULL;
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
long int fsize;
|
long int fsize;
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
fsize = ftell(f);
|
fsize = ftell(f);
|
||||||
buf = malloc(fsize+1);
|
buf = malloc(fsize + 1);
|
||||||
rewind(f);
|
rewind(f);
|
||||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||||
buf[r] = '\0';
|
buf[r] = '\0';
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slurp_write(const char *txt, const char *filename)
|
int slurp_write(const char *txt, const char *filename) {
|
||||||
{
|
FILE *f = fopen(filename, "w");
|
||||||
FILE *f = fopen(filename, "w");
|
if (!f) return 1;
|
||||||
if (!f) return 1;
|
|
||||||
|
|
||||||
fputs(txt, f);
|
fputs(txt, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sg_shader fontshader;
|
||||||
static sg_bindings bind_text;
|
static sg_bindings bind_text;
|
||||||
static sg_pipeline pipe_text;
|
static sg_pipeline pipe_text;
|
||||||
|
|
||||||
void font_init(struct shader *textshader) {
|
static float text_buffer[16 * 40000];
|
||||||
shader = textshader;
|
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"),
|
.vs.source = slurp_text("shaders/textvert.glsl"),
|
||||||
.fs.source = slurp_text("shaders/textfrag.glsl"),
|
.fs.source = slurp_text("shaders/textfrag.glsl"),
|
||||||
.vs.uniform_blocks[0] = {
|
.vs.uniform_blocks[0] = {
|
||||||
.size = sizeof(float)*16,
|
.size = sizeof(float) * 16,
|
||||||
// .layout = SG_UNIFORMLAYOUT_STD140,
|
// .layout = SG_UNIFORMLAYOUT_STD140,
|
||||||
.uniforms = {
|
.uniforms = {
|
||||||
[0] = { .name = "projection", .type = SG_UNIFORMTYPE_MAT4 }
|
[0] = {.name = "projection", .type = SG_UNIFORMTYPE_MAT4}}},
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.fs.images[0] = {
|
.fs.images[0] = {.name = "text", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT}});
|
||||||
.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,
|
.shader = fontshader,
|
||||||
.layout = {
|
.layout = {
|
||||||
.attrs = {
|
.attrs = {
|
||||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
[0].buffer_index = 0,
|
[0].buffer_index = 0,
|
||||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
[1].buffer_index = 0,
|
[1].buffer_index = 0,
|
||||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||||
[2].buffer_index = 1},
|
[2].buffer_index = 1,
|
||||||
.buffers[2].step_func = SG_VERTEXSTEP_PER_INSTANCE,
|
},
|
||||||
},
|
},
|
||||||
// .primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
|
||||||
.label = "text pipeline",
|
.label = "text pipeline",
|
||||||
.index_type = SG_INDEXTYPE_UINT16
|
.index_type = SG_INDEXTYPE_UINT16});
|
||||||
});
|
|
||||||
|
|
||||||
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.size = sizeof(float)*16*500,
|
.size = sizeof(float) * 16 * 40000,
|
||||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||||
.usage = SG_USAGE_STREAM,
|
.usage = SG_USAGE_STREAM,
|
||||||
.label = "text buffer"
|
.label = "text buffer"});
|
||||||
});
|
|
||||||
|
|
||||||
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.size = sizeof(float)*3*40000,
|
.size = sizeof(float) * 3 * 4 * 40000,
|
||||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||||
.usage = SG_USAGE_STREAM,
|
.usage = SG_USAGE_STREAM,
|
||||||
.label = "text color buffer"
|
.label = "text color buffer"});
|
||||||
});
|
|
||||||
|
|
||||||
bind_text.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
bind_text.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.size = sizeof(uint16_t)*6*500,
|
.size = sizeof(uint16_t) * 6 * 40000,
|
||||||
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
||||||
.usage = SG_USAGE_STREAM,
|
.usage = SG_USAGE_STREAM,
|
||||||
.label = "text index buffer"
|
.label = "text index buffer"});
|
||||||
});
|
|
||||||
|
|
||||||
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
|
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
|
||||||
bind_text.fs_images[0] = font->texID;
|
bind_text.fs_images[0] = font->texID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void font_frame(struct window *w) {
|
struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
shader_use(shader);
|
YughInfo("Making font %s.", fontfile);
|
||||||
}
|
|
||||||
|
|
||||||
struct sFont *MakeFont(const char *fontfile, int height)
|
int packsize = 1024;
|
||||||
{
|
|
||||||
YughInfo("Making font %s.", fontfile);
|
|
||||||
|
|
||||||
int packsize = 128;
|
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
||||||
|
newfont->height = height;
|
||||||
|
|
||||||
struct sFont *newfont = calloc(1, sizeof(struct sFont));
|
char fontpath[256];
|
||||||
newfont->height = height;
|
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
||||||
|
|
||||||
char fontpath[256];
|
unsigned char *ttf_buffer = slurp_file(fontpath);
|
||||||
snprintf(fontpath, 256, "fonts/%s", fontfile);
|
unsigned char *bitmap = malloc(packsize * packsize);
|
||||||
|
|
||||||
unsigned char *ttf_buffer = slurp_file(fontpath);
|
stbtt_packedchar glyphs[95];
|
||||||
unsigned char *bitmap = malloc(packsize*packsize);
|
|
||||||
|
|
||||||
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);
|
stbi_write_png("packedfont.png", packsize, packsize, 1, bitmap, sizeof(char) * packsize);
|
||||||
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);
|
stbtt_fontinfo fontinfo;
|
||||||
|
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
|
||||||
|
YughError("Failed to make font %s", fontfile);
|
||||||
|
}
|
||||||
|
|
||||||
stbtt_fontinfo fontinfo;
|
newfont->texID = sg_make_image(&(sg_image_desc){
|
||||||
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){
|
|
||||||
.type = SG_IMAGETYPE_2D,
|
.type = SG_IMAGETYPE_2D,
|
||||||
.width = packsize,
|
.width = packsize,
|
||||||
.height = packsize,
|
.height = packsize,
|
||||||
|
@ -172,215 +156,201 @@ struct sFont *MakeFont(const char *fontfile, int height)
|
||||||
.min_filter = SG_FILTER_NEAREST,
|
.min_filter = SG_FILTER_NEAREST,
|
||||||
.mag_filter = SG_FILTER_NEAREST,
|
.mag_filter = SG_FILTER_NEAREST,
|
||||||
.data.subimage[0][0] = {
|
.data.subimage[0][0] = {
|
||||||
.ptr = bitmap,
|
.ptr = bitmap,
|
||||||
.size = packsize*packsize
|
.size = packsize * packsize}});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
free(ttf_buffer);
|
free(ttf_buffer);
|
||||||
free(bitmap);
|
free(bitmap);
|
||||||
|
|
||||||
for (unsigned char c = 32; c < 127; c++) {
|
for (unsigned char c = 32; c < 127; c++) {
|
||||||
stbtt_packedchar glyph = glyphs[c-32];
|
stbtt_packedchar glyph = glyphs[c - 32];
|
||||||
|
|
||||||
struct glrect r;
|
struct glrect r;
|
||||||
r.s0 = glyph.x0 / (float) packsize;
|
r.s0 = glyph.x0 / (float)packsize;
|
||||||
r.s1 = glyph.x1 / (float) packsize;
|
r.s1 = glyph.x1 / (float)packsize;
|
||||||
r.t0 = glyph.y0 / (float) packsize;
|
r.t0 = glyph.y0 / (float)packsize;
|
||||||
r.t1 = glyph.y1 / (float) packsize;
|
r.t1 = glyph.y1 / (float)packsize;
|
||||||
|
|
||||||
newfont->Characters[c].Advance = glyph.xadvance;
|
newfont->Characters[c].Advance = glyph.xadvance;
|
||||||
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
||||||
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0;
|
||||||
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||||
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||||
newfont->Characters[c].rect = r;
|
newfont->Characters[c].rect = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return newfont;
|
return newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int curchar = 0;
|
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;
|
int x, y, w, h;
|
||||||
|
|
||||||
x = cursor[0];
|
x = cursor[0];
|
||||||
y = cursor[1];
|
y = cursor[1];
|
||||||
w = 8*scale;
|
w = 8 * scale;
|
||||||
h = 14;
|
h = 14;
|
||||||
x += w/2.f;
|
x += w / 2.f;
|
||||||
y += h/2.f;
|
y += h / 2.f;
|
||||||
|
|
||||||
draw_rect(x,y,w,h,color);
|
draw_rect(x, y, w, h, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_flush()
|
void text_flush() {
|
||||||
{
|
if (curchar == 0) return;
|
||||||
sg_apply_pipeline(pipe_text);
|
sg_apply_pipeline(pipe_text);
|
||||||
sg_apply_bindings(&bind_text);
|
sg_apply_bindings(&bind_text);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
|
||||||
|
|
||||||
sg_draw(0,6*curchar,1);
|
sg_range verts;
|
||||||
|
verts.ptr = text_buffer;
|
||||||
|
verts.size = sizeof(float) * 16 * curchar;
|
||||||
|
sg_update_buffer(bind_text.vertex_buffers[0], &verts);
|
||||||
|
|
||||||
|
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;
|
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 w = c.Size[0] * scale;
|
||||||
float h = c.Size[1] * scale;
|
float h = c.Size[1] * scale;
|
||||||
|
|
||||||
float xpos = cursor[0] + (c.Bearing[0]+offset[0]) * scale;
|
float xpos = cursor[0] + (c.Bearing[0] + offset[0]) * scale;
|
||||||
float ypos = cursor[1] - (c.Bearing[1]+offset[1]) * scale;
|
float ypos = cursor[1] - (c.Bearing[1] + offset[1]) * scale;
|
||||||
|
|
||||||
float v[16] = {
|
float v[16] = {
|
||||||
xpos, ypos, c.rect.s0, c.rect.t1,
|
xpos, ypos, c.rect.s0, c.rect.t1,
|
||||||
xpos+w, ypos, c.rect.s1, c.rect.t1,
|
xpos + w, ypos, c.rect.s1, c.rect.t1,
|
||||||
xpos, ypos + h, c.rect.s0, c.rect.t0,
|
xpos, ypos + h, c.rect.s0, c.rect.t0,
|
||||||
xpos + w, ypos + h, c.rect.s1, c.rect.t0
|
xpos + w, ypos + h, c.rect.s1, c.rect.t0};
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(verts, v, sizeof(float)*16);
|
memcpy(verts, v, sizeof(float) * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drawcaret = 0;
|
static int drawcaret = 0;
|
||||||
|
|
||||||
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]) {
|
||||||
{
|
float shadowcolor[3] = {0.f, 0.f, 0.f};
|
||||||
float shadowcolor[3] = {0.f, 0.f, 0.f};
|
float shadowcursor[2];
|
||||||
float shadowcursor[2];
|
|
||||||
|
|
||||||
float verts[16];
|
float verts[16];
|
||||||
float offset[2] = {-1, 1};
|
float offset[2] = {-1, 1};
|
||||||
|
|
||||||
fill_charverts(verts, cursor, scale, c, offset);
|
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));
|
|
||||||
|
|
||||||
|
/* 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;
|
return;
|
||||||
|
|
||||||
// fill_charverts(verts, cursor, scale, c, offset);
|
uint16_t pts[6] = {
|
||||||
|
0, 1, 2,
|
||||||
|
2, 1, 3};
|
||||||
|
|
||||||
/*
|
for (int i = 0; i < 6; i++)
|
||||||
if (drawcaret == curchar) {
|
pts[i] += curchar * 4;
|
||||||
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;
|
memcpy(text_buffer + (16 * curchar), verts, sizeof(verts));
|
||||||
offset[1] = -1;
|
for (int i = 0; i < 4; i++)
|
||||||
fill_charverts(verts, cursor, scale, c, offset);
|
memcpy(color_buffer + (12 * curchar) + (3 * i), color, sizeof(color));
|
||||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
memcpy(text_idx_buffer + (6 * curchar), pts, sizeof(pts));
|
||||||
|
curchar++;
|
||||||
|
return;
|
||||||
|
|
||||||
offset[1] = 1;
|
/*
|
||||||
fill_charverts(verts, cursor, scale, c, offset);
|
if (drawcaret == curchar) {
|
||||||
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
draw_char_box(c, cursor, scale, color);
|
||||||
|
shader_use(shader);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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') {
|
|
||||||
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
|
/*
|
||||||
|
sg_append_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
|
||||||
|
|
||||||
/* if (caret > curchar) {
|
offset[0] = 1;
|
||||||
draw_char_box(font->Characters[69], cursor, scale, color);
|
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];
|
return cursor[1] - pos[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,36 +2,34 @@
|
||||||
#define FONT_H
|
#define FONT_H
|
||||||
|
|
||||||
#include "mathc.h"
|
#include "mathc.h"
|
||||||
#include "texture.h"
|
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
struct shader;
|
struct shader;
|
||||||
struct window;
|
struct window;
|
||||||
|
|
||||||
/// Holds all state information relevant to a character as loaded using FreeType
|
/// Holds all state information relevant to a character as loaded using FreeType
|
||||||
struct Character {
|
struct Character {
|
||||||
mfloat_t Size[2]; // Size of glyph
|
mfloat_t Size[2]; // Size of glyph
|
||||||
mfloat_t Bearing[2]; // Offset from baseline to left/top of glyph
|
mfloat_t Bearing[2]; // Offset from baseline to left/top of glyph
|
||||||
unsigned int Advance; // Horizontal offset to advance to next glyph
|
unsigned int Advance; // Horizontal offset to advance to next glyph
|
||||||
struct glrect rect;
|
struct glrect rect;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sFont {
|
struct sFont {
|
||||||
uint32_t fontTexture;
|
uint32_t fontTexture;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
struct Character Characters[127];
|
struct Character Characters[127];
|
||||||
sg_image texID;
|
sg_image texID;
|
||||||
};
|
};
|
||||||
|
|
||||||
void font_init(struct shader *s);
|
void font_init(struct shader *s);
|
||||||
void font_frame(struct window *w);
|
|
||||||
struct sFont *MakeFont(const char *fontfile, int height);
|
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);
|
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();
|
void text_flush();
|
||||||
|
|
||||||
unsigned char *slurp_file(const char *filename);
|
unsigned char *slurp_file(const char *filename);
|
||||||
|
|
|
@ -1,45 +1,42 @@
|
||||||
#include "gameobject.h"
|
#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 "shader.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "2dphysics.h"
|
|
||||||
#include "script.h"
|
|
||||||
#include "input.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <chipmunk/chipmunk.h>
|
#include <chipmunk/chipmunk.h>
|
||||||
#include "resources.h"
|
#include <string.h>
|
||||||
#include "nuke.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "debugdraw.h"
|
|
||||||
|
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
struct gameobject *gameobjects = NULL;
|
struct gameobject *gameobjects = NULL;
|
||||||
static int first = -1;
|
static int first = -1;
|
||||||
|
|
||||||
const int nameBuf[MAXNAME] = { 0 };
|
const int nameBuf[MAXNAME] = {0};
|
||||||
const int prefabNameBuf[MAXNAME] = { 0 };
|
const int prefabNameBuf[MAXNAME] = {0};
|
||||||
|
|
||||||
struct gameobject *get_gameobject_from_id(int id)
|
struct gameobject *get_gameobject_from_id(int id) {
|
||||||
{ if (id < 0) return NULL;
|
if (id < 0) return NULL;
|
||||||
|
|
||||||
return &gameobjects[id];
|
return &gameobjects[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gameobject *id2go(int id)
|
struct gameobject *id2go(int id) {
|
||||||
{
|
if (id < 0) return NULL;
|
||||||
if (id < 0) return NULL;
|
|
||||||
|
|
||||||
return &gameobjects[id];
|
return &gameobjects[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
int body2id(cpBody *body)
|
int body2id(cpBody *body) {
|
||||||
{
|
|
||||||
return (int)cpBodyGetUserData(body);
|
return (int)cpBodyGetUserData(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpBody *id2body(int id)
|
cpBody *id2body(int id) {
|
||||||
{
|
|
||||||
struct gameobject *go = id2go(id);
|
struct gameobject *go = id2go(id);
|
||||||
|
|
||||||
if (go)
|
if (go)
|
||||||
|
@ -48,14 +45,12 @@ cpBody *id2body(int id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int shape2gameobject(cpShape *shape)
|
int shape2gameobject(cpShape *shape) {
|
||||||
{
|
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
return s->go;
|
return s->go;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos2gameobject(cpVect pos)
|
int pos2gameobject(cpVect pos) {
|
||||||
{
|
|
||||||
cpShape *hit = phys2d_query_pos(pos);
|
cpShape *hit = phys2d_query_pos(pos);
|
||||||
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
|
@ -73,269 +68,255 @@ int pos2gameobject(cpVect pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
int id_from_gameobject(struct gameobject *go) {
|
int id_from_gameobject(struct gameobject *go) {
|
||||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||||
if (&gameobjects[i] == go) return 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;
|
id2go(id)->sensor = sensor;
|
||||||
gameobject_apply(id2go(id));
|
gameobject_apply(id2go(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
int go2id(struct gameobject *go)
|
int go2id(struct gameobject *go) {
|
||||||
{
|
|
||||||
return id_from_gameobject(go);
|
return id_from_gameobject(go);
|
||||||
}
|
}
|
||||||
|
|
||||||
void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go)
|
void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go) {
|
||||||
{
|
cpShapeSetFriction(shape, go->f);
|
||||||
cpShapeSetFriction(shape, go->f);
|
cpShapeSetElasticity(shape, go->e);
|
||||||
cpShapeSetElasticity(shape, go->e);
|
cpShapeSetCollisionType(shape, go2id(go));
|
||||||
cpShapeSetCollisionType(shape, go2id(go));
|
|
||||||
|
|
||||||
|
/* cpShapeFilter filter;
|
||||||
/* cpShapeFilter filter;
|
filter.group = go2id(go);
|
||||||
filter.group = go2id(go);
|
filter.categories = 1<<go->layer;
|
||||||
filter.categories = 1<<go->layer;
|
filter.mask = category_masks[go->layer];
|
||||||
filter.mask = category_masks[go->layer];
|
cpShapeSetFilter(shape, filter);
|
||||||
cpShapeSetFilter(shape, filter);
|
*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void go_shape_moi(cpBody *body, cpShape *shape, struct gameobject *go)
|
void go_shape_moi(cpBody *body, cpShape *shape, struct gameobject *go) {
|
||||||
{
|
float moment = cpBodyGetMoment(go->body);
|
||||||
float moment = cpBodyGetMoment(go->body);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
if (!s) {
|
||||||
if (!s) {
|
cpBodySetMoment(go->body, moment + 1);
|
||||||
cpBodySetMoment(go->body, moment+1);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
moment += s->moi(s->data, go->mass);
|
moment += s->moi(s->data, go->mass);
|
||||||
cpBodySetMoment(go->body, moment);
|
cpBodySetMoment(go->body, moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_apply(struct gameobject *go)
|
void gameobject_apply(struct gameobject *go) {
|
||||||
{
|
cpBodySetType(go->body, go->bodytype);
|
||||||
cpBodySetType(go->body, go->bodytype);
|
cpBodyEachShape(go->body, go_shape_apply, go);
|
||||||
cpBodyEachShape(go->body, go_shape_apply, go);
|
|
||||||
|
|
||||||
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||||
cpBodySetMass(go->body, go->mass);
|
cpBodySetMass(go->body, go->mass);
|
||||||
cpBodySetMoment(go->body, 0.f);
|
cpBodySetMoment(go->body, 0.f);
|
||||||
cpBodyEachShape(go->body, go_shape_moi, go);
|
cpBodyEachShape(go->body, go_shape_moi, go);
|
||||||
|
|
||||||
if (cpBodyGetMoment(go->body) <= 0.f)
|
if (cpBodyGetMoment(go->body) <= 0.f)
|
||||||
cpBodySetMoment(go->body, 1.f);
|
cpBodySetMoment(go->body, 1.f);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gameobject_setpickcolor(struct gameobject *go)
|
static void gameobject_setpickcolor(struct gameobject *go) {
|
||||||
{
|
/*
|
||||||
/*
|
float r = ((go->editor.id & 0x000000FF) >> 0) / 255.f;
|
||||||
float r = ((go->editor.id & 0x000000FF) >> 0) / 255.f;
|
float g = ((go->editor.id & 0x0000FF00) >> 8) / 255.f;
|
||||||
float g = ((go->editor.id & 0x0000FF00) >> 8) / 255.f;
|
float b = ((go->editor.id & 0x00FF0000) >> 16) / 255.f;
|
||||||
float b = ((go->editor.id & 0x00FF0000) >> 16) / 255.f;
|
|
||||||
|
|
||||||
go->editor.color[0] = r;
|
go->editor.color[0] = r;
|
||||||
go->editor.color[1] = g;
|
go->editor.color[1] = g;
|
||||||
go->editor.color[2] = b;
|
go->editor.color[2] = b;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int MakeGameobject()
|
int MakeGameobject() {
|
||||||
{
|
struct gameobject go = {
|
||||||
struct gameobject go = {
|
.scale = 1.f,
|
||||||
.scale = 1.f,
|
.bodytype = CP_BODY_TYPE_STATIC,
|
||||||
.bodytype = CP_BODY_TYPE_STATIC,
|
.mass = 1.f,
|
||||||
.mass = 1.f,
|
.next = -1,
|
||||||
.next = -1,
|
.sensor = 0,
|
||||||
.sensor = 0,
|
.shape_cbs = NULL,
|
||||||
.shape_cbs = NULL,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
go.cbs.begin.obj = JS_NULL;
|
go.cbs.begin.obj = JS_NULL;
|
||||||
go.cbs.separate.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) {
|
if (first < 0) {
|
||||||
arrput(gameobjects, go);
|
arrput(gameobjects, go);
|
||||||
retid = arrlast(gameobjects).id = arrlen(gameobjects)-1;
|
retid = arrlast(gameobjects).id = arrlen(gameobjects) - 1;
|
||||||
} else {
|
} else {
|
||||||
retid = first;
|
retid = first;
|
||||||
first = id2go(first)->next;
|
first = id2go(first)->next;
|
||||||
*id2go(retid) = go;
|
*id2go(retid) = go;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpBodySetUserData(go.body, (void*)retid);
|
cpBodySetUserData(go.body, (void *)retid);
|
||||||
phys2d_setup_handlers(retid);
|
phys2d_setup_handlers(retid);
|
||||||
return retid;
|
return retid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
|
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
if (s->data) {
|
if (s->data) {
|
||||||
free(s->data);
|
free(s->data);
|
||||||
s->data = NULL;
|
s->data = NULL;
|
||||||
}
|
}
|
||||||
cpSpaceRemoveShape(space, shape);
|
cpSpaceRemoveShape(space, shape);
|
||||||
cpShapeFree(shape);
|
cpShapeFree(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
int *go_toclean = NULL;
|
int *go_toclean = NULL;
|
||||||
|
|
||||||
/* Free this gameobject */
|
/* Free this gameobject */
|
||||||
void gameobject_clean(int id) {
|
void gameobject_clean(int id) {
|
||||||
struct gameobject *go = id2go(id);
|
struct gameobject *go = id2go(id);
|
||||||
arrfree(go->shape_cbs);
|
arrfree(go->shape_cbs);
|
||||||
cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
||||||
cpSpaceRemoveBody(space, go->body);
|
cpSpaceRemoveBody(space, go->body);
|
||||||
cpBodyFree(go->body);
|
cpBodyFree(go->body);
|
||||||
go->body = NULL;
|
go->body = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Really more of a "mark for deletion" ... */
|
/* Really more of a "mark for deletion" ... */
|
||||||
void gameobject_delete(int id)
|
void gameobject_delete(int id) {
|
||||||
{
|
id2go(id)->next = first;
|
||||||
id2go(id)->next = first;
|
first = id;
|
||||||
first = id;
|
|
||||||
|
|
||||||
if (cpSpaceIsLocked(space))
|
if (cpSpaceIsLocked(space))
|
||||||
arrpush(go_toclean, id);
|
arrpush(go_toclean, id);
|
||||||
else
|
else
|
||||||
gameobject_clean(id);
|
gameobject_clean(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobjects_cleanup() {
|
void gameobjects_cleanup() {
|
||||||
for (int i = 0; i < arrlen(go_toclean); i++)
|
for (int i = 0; i < arrlen(go_toclean); i++)
|
||||||
gameobject_clean(go_toclean[i]);
|
gameobject_clean(go_toclean[i]);
|
||||||
|
|
||||||
arrsetlen(go_toclean, 0);
|
arrsetlen(go_toclean, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int clean = first;
|
int clean = first;
|
||||||
|
|
||||||
while (clean >= 0 && id2go(clean)->body) {
|
while (clean >= 0 && id2go(clean)->body) {
|
||||||
gameobject_clean(clean);
|
gameobject_clean(clean);
|
||||||
clean = id2go(clean)->next;
|
clean = id2go(clean)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_move(struct gameobject *go, cpVect vec)
|
void gameobject_move(struct gameobject *go, cpVect vec) {
|
||||||
{
|
cpVect p = cpBodyGetPosition(go->body);
|
||||||
cpVect p = cpBodyGetPosition(go->body);
|
p.x += vec.x;
|
||||||
p.x += vec.x;
|
p.y += vec.y;
|
||||||
p.y += vec.y;
|
cpBodySetPosition(go->body, p);
|
||||||
cpBodySetPosition(go->body, p);
|
|
||||||
|
|
||||||
phys2d_reindex_body(go->body);
|
phys2d_reindex_body(go->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_rotate(struct gameobject *go, float as)
|
void gameobject_rotate(struct gameobject *go, float as) {
|
||||||
{
|
cpFloat a = cpBodyGetAngle(go->body);
|
||||||
cpFloat a = cpBodyGetAngle(go->body);
|
a += as * deltaT;
|
||||||
a += as * deltaT;
|
cpBodySetAngle(go->body, a);
|
||||||
cpBodySetAngle(go->body, a);
|
|
||||||
|
|
||||||
phys2d_reindex_body(go->body);
|
phys2d_reindex_body(go->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_setangle(struct gameobject *go, float angle) {
|
void gameobject_setangle(struct gameobject *go, float angle) {
|
||||||
cpBodySetAngle(go->body, angle);
|
cpBodySetAngle(go->body, angle);
|
||||||
phys2d_reindex_body(go->body);
|
phys2d_reindex_body(go->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_setpos(struct gameobject *go, cpVect vec) {
|
void gameobject_setpos(struct gameobject *go, cpVect vec) {
|
||||||
if (!go || !go->body) return;
|
if (!go || !go->body) return;
|
||||||
cpBodySetPosition(go->body, vec);
|
cpBodySetPosition(go->body, vec);
|
||||||
|
|
||||||
phys2d_reindex_body(go->body);
|
phys2d_reindex_body(go->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void object_gui(struct gameobject *go)
|
void object_gui(struct gameobject *go) {
|
||||||
{
|
/*
|
||||||
/*
|
float temp_pos[2];
|
||||||
float temp_pos[2];
|
temp_pos[0] = cpBodyGetPosition(go->body).x;
|
||||||
temp_pos[0] = cpBodyGetPosition(go->body).x;
|
temp_pos[1] = cpBodyGetPosition(go->body).y;
|
||||||
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] };
|
cpVect tvect = { temp_pos[0], temp_pos[1] };
|
||||||
cpBodySetPosition(go->body, tvect);
|
cpBodySetPosition(go->body, tvect);
|
||||||
|
|
||||||
float mtry = cpBodyGetAngle(go->body);
|
float mtry = cpBodyGetAngle(go->body);
|
||||||
float modtry = fmodf(mtry * RAD2DEGS, 360.f);
|
float modtry = fmodf(mtry * RAD2DEGS, 360.f);
|
||||||
if (modtry < 0.f)
|
if (modtry < 0.f)
|
||||||
modtry += 360.f;
|
modtry += 360.f;
|
||||||
|
|
||||||
float modtry2 = modtry;
|
float modtry2 = modtry;
|
||||||
nuke_property_float("Angle", -1000.f, &modtry, 1000.f, 0.5f, 0.5f);
|
nuke_property_float("Angle", -1000.f, &modtry, 1000.f, 0.5f, 0.5f);
|
||||||
modtry -= modtry2;
|
modtry -= modtry2;
|
||||||
cpBodySetAngle(go->body, mtry + (modtry * DEG2RADS));
|
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_nel(3);
|
||||||
nuke_radio_btn("Static", &go->bodytype, CP_BODY_TYPE_STATIC);
|
nuke_radio_btn("Static", &go->bodytype, CP_BODY_TYPE_STATIC);
|
||||||
nuke_radio_btn("Dynamic", &go->bodytype, CP_BODY_TYPE_DYNAMIC);
|
nuke_radio_btn("Dynamic", &go->bodytype, CP_BODY_TYPE_DYNAMIC);
|
||||||
nuke_radio_btn("Kinematic", &go->bodytype, CP_BODY_TYPE_KINEMATIC);
|
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) {
|
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
|
||||||
nuke_property_float("Mass", 0.01f, &go->mass, 1000.f, 0.01f, 0.01f);
|
nuke_property_float("Mass", 0.01f, &go->mass, 1000.f, 0.01f, 0.01f);
|
||||||
cpBodySetMass(go->body, go->mass);
|
cpBodySetMass(go->body, go->mass);
|
||||||
}
|
}
|
||||||
|
|
||||||
nuke_property_float("Friction", 0.f, &go->f, 10.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);
|
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++) {
|
for (int i = 0; i < arrlen(go->components); i++) {
|
||||||
struct component *c = &go->components[i];
|
struct component *c = &go->components[i];
|
||||||
|
|
||||||
comp_draw_debug(c);
|
comp_draw_debug(c);
|
||||||
|
|
||||||
nuke_nel(5);
|
nuke_nel(5);
|
||||||
if (nuke_btn("Del")) n = i;
|
if (nuke_btn("Del")) n = i;
|
||||||
|
|
||||||
if (nuke_push_tree_id(c->ref->name, i)) {
|
if (nuke_push_tree_id(c->ref->name, i)) {
|
||||||
comp_draw_gui(c);
|
comp_draw_gui(c);
|
||||||
nuke_tree_pop();
|
nuke_tree_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n >= 0)
|
if (n >= 0)
|
||||||
gameobject_delcomponent(go, n);
|
gameobject_delcomponent(go, n);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
|
void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
s->debugdraw(s->data);
|
s->debugdraw(s->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_draw_debug(int go)
|
void gameobject_draw_debug(int go) {
|
||||||
{
|
|
||||||
struct gameobject *g = id2go(go);
|
struct gameobject *g = id2go(go);
|
||||||
if (!g || !g->body) return;
|
if (!g || !g->body) return;
|
||||||
|
|
||||||
|
@ -346,37 +327,40 @@ void gameobject_draw_debug(int go)
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_draw_debugs() {
|
void gameobject_draw_debugs() {
|
||||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||||
gameobject_draw_debug(i);
|
gameobject_draw_debug(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
static struct {struct gameobject go; cpVect pos; float angle; } *saveobjects = NULL;
|
struct gameobject go;
|
||||||
|
cpVect pos;
|
||||||
|
float angle;
|
||||||
|
} *saveobjects = NULL;
|
||||||
|
|
||||||
void gameobject_saveall() {
|
void gameobject_saveall() {
|
||||||
arrfree(saveobjects);
|
arrfree(saveobjects);
|
||||||
arrsetlen(saveobjects, arrlen(gameobjects));
|
arrsetlen(saveobjects, arrlen(gameobjects));
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(gameobjects); i++) {
|
for (int i = 0; i < arrlen(gameobjects); i++) {
|
||||||
saveobjects[i].go = gameobjects[i];
|
saveobjects[i].go = gameobjects[i];
|
||||||
saveobjects[i].pos = cpBodyGetPosition(gameobjects[i].body);
|
saveobjects[i].pos = cpBodyGetPosition(gameobjects[i].body);
|
||||||
saveobjects[i].angle = cpBodyGetAngle(gameobjects[i].body);
|
saveobjects[i].angle = cpBodyGetAngle(gameobjects[i].body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_loadall() {
|
void gameobject_loadall() {
|
||||||
YughInfo("N gameobjects: %d, N saved: %d", arrlen(gameobjects), arrlen(saveobjects));
|
YughInfo("N gameobjects: %d, N saved: %d", arrlen(gameobjects), arrlen(saveobjects));
|
||||||
for (int i = 0; i < arrlen(saveobjects); i++) {
|
for (int i = 0; i < arrlen(saveobjects); i++) {
|
||||||
gameobjects[i] = saveobjects[i].go;
|
gameobjects[i] = saveobjects[i].go;
|
||||||
cpBodySetPosition(gameobjects[i].body, saveobjects[i].pos);
|
cpBodySetPosition(gameobjects[i].body, saveobjects[i].pos);
|
||||||
cpBodySetAngle(gameobjects[i].body, saveobjects[i].angle);
|
cpBodySetAngle(gameobjects[i].body, saveobjects[i].angle);
|
||||||
cpBodySetVelocity(gameobjects[i].body, cpvzero);
|
cpBodySetVelocity(gameobjects[i].body, cpvzero);
|
||||||
cpBodySetAngularVelocity(gameobjects[i].body, 0.f);
|
cpBodySetAngularVelocity(gameobjects[i].body, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfree(saveobjects);
|
arrfree(saveobjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gameobjects_saved() {
|
int gameobjects_saved() {
|
||||||
return arrlen(saveobjects);
|
return arrlen(saveobjects);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
#ifndef GAMEOBJECT_H
|
#ifndef GAMEOBJECT_H
|
||||||
#define 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 "2dphysics.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "mathc.h"
|
||||||
|
#include <chipmunk/chipmunk.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
struct shader;
|
struct shader;
|
||||||
struct sprite;
|
struct sprite;
|
||||||
struct component;
|
struct component;
|
||||||
|
|
||||||
struct gameobject {
|
struct gameobject {
|
||||||
cpBodyType bodytype;
|
cpBodyType bodytype;
|
||||||
int next;
|
int next;
|
||||||
float scale;
|
float scale;
|
||||||
float mass;
|
float mass;
|
||||||
float f; /* friction */
|
float f; /* friction */
|
||||||
float e; /* elasticity */
|
float e; /* elasticity */
|
||||||
int flipx; /* 1 or -1 */
|
int flipx; /* 1 or -1 */
|
||||||
int flipy;
|
int flipy;
|
||||||
int sensor;
|
int sensor;
|
||||||
unsigned int layer;
|
unsigned int layer;
|
||||||
cpShapeFilter filter;
|
cpShapeFilter filter;
|
||||||
cpBody *body; /* NULL if this object is dead */
|
cpBody *body; /* NULL if this object is dead */
|
||||||
int id;
|
int id;
|
||||||
struct phys_cbs cbs;
|
struct phys_cbs cbs;
|
||||||
struct shape_cb *shape_cbs;
|
struct shape_cb *shape_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct gameobject *gameobjects;
|
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 "input.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "ffi.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "log.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "log.h"
|
|
||||||
#include "ffi.h"
|
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "font.h"
|
#include <stdio.h>
|
||||||
|
|
||||||
#inlcude "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
int32_t mouseWheelX = 0;
|
int32_t mouseWheelX = 0;
|
||||||
int32_t mouseWheelY = 0;
|
int32_t mouseWheelY = 0;
|
||||||
|
@ -24,8 +24,8 @@ JSValue jsany;
|
||||||
JSValue jsmouse;
|
JSValue jsmouse;
|
||||||
JSValue jspos;
|
JSValue jspos;
|
||||||
|
|
||||||
cpVect mouse_pos = {0,0};
|
cpVect mouse_pos = {0, 0};
|
||||||
cpVect mouse_delta = {0,0};
|
cpVect mouse_delta = {0, 0};
|
||||||
|
|
||||||
struct joystick {
|
struct joystick {
|
||||||
int id;
|
int id;
|
||||||
|
@ -45,8 +45,7 @@ static struct {
|
||||||
JSValue value;
|
JSValue value;
|
||||||
} *jshash = NULL;
|
} *jshash = NULL;
|
||||||
|
|
||||||
JSValue input2js(const char *input)
|
JSValue input2js(const char *input) {
|
||||||
{
|
|
||||||
int idx = shgeti(jshash, input);
|
int idx = shgeti(jshash, input);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
return jshash[idx].value;
|
return jshash[idx].value;
|
||||||
|
@ -60,36 +59,48 @@ JSValue input2js(const char *input)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *gamepad2str(int btn)
|
const char *gamepad2str(int btn) {
|
||||||
{
|
switch (btn) {
|
||||||
switch(btn) {
|
case GLFW_GAMEPAD_BUTTON_CROSS:
|
||||||
case GLFW_GAMEPAD_BUTTON_CROSS: return "cross";
|
return "cross";
|
||||||
case GLFW_GAMEPAD_BUTTON_CIRCLE: return "circle";
|
case GLFW_GAMEPAD_BUTTON_CIRCLE:
|
||||||
case GLFW_GAMEPAD_BUTTON_SQUARE: return "square";
|
return "circle";
|
||||||
case GLFW_GAMEPAD_BUTTON_TRIANGLE: return "triangle";
|
case GLFW_GAMEPAD_BUTTON_SQUARE:
|
||||||
case GLFW_GAMEPAD_BUTTON_START: return "start";
|
return "square";
|
||||||
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return "lbump";
|
case GLFW_GAMEPAD_BUTTON_TRIANGLE:
|
||||||
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return "rbump";
|
return "triangle";
|
||||||
case GLFW_GAMEPAD_BUTTON_GUIDE: return "guide";
|
case GLFW_GAMEPAD_BUTTON_START:
|
||||||
case GLFW_GAMEPAD_BUTTON_BACK: return "back";
|
return "start";
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_UP: return "dup";
|
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return "ddown";
|
return "lbump";
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return "dleft";
|
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
|
||||||
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return "dright";
|
return "rbump";
|
||||||
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return "lthumb";
|
case GLFW_GAMEPAD_BUTTON_GUIDE:
|
||||||
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return "rthumb";
|
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";
|
return "NOBTN";
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_pawn(struct callee c)
|
void register_pawn(struct callee c) {
|
||||||
{
|
|
||||||
pawn_callee = c;
|
pawn_callee = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_gamepad(struct callee c)
|
void register_gamepad(struct callee c) {
|
||||||
{
|
|
||||||
gamepad_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)
|
static void cursor_pos_cb(GLFWwindow *w, double xpos, double ypos) {
|
||||||
{
|
mouse_delta.x = xpos - mouse_pos.x;
|
||||||
mouse_delta.x = xpos - mouse_pos.x;
|
mouse_delta.y = ypos - mouse_pos.y;
|
||||||
mouse_delta.y = ypos - mouse_pos.y;
|
|
||||||
|
|
||||||
mouse_pos.x = xpos;
|
mouse_pos.x = xpos;
|
||||||
mouse_pos.y = ypos;
|
mouse_pos.y = ypos;
|
||||||
|
|
||||||
JSValue argv[4];
|
JSValue argv[4];
|
||||||
argv[0] = jsinput;
|
argv[0] = jsinput;
|
||||||
argv[1] = jsmouse;
|
argv[1] = jsmouse;
|
||||||
argv[2] = jspos;
|
argv[2] = jspos;
|
||||||
argv[3] = vec2js(mouse_pos);
|
argv[3] = vec2js(mouse_pos);
|
||||||
script_callee(pawn_callee, 4, argv);
|
script_callee(pawn_callee, 4, argv);
|
||||||
JS_FreeValue(js, argv[3]);
|
JS_FreeValue(js, argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pawn_call_keydown(int key)
|
static void pawn_call_keydown(int key) {
|
||||||
{
|
|
||||||
JSValue argv[4];
|
JSValue argv[4];
|
||||||
argv[0] = jsinput;
|
argv[0] = jsinput;
|
||||||
argv[1] = jsnum;
|
argv[1] = jsnum;
|
||||||
|
@ -137,45 +146,41 @@ static void pawn_call_keydown(int key)
|
||||||
JS_FreeValue(js, argv[3]);
|
JS_FreeValue(js, argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset)
|
static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset) {
|
||||||
{
|
mouseWheelY = yoffset;
|
||||||
mouseWheelY = yoffset;
|
mouseWheelX = xoffset;
|
||||||
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];
|
JSValue argv[3];
|
||||||
argv[0] = jsinput;
|
argv[0] = jsinput;
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case GLFW_PRESS:
|
case GLFW_PRESS:
|
||||||
argv[2] = jsinputstate[2];
|
argv[2] = jsinputstate[2];
|
||||||
add_downkey(button);
|
add_downkey(button);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_RELEASE:
|
case GLFW_RELEASE:
|
||||||
rm_downkey(button);
|
rm_downkey(button);
|
||||||
argv[2] = jsinputstate[0];
|
argv[2] = jsinputstate[0];
|
||||||
argv[1] = jsany;
|
argv[1] = jsany;
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_REPEAT:
|
case GLFW_REPEAT:
|
||||||
argv[2] = jsinputstate[1];
|
argv[2] = jsinputstate[1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
argv[1] = input2js(keyname_extd(button,button));
|
argv[1] = input2js(keyname_extd(button, button));
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_mouse_mode(int mousemode)
|
void set_mouse_mode(int mousemode) {
|
||||||
{
|
|
||||||
glfwSetInputMode(mainwin->window, GLFW_CURSOR, 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 char out[2] = {0};
|
||||||
static JSValue argv[2];
|
static JSValue argv[2];
|
||||||
|
|
||||||
|
@ -190,15 +195,13 @@ void char_cb(GLFWwindow *w, unsigned int codepoint)
|
||||||
|
|
||||||
static GLFWcharfun nukechar;
|
static GLFWcharfun nukechar;
|
||||||
|
|
||||||
void joystick_add(int id)
|
void joystick_add(int id) {
|
||||||
{
|
|
||||||
struct joystick joy = {0};
|
struct joystick joy = {0};
|
||||||
joy.id = id;
|
joy.id = id;
|
||||||
arrpush(joysticks, joy);
|
arrpush(joysticks, joy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void joystick_cb(int jid, int event)
|
void joystick_cb(int jid, int event) {
|
||||||
{
|
|
||||||
YughWarn("IN joystick cb");
|
YughWarn("IN joystick cb");
|
||||||
if (event == GLFW_CONNECTED) {
|
if (event == GLFW_CONNECTED) {
|
||||||
for (int i = 0; i < arrlen(joysticks); i++)
|
for (int i = 0; i < arrlen(joysticks); i++)
|
||||||
|
@ -208,58 +211,54 @@ void joystick_cb(int jid, int event)
|
||||||
} else if (event == GLFW_DISCONNECTED) {
|
} else if (event == GLFW_DISCONNECTED) {
|
||||||
for (int i = 0; i < arrlen(joysticks); i++) {
|
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||||
if (joysticks[i].id == jid) {
|
if (joysticks[i].id == jid) {
|
||||||
arrdelswap(joysticks,i);
|
arrdelswap(joysticks, i);
|
||||||
return;
|
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()
|
char *paddb = slurp_text("data/gamecontrollerdb.txt");
|
||||||
{
|
glfwUpdateGamepadMappings(paddb);
|
||||||
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
free(paddb);
|
||||||
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");
|
for (int b = 0; b < 15; b++)
|
||||||
glfwUpdateGamepadMappings(paddb);
|
jsgamepadstr[b] = str2js(gamepad2str(b));
|
||||||
free(paddb);
|
|
||||||
|
|
||||||
for (int b = 0; b < 15; b++)
|
jsaxesstr[0] = str2js("ljoy");
|
||||||
jsgamepadstr[b] = str2js(gamepad2str(b));
|
jsaxesstr[1] = str2js("rjoy");
|
||||||
|
jsaxesstr[2] = str2js("ltrigger");
|
||||||
|
jsaxesstr[3] = str2js("rtrigger");
|
||||||
|
jsaxis = str2js("axis");
|
||||||
|
|
||||||
jsaxesstr[0] = str2js("ljoy");
|
/* Grab all joysticks initially present */
|
||||||
jsaxesstr[1] = str2js("rjoy");
|
for (int i = 0; i < 16; i++)
|
||||||
jsaxesstr[2] = str2js("ltrigger");
|
if (glfwJoystickPresent(i)) joystick_add(i);
|
||||||
jsaxesstr[3] = str2js("rtrigger");
|
|
||||||
jsaxis = str2js("axis");
|
|
||||||
|
|
||||||
/* Grab all joysticks initially present */
|
jsinputstate[0] = str2js("released");
|
||||||
for (int i = 0; i < 16; i++)
|
jsinputstate[1] = str2js("rep");
|
||||||
if (glfwJoystickPresent(i)) joystick_add(i);
|
jsinputstate[2] = str2js("pressed");
|
||||||
|
jsinputstate[3] = str2js("pressrep");
|
||||||
jsinputstate[0] = str2js("released");
|
jsinputstate[4] = str2js("down");
|
||||||
jsinputstate[1] = str2js("rep");
|
jsinput = str2js("input");
|
||||||
jsinputstate[2] = str2js("pressed");
|
jsnum = str2js("num");
|
||||||
jsinputstate[3] = str2js("pressrep");
|
jsany = str2js("any");
|
||||||
jsinputstate[4] = str2js("down");
|
jsmouse = str2js("mouse");
|
||||||
jsinput = str2js("input");
|
jspos = str2js("pos");
|
||||||
jsnum = str2js("num");
|
|
||||||
jsany = str2js("any");
|
|
||||||
jsmouse = str2js("mouse");
|
|
||||||
jspos = str2js("pos");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_to_nuke()
|
void input_to_nuke() {
|
||||||
{
|
|
||||||
glfwSetCharCallback(mainwin->window, nukechar);
|
glfwSetCharCallback(mainwin->window, nukechar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_to_game()
|
void input_to_game() {
|
||||||
{
|
|
||||||
glfwSetCharCallback(mainwin->window, char_cb);
|
glfwSetCharCallback(mainwin->window, char_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,308 +271,303 @@ void call_input_signal(char *signal) {
|
||||||
char keybuf[50];
|
char keybuf[50];
|
||||||
|
|
||||||
const char *keyname_extd(int key, int scancode) {
|
const char *keyname_extd(int key, int scancode) {
|
||||||
const char *kkey = NULL;
|
const char *kkey = NULL;
|
||||||
|
|
||||||
if (key > 289 && key < 302) {
|
if (key > 289 && key < 302) {
|
||||||
int num = key-289;
|
int num = key - 289;
|
||||||
sprintf(keybuf, "f%d", num);
|
sprintf(keybuf, "f%d", num);
|
||||||
return keybuf;
|
return keybuf;
|
||||||
} else if (key >= 320 && key <= 329) {
|
} else if (key >= 320 && key <= 329) {
|
||||||
int num = key-320;
|
int num = key - 320;
|
||||||
sprintf(keybuf, "kp%d",num);
|
sprintf(keybuf, "kp%d", num);
|
||||||
return keybuf;
|
return keybuf;
|
||||||
} else {
|
} else {
|
||||||
switch(key) {
|
switch (key) {
|
||||||
case GLFW_KEY_ENTER:
|
case GLFW_KEY_ENTER:
|
||||||
kkey = "enter";
|
kkey = "enter";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_ESCAPE:
|
case GLFW_KEY_ESCAPE:
|
||||||
kkey = "escape";
|
kkey = "escape";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_DELETE:
|
case GLFW_KEY_DELETE:
|
||||||
kkey = "delete";
|
kkey = "delete";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_INSERT:
|
case GLFW_KEY_INSERT:
|
||||||
kkey = "insert";
|
kkey = "insert";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_TAB:
|
case GLFW_KEY_TAB:
|
||||||
kkey = "tab";
|
kkey = "tab";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_RIGHT:
|
case GLFW_KEY_RIGHT:
|
||||||
kkey = "right";
|
kkey = "right";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_LEFT:
|
case GLFW_KEY_LEFT:
|
||||||
kkey = "left";
|
kkey = "left";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_UP:
|
case GLFW_KEY_UP:
|
||||||
kkey = "up";
|
kkey = "up";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_DOWN:
|
case GLFW_KEY_DOWN:
|
||||||
kkey = "down";
|
kkey = "down";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_LEFT_SHIFT:
|
case GLFW_KEY_LEFT_SHIFT:
|
||||||
kkey = "lshift";
|
kkey = "lshift";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_RIGHT_SHIFT:
|
case GLFW_KEY_RIGHT_SHIFT:
|
||||||
kkey = "rshift";
|
kkey = "rshift";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_LEFT_CONTROL:
|
case GLFW_KEY_LEFT_CONTROL:
|
||||||
kkey = "lctrl";
|
kkey = "lctrl";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_LEFT_ALT:
|
case GLFW_KEY_LEFT_ALT:
|
||||||
kkey = "lalt";
|
kkey = "lalt";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_RIGHT_CONTROL:
|
case GLFW_KEY_RIGHT_CONTROL:
|
||||||
kkey = "rctrl";
|
kkey = "rctrl";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_RIGHT_ALT:
|
case GLFW_KEY_RIGHT_ALT:
|
||||||
kkey= "ralt";
|
kkey = "ralt";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_SPACE:
|
case GLFW_KEY_SPACE:
|
||||||
kkey = "space";
|
kkey = "space";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||||
kkey = "rmouse";
|
kkey = "rmouse";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_LEFT:
|
case GLFW_MOUSE_BUTTON_LEFT:
|
||||||
kkey = "lmouse";
|
kkey = "lmouse";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||||
kkey = "mmouse";
|
kkey = "mmouse";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_KP_ADD:
|
case GLFW_KEY_KP_ADD:
|
||||||
kkey = "plus";
|
kkey = "plus";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_KP_SUBTRACT:
|
case GLFW_KEY_KP_SUBTRACT:
|
||||||
kkey = "minus";
|
kkey = "minus";
|
||||||
break;
|
break;
|
||||||
case GLFW_KEY_GRAVE_ACCENT:
|
case GLFW_KEY_GRAVE_ACCENT:
|
||||||
kkey = "backtick";
|
kkey = "backtick";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_LEFT_BRACKET:
|
case GLFW_KEY_LEFT_BRACKET:
|
||||||
kkey = "lbracket";
|
kkey = "lbracket";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_RIGHT_BRACKET:
|
case GLFW_KEY_RIGHT_BRACKET:
|
||||||
kkey = "rbracket";
|
kkey = "rbracket";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_BACKSPACE:
|
case GLFW_KEY_BACKSPACE:
|
||||||
kkey = "backspace";
|
kkey = "backspace";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kkey) return kkey;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
kkey = glfwGetKeyName(key, scancode);
|
|
||||||
|
|
||||||
if (kkey) return kkey;
|
if (kkey) return kkey;
|
||||||
|
}
|
||||||
|
|
||||||
return "NULL";
|
kkey = glfwGetKeyName(key, scancode);
|
||||||
|
|
||||||
|
if (kkey) return kkey;
|
||||||
|
|
||||||
|
return "NULL";
|
||||||
}
|
}
|
||||||
|
|
||||||
void call_input_down(int *key) {
|
void call_input_down(int *key) {
|
||||||
JSValue argv[3];
|
JSValue argv[3];
|
||||||
argv[0] = jsinput;
|
argv[0] = jsinput;
|
||||||
argv[1] = input2js(keyname_extd(*key, *key));
|
argv[1] = input2js(keyname_extd(*key, *key));
|
||||||
argv[2] = jsinputstate[4];
|
argv[2] = jsinputstate[4];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *axis2str(int axis) {
|
||||||
const char *axis2str(int axis)
|
switch (axis) {
|
||||||
{
|
case GLFW_GAMEPAD_AXIS_LEFT_X:
|
||||||
switch (axis)
|
return "lx";
|
||||||
{
|
case GLFW_GAMEPAD_AXIS_LEFT_Y:
|
||||||
case GLFW_GAMEPAD_AXIS_LEFT_X: return "lx";
|
return "ly";
|
||||||
case GLFW_GAMEPAD_AXIS_LEFT_Y: return "ly";
|
case GLFW_GAMEPAD_AXIS_RIGHT_X:
|
||||||
case GLFW_GAMEPAD_AXIS_RIGHT_X: return "rx";
|
return "rx";
|
||||||
case GLFW_GAMEPAD_AXIS_RIGHT_Y: return "ry";
|
case GLFW_GAMEPAD_AXIS_RIGHT_Y:
|
||||||
case GLFW_GAMEPAD_AXIS_LEFT_TRIGGER: return "ltrigger";
|
return "ry";
|
||||||
case GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER: return "rtrigger";
|
case GLFW_GAMEPAD_AXIS_LEFT_TRIGGER:
|
||||||
|
return "ltrigger";
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER:
|
||||||
|
return "rtrigger";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "NOAXIS";
|
return "NOAXIS";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called once every frame - or more if we want it more! */
|
/* This is called once every frame - or more if we want it more! */
|
||||||
void input_poll(double wait)
|
void input_poll(double wait) {
|
||||||
{
|
mouse_delta = cpvzero;
|
||||||
mouse_delta = cpvzero;
|
mouseWheelX = 0;
|
||||||
mouseWheelX = 0;
|
mouseWheelY = 0;
|
||||||
mouseWheelY = 0;
|
|
||||||
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
// glfwWaitEventsTimeout(wait);
|
// glfwWaitEventsTimeout(wait);
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(downkeys); i++)
|
for (int i = 0; i < arrlen(downkeys); i++)
|
||||||
call_input_down(&downkeys[i]);
|
call_input_down(&downkeys[i]);
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(joysticks); i++) {
|
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||||
GLFWgamepadstate state;
|
GLFWgamepadstate state;
|
||||||
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||||
|
|
||||||
JSValue argv[4];
|
JSValue argv[4];
|
||||||
argv[0] = num_cache[joysticks[i].id];
|
argv[0] = num_cache[joysticks[i].id];
|
||||||
for (int b = 0; b < 15; b++) {
|
for (int b = 0; b < 15; b++) {
|
||||||
argv[1] = jsgamepadstr[b];
|
argv[1] = jsgamepadstr[b];
|
||||||
|
|
||||||
if (state.buttons[b]) {
|
if (state.buttons[b]) {
|
||||||
argv[2] = num_cache[0];
|
argv[2] = num_cache[0];
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee, 3, argv);
|
||||||
|
|
||||||
if (!joysticks[i].state.buttons[b]) {
|
if (!joysticks[i].state.buttons[b]) {
|
||||||
argv[2] = num_cache[1];
|
argv[2] = num_cache[1];
|
||||||
script_callee(gamepad_callee,3,argv);
|
script_callee(gamepad_callee, 3, argv);
|
||||||
}
|
}
|
||||||
}
|
} else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
||||||
else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
argv[2] = num_cache[2];
|
||||||
argv[2] = num_cache[2];
|
script_callee(gamepad_callee, 3, argv);
|
||||||
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) {
|
int key_is_num(int key) {
|
||||||
return key <= 57 && key >= 48;
|
return key <= 57 && key >= 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods)
|
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) {
|
||||||
{
|
JSValue argv[3];
|
||||||
JSValue argv[3];
|
argv[0] = jsinput;
|
||||||
argv[0] = jsinput;
|
argv[1] = input2js(keyname_extd(key, scancode));
|
||||||
argv[1] = input2js(keyname_extd(key,scancode));
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case GLFW_PRESS:
|
case GLFW_PRESS:
|
||||||
argv[2] = jsinputstate[2];
|
argv[2] = jsinputstate[2];
|
||||||
script_callee(pawn_callee, 3, argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
argv[2] = jsinputstate[3];
|
argv[2] = jsinputstate[3];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
add_downkey(key);
|
add_downkey(key);
|
||||||
argv[1] = jsany;
|
argv[1] = jsany;
|
||||||
argv[2] = jsinputstate[2];
|
argv[2] = jsinputstate[2];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
|
|
||||||
if (key_is_num(key))
|
if (key_is_num(key))
|
||||||
pawn_call_keydown(key-48);
|
pawn_call_keydown(key - 48);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_RELEASE:
|
case GLFW_RELEASE:
|
||||||
argv[2] = jsinputstate[0];
|
argv[2] = jsinputstate[0];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
rm_downkey(key);
|
rm_downkey(key);
|
||||||
argv[1] = jsany;
|
argv[1] = jsany;
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_REPEAT:
|
case GLFW_REPEAT:
|
||||||
argv[2] = jsinputstate[1];
|
argv[2] = jsinputstate[1];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
argv[2] = jsinputstate[3];
|
argv[2] = jsinputstate[3];
|
||||||
script_callee(pawn_callee,3,argv);
|
script_callee(pawn_callee, 3, argv);
|
||||||
break;
|
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()
|
return !found;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int want_quit() {
|
int want_quit() {
|
||||||
return mquit;
|
return mquit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit() {
|
void quit() {
|
||||||
YughInfo("Exiting game.");
|
YughInfo("Exiting game.");
|
||||||
mquit = 1;
|
mquit = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#ifndef INPUT_H
|
#ifndef INPUT_H
|
||||||
#define INPUT_H
|
#define INPUT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "script.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include <chipmunk/chipmunk.h>
|
#include <chipmunk/chipmunk.h>
|
||||||
#include "script.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
extern int32_t mouseWheelX;
|
extern int32_t mouseWheelX;
|
||||||
extern int32_t mouseWheelY;
|
extern int32_t mouseWheelY;
|
||||||
|
@ -33,9 +33,8 @@ void quit();
|
||||||
|
|
||||||
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods);
|
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods);
|
||||||
|
|
||||||
struct inputaction
|
struct inputaction {
|
||||||
{
|
int scancode;
|
||||||
int scancode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void input_to_nuke();
|
void input_to_nuke();
|
||||||
|
|
|
@ -1,53 +1,49 @@
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
void save_level(char name[MAXNAME])
|
void save_level(char name[MAXNAME]) {
|
||||||
{
|
FILE *lfile = res_open(name, "wb+");
|
||||||
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);
|
fclose(lfile);
|
||||||
fwrite(&objs, sizeof(objs), 1, lfile);
|
|
||||||
|
|
||||||
fclose(lfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_level(char name[MAXNAME])
|
void load_level(char name[MAXNAME]) {
|
||||||
{
|
/*
|
||||||
/*
|
FILE *lfile = fopen(name, "rb");
|
||||||
FILE *lfile = fopen(name, "rb");
|
|
||||||
|
|
||||||
if (!lfile) return;
|
if (!lfile) return;
|
||||||
|
|
||||||
new_level();
|
new_level();
|
||||||
|
|
||||||
int objs;
|
int objs;
|
||||||
fread(&objs, sizeof(objs), 1, lfile);
|
fread(&objs, sizeof(objs), 1, lfile);
|
||||||
|
|
||||||
arraddn(gameobjects, objs);
|
arraddn(gameobjects, objs);
|
||||||
|
|
||||||
for (int i = 0; i < objs; i++) {
|
for (int i = 0; i < objs; i++) {
|
||||||
struct gameobject *go = &gameobjects[i];
|
struct gameobject *go = &gameobjects[i];
|
||||||
fread(go, sizeof(struct gameobject), 1, lfile);
|
fread(go, sizeof(struct gameobject), 1, lfile);
|
||||||
go->components = NULL;
|
go->components = NULL;
|
||||||
gameobject_init(go, lfile);
|
gameobject_init(go, lfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(lfile);
|
fclose(lfile);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_level()
|
void new_level() {
|
||||||
{
|
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||||
for (int i = 0; i < arrlen(gameobjects); i++)
|
gameobject_delete(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.
|
// 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 {
|
struct level {
|
||||||
char name[MAXNAME];
|
char name[MAXNAME];
|
||||||
};
|
};
|
||||||
|
|
||||||
void save_level(char name[MAXNAME]);
|
void save_level(char name[MAXNAME]);
|
||||||
void load_level(char name[MAXNAME]);
|
void load_level(char name[MAXNAME]);
|
||||||
void new_level();
|
void new_level();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#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_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_IMPLEMENTATION
|
||||||
#define NK_GLFW_GL3_IMPLEMENTATION
|
|
||||||
#define NK_KEYSTATE_BASED_INPUT
|
#define NK_KEYSTATE_BASED_INPUT
|
||||||
|
|
||||||
|
#define STBTT_STATIC
|
||||||
|
|
||||||
#include "nuke.h"
|
#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 <stdarg.h>
|
||||||
|
|
||||||
#include "window.h"
|
|
||||||
#include "texture.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#define MAX_VERTEX_BUFFER 512 * 1024
|
#define MAX_VERTEX_BUFFER 512 * 1024
|
||||||
#define MAX_ELEMENT_BUFFER 128 * 1024
|
#define MAX_ELEMENT_BUFFER 128 * 1024
|
||||||
|
|
||||||
struct nk_context *ctx;
|
struct nk_context *ctx;
|
||||||
static struct nk_glfw nkglfw = {0};
|
//static struct nk_glfw nkglfw = {0};
|
||||||
|
|
||||||
|
|
||||||
void nuke_init(struct window *win) {
|
void nuke_init(struct window *win) {
|
||||||
window_makecurrent(win);
|
window_makecurrent(win);
|
||||||
|
|
||||||
ctx = nk_glfw3_init(&nkglfw, win->window, NK_GLFW3_INSTALL_CALLBACKS);
|
snk_setup(&(snk_desc_t){
|
||||||
|
.no_default_font = false
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_start()
|
void nuke_start() {
|
||||||
{
|
ctx = snk_new_frame();
|
||||||
nk_glfw3_new_frame(&nkglfw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_end()
|
void nuke_end() {
|
||||||
{
|
snk_render(1200,720);
|
||||||
nk_glfw3_render(&nkglfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int nuke_begin(const char *lbl, struct nk_rect rect, int flags) {
|
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);
|
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() {
|
void nuke_stop() {
|
||||||
nk_end(ctx);
|
nk_end(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nk_rect nuke_win_get_bounds() {
|
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);
|
nk_layout_row_dynamic(ctx, height, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_property_float3(const char *label, float min, float *val, float max, float step, float dragstep) {
|
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_layout_row_dynamic(ctx, 25, 1);
|
||||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||||
nk_layout_row_dynamic(ctx, 25, 3);
|
nk_layout_row_dynamic(ctx, 25, 3);
|
||||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||||
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
|
||||||
nuke_property_float("#Z", min, &val[2], 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) {
|
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_layout_row_dynamic(ctx, 25, 1);
|
||||||
nk_label(ctx, label, NK_TEXT_LEFT);
|
nk_label(ctx, label, NK_TEXT_LEFT);
|
||||||
nk_layout_row_dynamic(ctx, 25, 2);
|
nk_layout_row_dynamic(ctx, 25, 2);
|
||||||
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
nuke_property_float("#X", min, &val[0], max, step, dragstep);
|
||||||
nuke_property_float("#Y", min, &val[1], 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) {
|
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) {
|
int nuke_btn(const char *lbl) {
|
||||||
return nk_button_label(ctx, lbl);
|
return nk_button_label(ctx, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_img(char *path) {
|
void nuke_img(char *path) {
|
||||||
/*
|
/*
|
||||||
struct Texture *t = texture_pullfromfile(path);
|
struct Texture *t = texture_pullfromfile(path);
|
||||||
nk_layout_row_static(ctx, t->height, t->width, 1);
|
nk_layout_row_static(ctx, t->height, t->width, 1);
|
||||||
nk_image(ctx, nk_image_id(t->id));
|
nk_image(ctx, nk_image_id(t->id));
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_property_int(const char *lbl, int min, int *val, int max, int step) {
|
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) {
|
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) {
|
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)
|
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);
|
||||||
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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() {
|
void nuke_tree_pop() {
|
||||||
nk_tree_pop(ctx);
|
nk_tree_pop(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nuke_labelf(const char *fmt, ...) {
|
void nuke_labelf(const char *fmt, ...) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(buf, 512, fmt, args);
|
vsnprintf(buf, 512, fmt, args);
|
||||||
nuke_label(buf);
|
nuke_label(buf);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#ifndef NUKE_H
|
#ifndef NUKE_H
|
||||||
#define 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"
|
#include "nuklear.h"
|
||||||
|
|
||||||
struct window;
|
struct window;
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
#include "openglrender.h"
|
#include "openglrender.h"
|
||||||
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "font.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "gameobject.h"
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "window.h"
|
#include "config.h"
|
||||||
#include "debugdraw.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "datastream.h"
|
#include "datastream.h"
|
||||||
|
#include "debugdraw.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "gameobject.h"
|
||||||
|
#include "log.h"
|
||||||
#include "nuke.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;
|
int renderMode = LIT;
|
||||||
|
|
||||||
|
@ -19,13 +23,13 @@ struct shader *wireframeShader = NULL;
|
||||||
struct shader *animSpriteShader = NULL;
|
struct shader *animSpriteShader = NULL;
|
||||||
static struct shader *textShader;
|
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;
|
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 gridScale = 500.f;
|
||||||
float smallGridUnit = 1.f;
|
float smallGridUnit = 1.f;
|
||||||
|
@ -50,130 +54,263 @@ bool renderReflection = true;
|
||||||
|
|
||||||
///// for editing
|
///// for editing
|
||||||
struct gameobject *selectedobject = NULL;
|
struct gameobject *selectedobject = NULL;
|
||||||
char objectName[200] = { '\0' }; // object name buffer
|
char objectName[200] = {'\0'}; // object name buffer
|
||||||
|
|
||||||
struct sprite *tsprite = NULL;
|
struct sprite *tsprite = NULL;
|
||||||
|
|
||||||
const char *donquixote;
|
const char *donquixote;
|
||||||
|
|
||||||
|
static struct model *duck;
|
||||||
|
|
||||||
|
sg_image ddimg;
|
||||||
|
|
||||||
void debug_draw_phys(int draw) {
|
void debug_draw_phys(int draw) {
|
||||||
debugDrawPhysics = draw;
|
debugDrawPhysics = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opengl_rendermode(enum RenderMode r)
|
void opengl_rendermode(enum RenderMode r) {
|
||||||
{
|
|
||||||
renderMode = r;
|
renderMode = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_pipeline mainpip;
|
sg_pipeline mainpip;
|
||||||
sg_pass_action pass_action = {0};
|
sg_pass_action pass_action = {0};
|
||||||
|
|
||||||
void openglInit()
|
static struct {
|
||||||
{
|
sg_pass_action pass_action;
|
||||||
if (!mainwin) {
|
sg_pass pass;
|
||||||
YughError("No window to init OpenGL on.", 1);
|
sg_pipeline pipe;
|
||||||
exit(1);
|
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
|
crt_post.img = sg_make_image(&(sg_image_desc){
|
||||||
spriteShader = MakeShader("spritevert.glsl", "spritefrag.glsl");
|
.render_target = true,
|
||||||
wireframeShader = MakeShader("spritevert.glsl", "spritewireframefrag.glsl");
|
.width = 1200,
|
||||||
animSpriteShader = MakeShader("animspritevert.glsl", "animspritefrag.glsl");
|
.height = 720,
|
||||||
textShader = MakeShader("textvert.glsl", "textfrag.glsl");
|
});
|
||||||
|
|
||||||
font_init(textShader);
|
crt_post.depth_img = sg_make_image(&(sg_image_desc){
|
||||||
sprite_initialize();
|
.render_target = true,
|
||||||
debugdraw_init();
|
.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);
|
duck = MakeModel("sponza.glb");
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
glGenBuffers(1, &projUBO);
|
sg_shadow.pass = sg_make_pass(&(sg_pass_desc){
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, projUBO);
|
.color_attachments[0].image = depth_img,
|
||||||
glBufferData(GL_UNIFORM_BUFFER, 64, NULL, GL_DYNAMIC_DRAW);
|
.depth_stencil_attachment.image = ddimg,
|
||||||
glBindBufferRange(GL_UNIFORM_BUFFER, 0, projUBO, 0, sizeof(float) * 16);
|
});
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
|
sg_shadow.pass_action = (sg_pass_action) {
|
||||||
|
.colors[0] = { .action=SG_ACTION_CLEAR, .value = {1,1,1,1} } };
|
||||||
|
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
shader_setUBO(spriteShader, "Projection", 0);
|
|
||||||
shader_setUBO(textShader, "Projection", 0);
|
|
||||||
shader_setUBO(animSpriteShader, "Projection", 0);
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static cpBody *camera = NULL;
|
static cpBody *camera = NULL;
|
||||||
void set_cam_body(cpBody *body) {
|
void set_cam_body(cpBody *body) {
|
||||||
camera = body;
|
camera = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpVect cam_pos() {
|
cpVect cam_pos() {
|
||||||
return camera ? cpBodyGetPosition(camera) : cpvzero;
|
return camera ? cpBodyGetPosition(camera) : cpvzero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float zoom = 1.f;
|
static float zoom = 1.f;
|
||||||
float cam_zoom() { return zoom; }
|
float cam_zoom() { return zoom; }
|
||||||
|
|
||||||
|
|
||||||
void add_zoom(float val) { zoom = val; }
|
void add_zoom(float val) { zoom = val; }
|
||||||
|
|
||||||
mfloat_t projection[16] = {0.f};
|
mfloat_t projection[16] = {0.f};
|
||||||
|
|
||||||
void openglRender(struct window *window)
|
HMM_Vec3 dirl_pos = {4, 100, 20};
|
||||||
{
|
|
||||||
sg_begin_default_pass(&pass_action, window->width, window->height);
|
|
||||||
|
|
||||||
//////////// 2D projection
|
void openglRender(struct window *window) {
|
||||||
cpVect pos = cam_pos();
|
/*
|
||||||
|
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 };
|
// Shadow pass
|
||||||
mat4_ortho(ui_projection, 0,
|
sg_begin_pass(sg_shadow.pass, &sg_shadow.pass_action);
|
||||||
window->width,
|
sg_apply_pipeline(sg_shadow.pipe);
|
||||||
0,
|
|
||||||
window->height, -1.f, 1.f);
|
|
||||||
|
|
||||||
sprite_draw_all();
|
HMM_Mat4 light_proj = HMM_Orthographic_RH_ZO(-100.f, 100.f, -100.f, 100.f, 1.f, 100.f);
|
||||||
gui_draw_img("pill1.png", 200, 200);
|
HMM_Mat4 light_view = HMM_LookAt_RH(dirl_pos, (HMM_Vec3){0,0,0}, (HMM_Vec3){0,1,0});
|
||||||
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};
|
HMM_Mat4 lsm = HMM_MulM4(light_proj, light_view);
|
||||||
renderText("TEST @@@@ RENDER", b, 1.f, w, 0,-1);
|
|
||||||
|
|
||||||
/* UI Elements & Debug elements */
|
HMM_Mat4 subo[2];
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
subo[0] = lsm;
|
||||||
// glDisable(GL_DEPTH_TEST);
|
subo[1] = model;
|
||||||
//// DEBUG
|
|
||||||
// if (debugDrawPhysics)
|
|
||||||
// gameobject_draw_debugs();
|
|
||||||
|
|
||||||
// call_debugs();
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(subo));
|
||||||
|
|
||||||
////// TEXT && GUI
|
for (int i = 0; i < arrlen(duck->meshes); i++) {
|
||||||
// glBindBuffer(GL_UNIFORM_BUFFER, projUBO);
|
sg_bindings sbind = {0};
|
||||||
// glBufferSubData(GL_UNIFORM_BUFFER, 0, 64, ui_projection);
|
sbind.vertex_buffers[0] = duck->meshes[i].bind.vertex_buffers[0];
|
||||||
text_flush();
|
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();
|
// sg_begin_default_pass(&pass_action, window->width, window->height);
|
||||||
// call_nk_gui();
|
sg_begin_pass(crt_post.pass, &pass_action);
|
||||||
// nuke_end();
|
|
||||||
|
|
||||||
|
//////////// 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_end_pass();
|
||||||
sg_commit();
|
|
||||||
|
|
||||||
sprite_flush();
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
sg_commit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
#ifndef OPENGL_RENDER_H
|
#ifndef OPENGL_RENDER_H
|
||||||
#define OPENGL_RENDER_H
|
#define OPENGL_RENDER_H
|
||||||
|
|
||||||
|
#include "sokol/sokol_gfx.h"
|
||||||
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
struct mCamera;
|
struct mCamera;
|
||||||
struct window;
|
struct window;
|
||||||
|
|
||||||
extern struct shader *spriteShader;
|
extern struct shader *spriteShader;
|
||||||
extern struct shader *animSpriteShader;
|
extern struct shader *animSpriteShader;
|
||||||
|
|
||||||
|
extern sg_image ddimg;
|
||||||
|
|
||||||
extern struct sprite *tsprite;
|
extern struct sprite *tsprite;
|
||||||
|
|
||||||
extern int renderMode;
|
extern int renderMode;
|
||||||
|
|
||||||
|
extern HMM_Vec3 dirl_pos;
|
||||||
|
|
||||||
extern float projection[16];
|
extern float projection[16];
|
||||||
|
|
||||||
extern float gridScale;
|
extern float gridScale;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,8 +27,7 @@
|
||||||
#define parson_parson_h
|
#define parson_parson_h
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
} /* unconfuse xcode */
|
} /* unconfuse xcode */
|
||||||
|
@ -40,32 +39,32 @@ extern "C"
|
||||||
|
|
||||||
#define PARSON_VERSION_STRING "1.4.0"
|
#define PARSON_VERSION_STRING "1.4.0"
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
/* Types and enums */
|
/* Types and enums */
|
||||||
typedef struct json_object_t JSON_Object;
|
typedef struct json_object_t JSON_Object;
|
||||||
typedef struct json_array_t JSON_Array;
|
typedef struct json_array_t JSON_Array;
|
||||||
typedef struct json_value_t JSON_Value;
|
typedef struct json_value_t JSON_Value;
|
||||||
|
|
||||||
enum json_value_type {
|
enum json_value_type {
|
||||||
JSONError = -1,
|
JSONError = -1,
|
||||||
JSONNull = 1,
|
JSONNull = 1,
|
||||||
JSONString = 2,
|
JSONString = 2,
|
||||||
JSONNumber = 3,
|
JSONNumber = 3,
|
||||||
JSONObject = 4,
|
JSONObject = 4,
|
||||||
JSONArray = 5,
|
JSONArray = 5,
|
||||||
JSONBoolean = 6
|
JSONBoolean = 6
|
||||||
};
|
};
|
||||||
typedef int JSON_Value_Type;
|
typedef int JSON_Value_Type;
|
||||||
|
|
||||||
enum json_result_t {
|
enum json_result_t {
|
||||||
JSONSuccess = 0,
|
JSONSuccess = 0,
|
||||||
JSONFailure = -1
|
JSONFailure = -1
|
||||||
};
|
};
|
||||||
typedef int JSON_Status;
|
typedef int JSON_Status;
|
||||||
|
|
||||||
typedef void * (*JSON_Malloc_Function)(size_t);
|
typedef void *(*JSON_Malloc_Function)(size_t);
|
||||||
typedef void (*JSON_Free_Function)(void *);
|
typedef void (*JSON_Free_Function)(void *);
|
||||||
|
|
||||||
/* Call only once, before calling any other function from parson API. If not called, malloc and free
|
/* 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 */
|
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);
|
void json_set_float_serialization_format(const char *format);
|
||||||
|
|
||||||
/* Parses first JSON value in a file, returns NULL in case of error */
|
/* 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 //),
|
/* Parses first JSON value in a file and ignores comments (/ * * / and //),
|
||||||
returns NULL in case of error */
|
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 */
|
/* 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 //),
|
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||||
returns NULL in case of error */
|
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 */
|
/* 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_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);
|
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 */
|
/* 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_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);
|
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 */
|
/* 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
|
/* Validation
|
||||||
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
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 Object
|
||||||
*/
|
*/
|
||||||
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name);
|
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);
|
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 */
|
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_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);
|
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 */
|
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 */
|
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,
|
/* 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).
|
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
|
Because valid names in JSON can contain dots, some values may be inaccessible
|
||||||
this way. */
|
this way. */
|
||||||
JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *name);
|
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);
|
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 */
|
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_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);
|
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 */
|
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 */
|
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||||
|
|
||||||
/* Functions to get available names */
|
/* Functions to get available names */
|
||||||
size_t json_object_get_count (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);
|
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_value_at(const JSON_Object *object, size_t index);
|
||||||
JSON_Value * json_object_get_wrapping_value(const JSON_Object *object);
|
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
|
/* 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. */
|
* 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_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);
|
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.
|
/* 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_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_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(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_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_boolean(JSON_Object *object, const char *name, int boolean);
|
||||||
JSON_Status json_object_set_null(JSON_Object *object, const char *name);
|
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 Array
|
||||||
*/
|
*/
|
||||||
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index);
|
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);
|
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 */
|
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_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);
|
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 */
|
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 */
|
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);
|
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_wrapping_value(const JSON_Array *array);
|
||||||
|
|
||||||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
/* 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. */
|
* 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.
|
* 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_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_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_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_number(JSON_Array *array, size_t i, double number);
|
||||||
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
|
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 * json_value_init_object (void);
|
JSON_Value *json_value_init_object(void);
|
||||||
JSON_Value * json_value_init_array (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(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_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_number(double number);
|
||||||
JSON_Value * json_value_init_boolean(int boolean);
|
JSON_Value *json_value_init_boolean(int boolean);
|
||||||
JSON_Value * json_value_init_null (void);
|
JSON_Value *json_value_init_null(void);
|
||||||
JSON_Value * json_value_deep_copy (const JSON_Value *value);
|
JSON_Value *json_value_deep_copy(const JSON_Value *value);
|
||||||
void json_value_free (JSON_Value *value);
|
void json_value_free(JSON_Value *value);
|
||||||
|
|
||||||
JSON_Value_Type json_value_get_type (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_Object *json_value_get_object(const JSON_Value *value);
|
||||||
JSON_Array * json_value_get_array (const JSON_Value *value);
|
JSON_Array *json_value_get_array(const JSON_Value *value);
|
||||||
const char * json_value_get_string (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 */
|
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);
|
double json_value_get_number(const JSON_Value *value);
|
||||||
int json_value_get_boolean(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 *json_value_get_parent(const JSON_Value *value);
|
||||||
|
|
||||||
/* Same as above, but shorter */
|
/* Same as above, but shorter */
|
||||||
JSON_Value_Type json_type (const JSON_Value *value);
|
JSON_Value_Type json_type(const JSON_Value *value);
|
||||||
JSON_Object * json_object (const JSON_Value *value);
|
JSON_Object *json_object(const JSON_Value *value);
|
||||||
JSON_Array * json_array (const JSON_Value *value);
|
JSON_Array *json_array(const JSON_Value *value);
|
||||||
const char * json_string (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 */
|
size_t json_string_len(const JSON_Value *value); /* doesn't account for last null character */
|
||||||
double json_number (const JSON_Value *value);
|
double json_number(const JSON_Value *value);
|
||||||
int json_boolean(const JSON_Value *value);
|
int json_boolean(const JSON_Value *value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,48 @@
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
struct emitter make_emitter()
|
struct emitter make_emitter() {
|
||||||
{
|
struct emitter e = {0};
|
||||||
struct emitter e = { 0 };
|
return e;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct emitter set_emitter(struct emitter e)
|
struct emitter set_emitter(struct emitter e) {
|
||||||
{
|
arrsetlen(e.particles, e.max);
|
||||||
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++) {
|
for (int i = 0; i < arrlen(e.particles) - 1; i++) {
|
||||||
e.particles[i].next = &e.particles[i+1];
|
e.particles[i].next = &e.particles[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_emitter(struct emitter e)
|
void free_emitter(struct emitter e) {
|
||||||
{
|
arrfree(e.particles);
|
||||||
arrfree(e.particles);
|
}
|
||||||
}
|
|
||||||
|
void start_emitter(struct emitter e) {
|
||||||
void start_emitter(struct emitter e)
|
}
|
||||||
{
|
|
||||||
|
void pause_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++) {
|
||||||
void stop_emitter(struct emitter e)
|
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;
|
||||||
void emitter_step(struct emitter e, double dt)
|
e.particles[i].life -= dt;
|
||||||
{
|
|
||||||
for (int i = 0; i < arrlen(e.particles); i++) {
|
if (e.particles[i].life <= 0) {
|
||||||
if (e.particles[i].life <= 0)
|
e.particles[i].next = e.first;
|
||||||
continue;
|
e.first = &e.particles[i];
|
||||||
|
|
||||||
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 "resources.h"
|
||||||
|
|
||||||
#include "config.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 "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>
|
#include <ftw.h>
|
||||||
|
|
||||||
|
@ -31,111 +31,101 @@ static const char *cur_ext = NULL;
|
||||||
struct dirent *c_dirent = NULL;
|
struct dirent *c_dirent = NULL;
|
||||||
struct vec *c_vec = NULL;
|
struct vec *c_vec = NULL;
|
||||||
|
|
||||||
char pathbuf[MAXPATH+1];
|
char pathbuf[MAXPATH + 1];
|
||||||
|
|
||||||
void resources_init()
|
void resources_init() {
|
||||||
{
|
prefabs = vec_make(MAXNAME, 25);
|
||||||
prefabs = vec_make(MAXNAME, 25);
|
|
||||||
|
|
||||||
DATA_PATH = malloc(MAXPATH);
|
DATA_PATH = malloc(MAXPATH);
|
||||||
getcwd(DATA_PATH, MAXPATH);
|
getcwd(DATA_PATH, MAXPATH);
|
||||||
strncat(DATA_PATH, "/", MAXPATH);
|
strncat(DATA_PATH, "/", MAXPATH);
|
||||||
|
|
||||||
if (!PREF_PATH)
|
if (!PREF_PATH)
|
||||||
PREF_PATH = strdup("./tmp/");
|
PREF_PATH = strdup("./tmp/");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_filename_from_path(char *path, int extension)
|
char *get_filename_from_path(char *path, int extension) {
|
||||||
{
|
char *dirpos = strrchr(path, '/');
|
||||||
char *dirpos = strrchr(path, '/');
|
if (!dirpos)
|
||||||
if (!dirpos)
|
dirpos = path;
|
||||||
dirpos = path;
|
|
||||||
|
|
||||||
char *end = strrchr(path, '\0');
|
char *end = strrchr(path, '\0');
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
char *ext = strrchr(path, '.');
|
char *ext = strrchr(path, '.');
|
||||||
offset = end - ext;
|
offset = end - ext;
|
||||||
YughInfo("Making %s without extension ...");
|
YughInfo("Making %s without extension ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *filename = malloc(sizeof(char) * (end - dirpos - offset + 1));
|
char *filename = malloc(sizeof(char) * (end - dirpos - offset + 1));
|
||||||
strncpy(filename, dirpos, end - dirpos - offset);
|
strncpy(filename, dirpos, end - dirpos - offset);
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_directory_from_path(char *path)
|
char *get_directory_from_path(char *path) {
|
||||||
{
|
const char *dirpos = strrchr(path, '/');
|
||||||
const char *dirpos = strrchr(path, '/');
|
char *directory = (char *)malloc(sizeof(char) * (dirpos - path + 1));
|
||||||
char *directory = (char *) malloc(sizeof(char) * (dirpos - path + 1));
|
strncpy(directory, path, dirpos - path);
|
||||||
strncpy(directory, path, dirpos - path);
|
return directory;
|
||||||
return directory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *res_open(char *path, const char *tag)
|
FILE *res_open(char *path, const char *tag) {
|
||||||
{
|
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
strncat(pathbuf, path, MAXPATH);
|
||||||
strncat(pathbuf, path, MAXPATH);
|
FILE *f = fopen(pathbuf, tag);
|
||||||
FILE *f = fopen(pathbuf, tag);
|
return f;
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ext_check(const char *path, const struct stat *sb, int typeflag)
|
static int ext_check(const char *path, const struct stat *sb, int typeflag) {
|
||||||
{
|
if (typeflag == FTW_F) {
|
||||||
if (typeflag == FTW_F) {
|
const char *ext = strrchr(path, '.');
|
||||||
const char *ext = strrchr(path, '.');
|
if (ext != NULL && !strcmp(ext, cur_ext))
|
||||||
if (ext != NULL && !strcmp(ext, cur_ext))
|
vec_add(c_vec, path);
|
||||||
vec_add(c_vec, path);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_extensions(struct vec *vec, const char *path, const char *ext)
|
void fill_extensions(struct vec *vec, const char *path, const char *ext) {
|
||||||
{
|
c_vec = vec;
|
||||||
c_vec = vec;
|
cur_ext = ext;
|
||||||
cur_ext = ext;
|
vec_clear(c_vec);
|
||||||
vec_clear(c_vec);
|
ftw(".", ext_check, 10);
|
||||||
ftw(".", ext_check, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void findPrefabs()
|
void findPrefabs() {
|
||||||
{
|
fill_extensions(prefabs, DATA_PATH, EXT_PREFAB);
|
||||||
fill_extensions(prefabs, DATA_PATH, EXT_PREFAB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *str_replace_ext(const char *s, const char *newext) {
|
char *str_replace_ext(const char *s, const char *newext) {
|
||||||
static char ret[256];
|
static char ret[256];
|
||||||
|
|
||||||
strncpy(ret, s, 256);
|
strncpy(ret, s, 256);
|
||||||
char *ext = strrchr(ret, '.');
|
char *ext = strrchr(ret, '.');
|
||||||
strncpy(ext, newext, 10);
|
strncpy(ext, newext, 10);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *path_open(const char *tag, const char *fmt, ...)
|
FILE *path_open(const char *tag, const char *fmt, ...) {
|
||||||
{
|
va_list args;
|
||||||
va_list args;
|
va_start(args, fmt);
|
||||||
va_start(args, fmt);
|
vsprintf(pathbuf, fmt, args);
|
||||||
vsprintf(pathbuf, fmt, args);
|
va_end(args);
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
FILE *f = fopen(pathbuf, tag);
|
FILE *f = fopen(pathbuf, tag);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *make_path(const char *file)
|
char *make_path(const char *file) {
|
||||||
{
|
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
||||||
strncpy(pathbuf, DATA_PATH, MAXPATH);
|
strncat(pathbuf, file, MAXPATH);
|
||||||
strncat(pathbuf, file, MAXPATH);
|
return pathbuf;
|
||||||
return pathbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strdup(const char *s)
|
char *strdup(const char *s) {
|
||||||
{
|
char *new = malloc(sizeof(char) * (strlen(s) + 1));
|
||||||
char *new = malloc(sizeof(char)*(strlen(s)+1));
|
strcpy(new, s);
|
||||||
strcpy(new, s);
|
return new;
|
||||||
return new;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef RESOURCES_H
|
#ifndef RESOURCES_H
|
||||||
#define RESOURCES_H
|
#define RESOURCES_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
struct vec;
|
struct vec;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
#include "ffi.h"
|
#include "ffi.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
@ -10,39 +10,38 @@
|
||||||
|
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
#include "time.h"
|
|
||||||
#include "sys/stat.h"
|
#include "sys/stat.h"
|
||||||
#include "sys/types.h"
|
#include "sys/types.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
JSContext *js = NULL;
|
JSContext *js = NULL;
|
||||||
JSRuntime *rt = NULL;
|
JSRuntime *rt = NULL;
|
||||||
|
|
||||||
static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) {
|
static int load_prefab(const char *fpath, const struct stat *sb, int typeflag) {
|
||||||
if (typeflag != FTW_F)
|
if (typeflag != FTW_F)
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!strcmp(".prefab", strrchr(fpath, '.')))
|
|
||||||
script_dofile(fpath);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!strcmp(".prefab", strrchr(fpath, '.')))
|
||||||
|
script_dofile(fpath);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void script_startup()
|
void script_startup() {
|
||||||
{
|
rt = JS_NewRuntime();
|
||||||
rt = JS_NewRuntime();
|
JS_SetMaxStackSize(rt, 0);
|
||||||
JS_SetMaxStackSize(rt,0);
|
js = JS_NewContext(rt);
|
||||||
js = JS_NewContext(rt);
|
ffi_load();
|
||||||
ffi_load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue num_cache[100] = {0};
|
JSValue num_cache[100] = {0};
|
||||||
|
|
||||||
void script_init() {
|
void script_init() {
|
||||||
/* Load all prefabs into memory */
|
/* Load all prefabs into memory */
|
||||||
script_dofile("scripts/engine.js");
|
script_dofile("scripts/engine.js");
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++)
|
||||||
num_cache[i] = int2js(i);
|
num_cache[i] = int2js(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void script_run(const char *script) {
|
void script_run(const char *script) {
|
||||||
|
@ -52,19 +51,17 @@ void script_run(const char *script) {
|
||||||
struct callee stacktrace_callee;
|
struct callee stacktrace_callee;
|
||||||
|
|
||||||
time_t file_mod_secs(const char *file) {
|
time_t file_mod_secs(const char *file) {
|
||||||
struct stat attr;
|
struct stat attr;
|
||||||
stat(file, &attr);
|
stat(file, &attr);
|
||||||
return attr.st_mtime;
|
return attr.st_mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void js_stacktrace()
|
void js_stacktrace() {
|
||||||
{
|
|
||||||
call_callee(&stacktrace_callee);
|
call_callee(&stacktrace_callee);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void js_dump_stack()
|
void js_dump_stack() {
|
||||||
{
|
|
||||||
js_stacktrace();
|
js_stacktrace();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -74,50 +71,48 @@ void js_dump_stack()
|
||||||
if (!JS_IsUndefined(val)) {
|
if (!JS_IsUndefined(val)) {
|
||||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||||
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message"));
|
||||||
const char *stack = JS_ToCString(js, val);
|
const char *stack = JS_ToCString(js, val);
|
||||||
YughError("%s :: %s\n%s", name, msg, stack);
|
YughError("%s :: %s\n%s", name, msg, stack);
|
||||||
|
|
||||||
JS_FreeCString(js, name);
|
JS_FreeCString(js, name);
|
||||||
JS_FreeCString(js, msg);
|
JS_FreeCString(js, msg);
|
||||||
JS_FreeCString(js, stack);
|
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)
|
JS_FreeCString(js, name);
|
||||||
{
|
JS_FreeCString(js, msg);
|
||||||
if (JS_IsException(v)) {
|
JS_FreeCString(js, stack);
|
||||||
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);
|
return 1;
|
||||||
JS_FreeCString(js, msg);
|
}
|
||||||
JS_FreeCString(js, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int script_dofile(const char *file) {
|
int script_dofile(const char *file) {
|
||||||
YughInfo("Doing script %s", file);
|
YughInfo("Doing script %s", file);
|
||||||
const char *script = slurp_text(file);
|
const char *script = slurp_text(file);
|
||||||
if (!script) {
|
if (!script) {
|
||||||
YughError("Can't find file %s.", file);
|
YughError("Can't find file %s.", file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
||||||
js_print_exception(obj);
|
js_print_exception(obj);
|
||||||
JS_FreeValue(js, obj);
|
JS_FreeValue(js, obj);
|
||||||
|
|
||||||
return file_mod_secs(file);
|
return file_mod_secs(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* env is an object in the scripting environment;
|
/* 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);
|
JS_FreeValue(js, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void script_call_sym(JSValue sym)
|
void script_call_sym(JSValue sym) {
|
||||||
{
|
|
||||||
struct callee c;
|
struct callee c;
|
||||||
c.fn = sym;
|
c.fn = sym;
|
||||||
c.obj = JS_GetGlobalObject(js);
|
c.obj = JS_GetGlobalObject(js);
|
||||||
call_callee(&c);
|
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);
|
JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv);
|
||||||
js_print_exception(ret);
|
js_print_exception(ret);
|
||||||
JS_FreeValue(js, ret);
|
JS_FreeValue(js, ret);
|
||||||
|
@ -150,29 +142,25 @@ void call_callee(struct callee *c) {
|
||||||
js_callee_exec(c, 0, NULL);
|
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);
|
JSValue v = num2js(d);
|
||||||
js_callee_exec(&c, 1, &v);
|
js_callee_exec(&c, 1, &v);
|
||||||
JS_FreeValue(js, 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);
|
JSValue v = int2js(i);
|
||||||
js_callee_exec(&c, 1, &v);
|
js_callee_exec(&c, 1, &v);
|
||||||
JS_FreeValue(js, 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);
|
JSValue v = vec2js(vec);
|
||||||
js_callee_exec(&c, 1, &v);
|
js_callee_exec(&c, 1, &v);
|
||||||
JS_FreeValue(js, 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);
|
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); }
|
void call_nk_gui() { js_callee_exec(&nk_gui_callee, 0, NULL); }
|
||||||
|
|
||||||
static struct callee physupdate_callee;
|
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); }
|
void call_physics(double dt) { callee_dbl(physupdate_callee, dt); }
|
||||||
|
|
||||||
struct callee debug_callee;
|
struct callee debug_callee;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
|
||||||
#include "render.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include "font.h"
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "render.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "font.h"
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
|
@ -17,110 +17,104 @@
|
||||||
|
|
||||||
static struct shader *shaders;
|
static struct shader *shaders;
|
||||||
|
|
||||||
struct shader *MakeShader(const char *vertpath, const char *fragpath)
|
struct shader *MakeShader(const char *vertpath, const char *fragpath) {
|
||||||
{
|
if (arrcap(shaders) == 0)
|
||||||
if (arrcap(shaders) == 0)
|
arrsetcap(shaders, 20);
|
||||||
arrsetcap(shaders, 20);
|
|
||||||
|
|
||||||
struct shader init = {
|
struct shader init = {
|
||||||
.vertpath = vertpath,
|
.vertpath = vertpath,
|
||||||
.fragpath = fragpath };
|
.fragpath = fragpath};
|
||||||
shader_compile(&init);
|
shader_compile(&init);
|
||||||
arrput(shaders, init);
|
arrput(shaders, init);
|
||||||
return &arrlast(shaders);
|
return &arrlast(shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
int shader_compile_error(int shader)
|
int shader_compile_error(int shader) {
|
||||||
{
|
/*
|
||||||
/*
|
GLint success = 0;
|
||||||
GLint success = 0;
|
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
|
||||||
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||||
if (success) return 0;
|
if (success) return 0;
|
||||||
|
|
||||||
glGetShaderInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
glGetShaderInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||||
YughLog(0, LOG_ERROR, "Shader compilation error.\nLog: %s", infoLog);
|
YughLog(0, LOG_ERROR, "Shader compilation error.\nLog: %s", infoLog);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int shader_link_error(int shader)
|
int shader_link_error(int shader) {
|
||||||
{
|
/*
|
||||||
/*
|
GLint success = 0;
|
||||||
GLint success = 0;
|
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
||||||
GLchar infoLog[ERROR_BUFFER] = { '\0' };
|
|
||||||
|
|
||||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||||
if (success) return 0;
|
if (success) return 0;
|
||||||
|
|
||||||
glGetProgramInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
glGetProgramInfoLog(shader, ERROR_BUFFER, NULL, infoLog);
|
||||||
YughLog(0, LOG_ERROR, "Shader link error.\nLog: %s", 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)
|
int load_shader_from_file(const char *path, int type) {
|
||||||
{
|
char spath[MAXPATH] = {'\0'};
|
||||||
char spath[MAXPATH] = {'\0'};
|
|
||||||
|
|
||||||
sprintf(spath, "%s%s", "shaders/", path);
|
sprintf(spath, "%s%s", "shaders/", path);
|
||||||
FILE *f = fopen(make_path(spath), "r'");
|
FILE *f = fopen(make_path(spath), "r'");
|
||||||
if (!path)
|
if (!path)
|
||||||
perror(spath), exit(1);
|
perror(spath), exit(1);
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
long int fsize;
|
long int fsize;
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
fsize = ftell(f);
|
fsize = ftell(f);
|
||||||
buf = malloc(fsize+1);
|
buf = malloc(fsize + 1);
|
||||||
rewind(f);
|
rewind(f);
|
||||||
size_t r = fread(buf, sizeof(char), fsize, f);
|
size_t r = fread(buf, sizeof(char), fsize, f);
|
||||||
buf[r] = '\0';
|
buf[r] = '\0';
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GLuint id = glCreateShader(type);
|
GLuint id = glCreateShader(type);
|
||||||
const char *code = buf;
|
const char *code = buf;
|
||||||
glShaderSource(id, 1, &code, NULL);
|
glShaderSource(id, 1, &code, NULL);
|
||||||
glCompileShader(id);
|
glCompileShader(id);
|
||||||
if (shader_compile_error(id)) {
|
if (shader_compile_error(id)) {
|
||||||
YughError("Error with shader %s.", path);
|
YughError("Error with shader %s.", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader_compile(struct shader *shader)
|
void shader_compile(struct shader *shader) {
|
||||||
{
|
YughInfo("Making shader with %s and %s.", shader->vertpath, shader->fragpath);
|
||||||
YughInfo("Making shader with %s and %s.", shader->vertpath, shader->fragpath);
|
char spath[MAXPATH];
|
||||||
char spath[MAXPATH];
|
sprintf(spath, "%s%s", "shaders/", shader->vertpath);
|
||||||
sprintf(spath,"%s%s", "shaders/", shader->vertpath);
|
const char *vsrc = slurp_text(spath);
|
||||||
const char *vsrc = slurp_text(spath);
|
sprintf(spath, "%s%s", "shaders/", shader->fragpath);
|
||||||
sprintf(spath, "%s%s", "shaders/", shader->fragpath);
|
const char *fsrc = slurp_text(spath);
|
||||||
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,
|
.vs.source = vsrc,
|
||||||
.fs.source = fsrc,
|
.fs.source = fsrc,
|
||||||
.label = shader->vertpath,
|
.label = shader->vertpath,
|
||||||
});
|
});
|
||||||
|
|
||||||
free(vsrc);
|
free(vsrc);
|
||||||
free(fsrc);
|
free(fsrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader_use(struct shader *shader)
|
void shader_use(struct shader *shader) {
|
||||||
{
|
// glUseProgram(shader->id);
|
||||||
// glUseProgram(shader->id);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void shader_setbool(struct shader *shader, const char *name, int val)
|
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()
|
void shader_compile_all() {
|
||||||
{
|
for (int i = 0; i < arrlen(shaders); i++)
|
||||||
for (int i = 0; i < arrlen(shaders); i++)
|
shader_compile(&shaders[i]);
|
||||||
shader_compile(&shaders[i]);
|
|
||||||
}
|
}
|
||||||
void shader_setvec3(struct shader *shader, const char *name, mfloat_t val[3])
|
void shader_setvec3(struct shader *shader, const char *name, mfloat_t val[3]) {
|
||||||
{
|
// glUniform3fv(glGetUniformLocation(shader->id, name), 1, val);
|
||||||
// glUniform3fv(glGetUniformLocation(shader->id, name), 1, val);
|
|
||||||
}
|
}
|
||||||
void shader_setmat4(struct shader *shader, const char *name, mfloat_t val[16])
|
void shader_setmat4(struct shader *shader, const char *name, mfloat_t val[16]) {
|
||||||
{
|
// glUniformMatrix4fv(glGetUniformLocation(shader->id, name), 1, GL_FALSE, val);
|
||||||
// glUniformMatrix4fv(glGetUniformLocation(shader->id, name), 1, GL_FALSE, val);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
|
|
||||||
struct shader {
|
struct shader {
|
||||||
sg_shader shd;
|
sg_shader shd;
|
||||||
const char *vertpath;
|
const char *vertpath;
|
||||||
const char *fragpath;
|
const char *fragpath;
|
||||||
};
|
};
|
||||||
|
|
||||||
void shader_compile_all();
|
void shader_compile_all();
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "resources.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "log.h"
|
|
||||||
#include "string.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include "time.h"
|
#include "log.h"
|
||||||
|
#include "math.h"
|
||||||
#include "music.h"
|
#include "music.h"
|
||||||
|
#include "resources.h"
|
||||||
#include "stb_vorbis.h"
|
#include "stb_vorbis.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "samplerate.h"
|
#include "samplerate.h"
|
||||||
|
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
#include "mix.h"
|
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
|
#include "mix.h"
|
||||||
|
|
||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
|
|
||||||
|
@ -25,85 +25,81 @@
|
||||||
#include "tml.h"
|
#include "tml.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *key;
|
char *key;
|
||||||
struct wav *value;
|
struct wav *value;
|
||||||
} *wavhash = NULL;
|
} *wavhash = NULL;
|
||||||
|
|
||||||
static struct wav change_channels(struct wav w, int ch)
|
static struct wav change_channels(struct wav w, int ch) {
|
||||||
{
|
short *data = w.data;
|
||||||
short *data = w.data;
|
int samples = ch * w.frames;
|
||||||
int samples = ch * w.frames;
|
short *new = malloc(sizeof(short) * samples);
|
||||||
short *new = malloc(sizeof(short)*samples);
|
|
||||||
|
|
||||||
if (ch > w.ch) {
|
if (ch > w.ch) {
|
||||||
/* Sets all new channels equal to the first one */
|
/* Sets all new channels equal to the first one */
|
||||||
for (int i = 0; i < w.frames; i++) {
|
for (int i = 0; i < w.frames; i++) {
|
||||||
for (int j = 0; j < ch; j++)
|
for (int j = 0; j < ch; j++)
|
||||||
new[i*ch+j] = data[i];
|
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];
|
|
||||||
}
|
}
|
||||||
|
} 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);
|
free(w.data);
|
||||||
w.data = new;
|
w.data = new;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wav change_samplerate(struct wav w, int rate)
|
static struct wav change_samplerate(struct wav w, int rate) {
|
||||||
{
|
float ratio = (float)rate / w.samplerate;
|
||||||
float ratio = (float)rate/w.samplerate;
|
int outframes = w.frames * ratio;
|
||||||
int outframes = w.frames * ratio;
|
SRC_DATA ssrc;
|
||||||
SRC_DATA ssrc;
|
float floatdata[w.frames * w.ch];
|
||||||
float floatdata[w.frames*w.ch];
|
src_short_to_float_array(w.data, floatdata, w.frames * w.ch);
|
||||||
src_short_to_float_array(w.data, floatdata, w.frames*w.ch);
|
float resampled[w.ch * outframes];
|
||||||
float resampled[w.ch*outframes];
|
|
||||||
|
|
||||||
ssrc.data_in = floatdata;
|
ssrc.data_in = floatdata;
|
||||||
ssrc.data_out = resampled;
|
ssrc.data_out = resampled;
|
||||||
ssrc.input_frames = w.frames;
|
ssrc.input_frames = w.frames;
|
||||||
ssrc.output_frames = outframes;
|
ssrc.output_frames = outframes;
|
||||||
ssrc.src_ratio = ratio;
|
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);
|
short *newdata = malloc(sizeof(short) * outframes * w.ch);
|
||||||
src_float_to_short_array(resampled, newdata, outframes*w.ch);
|
src_float_to_short_array(resampled, newdata, outframes * w.ch);
|
||||||
|
|
||||||
free(w.data);
|
free(w.data);
|
||||||
w.data = newdata;
|
w.data = newdata;
|
||||||
w.samplerate = rate;
|
w.samplerate = rate;
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wav_norm_gain(struct wav *w, double lv)
|
void wav_norm_gain(struct wav *w, double lv) {
|
||||||
{
|
short tarmax = db2short(lv);
|
||||||
short tarmax = db2short(lv);
|
short max = 0;
|
||||||
short max = 0;
|
short *s = w->data;
|
||||||
short *s = w->data;
|
for (int i = 0; i < w->frames; i++) {
|
||||||
for (int i = 0; i < w->frames; i++) {
|
for (int j = 0; j < w->ch; j++) {
|
||||||
for (int j = 0; j < w->ch; j++) {
|
max = (abs(s[i * w->ch + j]) > max) ? abs(s[i * w->ch + j]) : max;
|
||||||
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 i = 0; i < w->frames; i++) {
|
||||||
for (int j = 0; j < w->ch; j++) {
|
for (int j = 0; j < w->ch; j++) {
|
||||||
s[i*w->ch + j] *= mult;
|
s[i * w->ch + j] *= mult;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ma_engine *engine;
|
static ma_engine *engine;
|
||||||
|
|
||||||
void sound_init()
|
void sound_init() {
|
||||||
{
|
|
||||||
ma_result result;
|
ma_result result;
|
||||||
engine = malloc(sizeof(*engine));
|
engine = malloc(sizeof(*engine));
|
||||||
result = ma_engine_init(NULL, engine);
|
result = ma_engine_init(NULL, engine);
|
||||||
|
@ -115,62 +111,57 @@ void sound_init()
|
||||||
mixer_init();
|
mixer_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wav *make_sound(const char *wav)
|
struct wav *make_sound(const char *wav) {
|
||||||
{
|
int index = shgeti(wavhash, wav);
|
||||||
int index = shgeti(wavhash, wav);
|
if (index != -1) return wavhash[index].value;
|
||||||
if (index != -1) return wavhash[index].value;
|
|
||||||
|
|
||||||
struct wav mwav;
|
struct wav mwav;
|
||||||
// mwav.data = drwav_open_file_and_read_pcm_frames_s16(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
// mwav.data = drwav_open_file_and_read_pcm_frames_s16(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||||
|
|
||||||
if (mwav.samplerate != SAMPLERATE) {
|
if (mwav.samplerate != SAMPLERATE) {
|
||||||
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
||||||
// mwav = change_samplerate(mwav, SAMPLERATE);
|
// mwav = change_samplerate(mwav, SAMPLERATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mwav.ch != CHANNELS) {
|
if (mwav.ch != CHANNELS) {
|
||||||
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
||||||
mwav = change_channels(mwav, CHANNELS);
|
mwav = change_channels(mwav, CHANNELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
mwav.gain = 1.f;
|
mwav.gain = 1.f;
|
||||||
|
|
||||||
struct wav *newwav = malloc(sizeof(*newwav));
|
struct wav *newwav = malloc(sizeof(*newwav));
|
||||||
*newwav = mwav;
|
*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)
|
void free_sound(const char *wav) {
|
||||||
{
|
struct wav *w = shget(wavhash, wav);
|
||||||
struct wav *w = shget(wavhash, wav);
|
if (w == NULL) return;
|
||||||
if (w == NULL) return;
|
|
||||||
|
|
||||||
free(w->data);
|
free(w->data);
|
||||||
free(w);
|
free(w);
|
||||||
shdel(wavhash, wav);
|
shdel(wavhash, wav);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct soundstream *soundstream_make()
|
struct soundstream *soundstream_make() {
|
||||||
{
|
struct soundstream *new = malloc(sizeof(*new));
|
||||||
struct soundstream *new = malloc(sizeof(*new));
|
new->buf = circbuf_make(sizeof(short), BUF_FRAMES * CHANNELS * 2);
|
||||||
new->buf = circbuf_make(sizeof(short), BUF_FRAMES*CHANNELS*2);
|
return new;
|
||||||
return new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mini_sound(char *path)
|
void mini_sound(char *path) {
|
||||||
{
|
|
||||||
ma_engine_play_sound(engine, path, NULL);
|
ma_engine_play_sound(engine, path, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ma_sound music_sound;
|
static ma_sound music_sound;
|
||||||
|
|
||||||
void mini_music_play(char *path)
|
void mini_music_play(char *path) {
|
||||||
{
|
|
||||||
ma_sound_uninit(&music_sound);
|
ma_sound_uninit(&music_sound);
|
||||||
int result = ma_sound_init_from_file(engine, path, MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, NULL, &music_sound);
|
int result = ma_sound_init_from_file(engine, path, MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, NULL, &music_sound);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
|
@ -181,163 +172,139 @@ void mini_music_play(char *path)
|
||||||
ma_sound_start(&music_sound);
|
ma_sound_start(&music_sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mini_music_pause()
|
void mini_music_pause() {
|
||||||
{
|
|
||||||
ma_sound_stop(&music_sound);
|
ma_sound_stop(&music_sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mini_music_stop()
|
void mini_music_stop() {
|
||||||
{
|
|
||||||
ma_sound_stop(&music_sound);
|
ma_sound_stop(&music_sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mini_master(float v)
|
void mini_master(float v) {
|
||||||
{
|
|
||||||
ma_engine_set_volume(engine, v);
|
ma_engine_set_volume(engine, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kill_oneshot(struct sound *s)
|
void kill_oneshot(struct sound *s) {
|
||||||
{
|
free(s);
|
||||||
free(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_oneshot(struct wav *wav) {
|
void play_oneshot(struct wav *wav) {
|
||||||
struct sound *new = malloc(sizeof(*new));
|
struct sound *new = malloc(sizeof(*new));
|
||||||
new->data = wav;
|
new->data = wav;
|
||||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||||
new->playing=1;
|
new->playing = 1;
|
||||||
new->loop=0;
|
new->loop = 0;
|
||||||
new->frame = 0;
|
new->frame = 0;
|
||||||
new->endcb = kill_oneshot;
|
new->endcb = kill_oneshot;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sound *play_sound(struct wav *wav)
|
struct sound *play_sound(struct wav *wav) {
|
||||||
{
|
struct sound *new = calloc(1, sizeof(*new));
|
||||||
struct sound *new = calloc(1, sizeof(*new));
|
new->data = wav;
|
||||||
new->data = wav;
|
|
||||||
|
|
||||||
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
|
||||||
new->playing = 1;
|
new->playing = 1;
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sound_playing(const struct sound *s)
|
int sound_playing(const struct sound *s) {
|
||||||
{
|
return s->playing;
|
||||||
return s->playing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sound_paused(const struct sound *s)
|
int sound_paused(const struct sound *s) {
|
||||||
{
|
return (!s->playing && s->frame < s->data->frames);
|
||||||
return (!s->playing && s->frame < s->data->frames);
|
|
||||||
}
|
}
|
||||||
void sound_pause(struct sound *s)
|
void sound_pause(struct sound *s) {
|
||||||
{
|
s->playing = 0;
|
||||||
s->playing = 0;
|
bus_free(s->bus);
|
||||||
bus_free(s->bus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_resume(struct sound *s)
|
void sound_resume(struct sound *s) {
|
||||||
{
|
s->playing = 1;
|
||||||
s->playing = 1;
|
s->bus = first_free_bus(dsp_filter(s, sound_fillbuf));
|
||||||
s->bus = first_free_bus(dsp_filter(s, sound_fillbuf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_stop(struct sound *s)
|
void sound_stop(struct sound *s) {
|
||||||
{
|
s->playing = 0;
|
||||||
s->playing = 0;
|
s->frame = 0;
|
||||||
s->frame = 0;
|
bus_free(s->bus);
|
||||||
bus_free(s->bus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sound_finished(const struct sound *s)
|
int sound_finished(const struct sound *s) {
|
||||||
{
|
return !s->playing && s->frame == s->data->frames;
|
||||||
return !s->playing && s->frame == s->data->frames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sound_stopped(const struct sound *s)
|
int sound_stopped(const struct sound *s) {
|
||||||
{
|
return !s->playing && s->frame == 0;
|
||||||
return !s->playing && s->frame == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mp3 make_music(const char *mp3)
|
struct mp3 make_music(const char *mp3) {
|
||||||
{
|
// drmp3 new;
|
||||||
// drmp3 new;
|
// if (!drmp3_init_file(&new, mp3, NULL)) {
|
||||||
// if (!drmp3_init_file(&new, mp3, NULL)) {
|
// YughError("Could not open mp3 file %s.", mp3);
|
||||||
// YughError("Could not open mp3 file %s.", mp3);
|
// }
|
||||||
// }
|
|
||||||
|
|
||||||
struct mp3 newmp3 = {};
|
struct mp3 newmp3 = {};
|
||||||
return newmp3;
|
return newmp3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_audio_device(int device)
|
void close_audio_device(int device) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int open_device(const char *adriver)
|
int open_device(const char *adriver) {
|
||||||
{
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_fillbuf(struct sound *s, short *buf, int n)
|
void sound_fillbuf(struct sound *s, short *buf, int n) {
|
||||||
{
|
float gainmult = pct2mult(s->data->gain);
|
||||||
float gainmult = pct2mult(s->data->gain);
|
|
||||||
|
|
||||||
short *in = s->data->data;
|
short *in = s->data->data;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
for (int j = 0; j < CHANNELS; j++) buf[i*CHANNELS+j] = in[s->frame+j] * gainmult;
|
for (int j = 0; j < CHANNELS; j++)
|
||||||
s->frame++;
|
buf[i * CHANNELS + j] = in[s->frame + j] * gainmult;
|
||||||
if (s->frame == s->data->frames) {
|
s->frame++;
|
||||||
|
if (s->frame == s->data->frames) {
|
||||||
|
|
||||||
bus_free(s->bus);
|
bus_free(s->bus);
|
||||||
s->bus = NULL;
|
s->bus = NULL;
|
||||||
s->endcb(s);
|
s->endcb(s);
|
||||||
return;
|
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)
|
void soundstream_fillbuf(struct soundstream *s, short *buf, int n) {
|
||||||
{
|
int max = s->buf->write - s->buf->read;
|
||||||
int max = s->buf->write - s->buf->read;
|
int lim = (max < n * CHANNELS) ? max : n * CHANNELS;
|
||||||
int lim = (max < n*CHANNELS) ? max : n*CHANNELS;
|
for (int i = 0; i < lim; i++) {
|
||||||
for (int i = 0; i < lim; i++) {
|
buf[i] = cbuf_shift(s->buf);
|
||||||
buf[i] = cbuf_shift(s->buf);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float short2db(short val)
|
float short2db(short val) {
|
||||||
{
|
return 20 * log10(abs(val) / SHRT_MAX);
|
||||||
return 20*log10(abs(val) / SHRT_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
short db2short(float db)
|
short db2short(float db) {
|
||||||
{
|
return pow(10, db / 20.f) * SHRT_MAX;
|
||||||
return pow(10, db/20.f) * SHRT_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
short short_gain(short val, float db)
|
short short_gain(short val, float db) {
|
||||||
{
|
return (short)(pow(10, db / 20.f) * val);
|
||||||
return (short)(pow(10, db/20.f) * val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float pct2db(float pct)
|
float pct2db(float pct) {
|
||||||
{
|
if (pct <= 0) return -72.f;
|
||||||
if (pct <= 0) return -72.f;
|
|
||||||
|
|
||||||
return 10*log2(pct);
|
return 10 * log2(pct);
|
||||||
}
|
}
|
||||||
|
|
||||||
float pct2mult(float pct)
|
float pct2mult(float pct) {
|
||||||
{
|
if (pct <= 0) return 0.f;
|
||||||
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 "sprite.h"
|
||||||
|
|
||||||
#include "timer.h"
|
|
||||||
#include "render.h"
|
|
||||||
#include "openglrender.h"
|
|
||||||
#include "texture.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "datastream.h"
|
#include "datastream.h"
|
||||||
#include "gameobject.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "stb_ds.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "font.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 struct sprite *sprites;
|
||||||
static int first = -1;
|
static int first = -1;
|
||||||
|
|
||||||
sg_pipeline pip_sprite;
|
static sg_pipeline pip_sprite;
|
||||||
sg_bindings bind_sprite;
|
static sg_bindings bind_sprite;
|
||||||
|
static int sprite_c = 0;
|
||||||
|
|
||||||
int make_sprite(int go)
|
int make_sprite(int go) {
|
||||||
{
|
struct sprite sprite = {
|
||||||
struct sprite sprite = {
|
.color = {1.f, 1.f, 1.f},
|
||||||
.color = {1.f, 1.f, 1.f},
|
.size = {1.f, 1.f},
|
||||||
.size = {1.f, 1.f},
|
.tex = texture_loadfromfile(NULL),
|
||||||
.tex = texture_loadfromfile(NULL),
|
.go = go,
|
||||||
.go = go,
|
.next = -1,
|
||||||
.next = -1,
|
.layer = 0,
|
||||||
.layer = 0,
|
.enabled = 1};
|
||||||
.enabled = 1 };
|
|
||||||
|
|
||||||
if (first<0) {
|
if (first < 0) {
|
||||||
arrput(sprites, sprite);
|
arrput(sprites, sprite);
|
||||||
arrlast(sprites).id = arrlen(sprites)-1;
|
arrlast(sprites).id = arrlen(sprites) - 1;
|
||||||
return arrlen(sprites)-1;
|
return arrlen(sprites) - 1;
|
||||||
} else {
|
} else {
|
||||||
int slot = first;
|
int slot = first;
|
||||||
first = id2sprite(first)->next;
|
first = id2sprite(first)->next;
|
||||||
*id2sprite(slot) = sprite;
|
*id2sprite(slot) = sprite;
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_delete(int id)
|
void sprite_delete(int id) {
|
||||||
{
|
struct sprite *sp = id2sprite(id);
|
||||||
struct sprite *sp = id2sprite(id);
|
sp->go = -1;
|
||||||
sp->go = -1;
|
sp->next = first;
|
||||||
sp->next = first;
|
first = id;
|
||||||
first = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_enabled(int id, int e)
|
void sprite_enabled(int id, int e) {
|
||||||
{
|
sprites[id].enabled = e;
|
||||||
sprites[id].enabled = e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sprite *id2sprite(int id) {
|
struct sprite *id2sprite(int id) {
|
||||||
if (id < 0) return NULL;
|
if (id < 0) return NULL;
|
||||||
return &sprites[id];
|
return &sprites[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
static sprite_count = 0;
|
static sprite_count = 0;
|
||||||
|
|
||||||
void sprite_flush()
|
void sprite_flush() {
|
||||||
{
|
|
||||||
sprite_count = 0;
|
sprite_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_io(struct sprite *sprite, FILE *f, int read)
|
void sprite_io(struct sprite *sprite, FILE *f, int read) {
|
||||||
{
|
char path[100];
|
||||||
char path[100];
|
if (read) {
|
||||||
if (read) {
|
// fscanf(f, "%s", &path);
|
||||||
//fscanf(f, "%s", &path);
|
for (int i = 0; i < 100; i++) {
|
||||||
for (int i = 0; i < 100; i++) {
|
path[i] = fgetc(f);
|
||||||
path[i] = fgetc(f);
|
|
||||||
|
|
||||||
if (path[i] == '\0') break;
|
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);
|
|
||||||
}
|
}
|
||||||
|
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()
|
void sprite_draw_all() {
|
||||||
{
|
sg_apply_pipeline(pip_sprite);
|
||||||
sg_apply_pipeline(pip_sprite);
|
|
||||||
|
|
||||||
static struct sprite **layers[5];
|
static struct sprite **layers[5];
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
arrfree(layers[i]);
|
arrfree(layers[i]);
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(sprites); i++) {
|
for (int i = 0; i < arrlen(sprites); i++) {
|
||||||
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers[sprites[i].layer], &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 i = 4; i >= 0; i--)
|
||||||
for (int j = 0; j < arrlen(layers[i]); j++)
|
for (int j = 0; j < arrlen(layers[i]); j++)
|
||||||
sprite_draw(layers[i][j]);
|
sprite_draw(layers[i][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame)
|
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
|
||||||
{
|
sprite->tex = texture_loadfromfile(path);
|
||||||
sprite->tex = texture_loadfromfile(path);
|
sprite_setframe(sprite, &frame);
|
||||||
sprite_setframe(sprite, &frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_settex(struct sprite *sprite, struct Texture *tex)
|
void sprite_settex(struct sprite *sprite, struct Texture *tex) {
|
||||||
{
|
sprite->tex = tex;
|
||||||
sprite->tex = tex;
|
sprite_setframe(sprite, &ST_UNIT);
|
||||||
sprite_setframe(sprite, &ST_UNIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_shader shader_sprite;
|
sg_shader shader_sprite;
|
||||||
|
|
||||||
void sprite_initialize()
|
void sprite_initialize() {
|
||||||
{
|
shader_sprite = sg_make_shader(&(sg_shader_desc){
|
||||||
shader_sprite = sg_make_shader(&(sg_shader_desc){
|
|
||||||
.vs.source = slurp_text("shaders/spritevert.glsl"),
|
.vs.source = slurp_text("shaders/spritevert.glsl"),
|
||||||
.fs.source = slurp_text("shaders/spritefrag.glsl"),
|
.fs.source = slurp_text("shaders/spritefrag.glsl"),
|
||||||
.vs.uniform_blocks[0] = {
|
.vs.uniform_blocks[0] = {
|
||||||
.size = 64,
|
.size = 64,
|
||||||
.layout = SG_UNIFORMLAYOUT_STD140,
|
.layout = SG_UNIFORMLAYOUT_STD140,
|
||||||
.uniforms = { [0] = { .name = "mpv", .type = SG_UNIFORMTYPE_MAT4 }}
|
.uniforms = {[0] = {.name = "mpv", .type = SG_UNIFORMTYPE_MAT4}}},
|
||||||
},
|
|
||||||
|
|
||||||
.fs.images[0] = {
|
.fs.images[0] = {
|
||||||
.name = "image",
|
.name = "image",
|
||||||
.image_type = SG_IMAGETYPE_2D,
|
.image_type = SG_IMAGETYPE_2D,
|
||||||
.sampler_type = SG_SAMPLERTYPE_FLOAT,
|
.sampler_type = SG_SAMPLERTYPE_FLOAT,
|
||||||
},
|
},
|
||||||
|
|
||||||
.fs.uniform_blocks[0] = {
|
.fs.uniform_blocks[0] = {.size = 12, .uniforms = {[0] = {.name = "spriteColor", .type = SG_UNIFORMTYPE_FLOAT3}}}});
|
||||||
.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,
|
.shader = shader_sprite,
|
||||||
.layout = {
|
.layout = {
|
||||||
.attrs = {
|
.attrs = {
|
||||||
[0].format=SG_VERTEXFORMAT_FLOAT4
|
[0].format = SG_VERTEXFORMAT_FLOAT4}},
|
||||||
}
|
|
||||||
},
|
|
||||||
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||||
.label = "sprite pipeline"
|
.label = "sprite pipeline"});
|
||||||
});
|
|
||||||
|
|
||||||
bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.size = sizeof(float)*16*500,
|
.size = sizeof(float) * 16 * 500,
|
||||||
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||||
.usage = SG_USAGE_STREAM,
|
.usage = SG_USAGE_STREAM,
|
||||||
.label = "sprite vertex buffer",
|
.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]) {
|
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 };
|
float model[16] = {0.f};
|
||||||
mfloat_t r_model[16] = { 0.f };
|
mfloat_t r_model[16] = {0.f};
|
||||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||||
memcpy(r_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_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_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_scale_vec2(model, t_scale);
|
||||||
mat4_rotation_z(r_model, angle);
|
mat4_rotation_z(r_model, angle);
|
||||||
|
|
||||||
mat4_multiply(model, r_model, model);
|
mat4_multiply(model, r_model, model);
|
||||||
|
|
||||||
mat4_translate_vec2(model, pos);
|
mat4_translate_vec2(model, pos);
|
||||||
mat4_multiply(model, projection,model);
|
mat4_multiply(model, projection, model);
|
||||||
|
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
0.f, 0.f, r.s0, r.t1,
|
0.f, 0.f, r.s0, r.t1,
|
||||||
1, 0.f, r.s1, r.t1,
|
1, 0.f, r.s1, r.t1,
|
||||||
0.f, 1, r.s0, r.t0,
|
0.f, 1, r.s0, r.t0,
|
||||||
1.f, 1.f, r.s1, r.t0
|
1.f, 1.f, r.s1, r.t0};
|
||||||
};
|
|
||||||
|
|
||||||
bind_sprite.fs_images[0] = tex->id;
|
bind_sprite.fs_images[0] = tex->id;
|
||||||
sg_append_buffer(bind_sprite.vertex_buffers[0], SG_RANGE_REF(vertices));
|
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_bindings(&bind_sprite);
|
sg_range c = {
|
||||||
|
.ptr = color,
|
||||||
|
.size = sizeof(float) * 3};
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, &c);
|
||||||
|
|
||||||
|
sg_draw(sprite_count * 4, 4, 1);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(model));
|
sprite_count++;
|
||||||
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_draw(sprite_count*4,4,1);
|
|
||||||
sprite_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_draw(struct sprite *sprite)
|
void sprite_draw(struct sprite *sprite) {
|
||||||
{
|
struct gameobject *go = id2go(sprite->go);
|
||||||
struct gameobject *go = id2go(sprite->go);
|
|
||||||
|
|
||||||
if (sprite->tex) {
|
if (sprite->tex) {
|
||||||
cpVect cpos = cpBodyGetPosition(go->body);
|
cpVect cpos = cpBodyGetPosition(go->body);
|
||||||
float pos[2] = {cpos.x, cpos.y};
|
float pos[2] = {cpos.x, cpos.y};
|
||||||
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
|
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);
|
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)
|
void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame) {
|
||||||
{
|
if (!sprite) return;
|
||||||
if (!sprite) return;
|
sprite->tex = anim->tex;
|
||||||
sprite->tex = anim->tex;
|
sprite->frame = anim->st_frames[frame];
|
||||||
sprite->frame = anim->st_frames[frame];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_draw_img(const char *img, float x, float y) {
|
void gui_draw_img(const char *img, float x, float y) {
|
||||||
sg_apply_pipeline(pip_sprite);
|
sg_apply_pipeline(pip_sprite);
|
||||||
struct Texture *tex = texture_loadfromfile(img);
|
struct Texture *tex = texture_loadfromfile(img);
|
||||||
float pos[2] = {x, y};
|
float pos[2] = {x, y};
|
||||||
float size[2] = {1.f, 1.f};
|
float size[2] = {1.f, 1.f};
|
||||||
float offset[2] = { 0.f, 0.f };
|
float offset[2] = {0.f, 0.f};
|
||||||
float white[3] = {0.3f,1.f,1.f};
|
float white[3] = {1.f, 1.f, 1.f};
|
||||||
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
|
tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), white);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_setframe(struct sprite *sprite, struct glrect *frame)
|
void sprite_setframe(struct sprite *sprite, struct glrect *frame) {
|
||||||
{
|
sprite->frame = *frame;
|
||||||
sprite->frame = *frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3])
|
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3]) {
|
||||||
{
|
shader_use(vid_shader);
|
||||||
shader_use(vid_shader);
|
|
||||||
|
|
||||||
static mfloat_t model[16];
|
static mfloat_t model[16];
|
||||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||||
mat4_translate_vec2(model, position);
|
mat4_translate_vec2(model, position);
|
||||||
mat4_scale_vec2(model, size);
|
mat4_scale_vec2(model, size);
|
||||||
|
|
||||||
shader_setmat4(vid_shader, "model", model);
|
shader_setmat4(vid_shader, "model", model);
|
||||||
shader_setvec3(vid_shader, "spriteColor", color);
|
shader_setvec3(vid_shader, "spriteColor", color);
|
||||||
/*
|
/*
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, stream->texture_y);
|
glBindTexture(GL_TEXTURE_2D, stream->texture_y);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cb);
|
glBindTexture(GL_TEXTURE_2D, stream->texture_cb);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_2D, stream->texture_cr);
|
glBindTexture(GL_TEXTURE_2D, stream->texture_cr);
|
||||||
|
|
||||||
// TODO: video bind VAO
|
// TODO: video bind VAO
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,208 +1,184 @@
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
#include "render.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stb_image.h>
|
|
||||||
#include <stb_ds.h>
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <math.h>
|
#include "render.h"
|
||||||
#include "util.h"
|
|
||||||
#include "sokol/sokol_gfx.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 {
|
static struct {
|
||||||
char *key;
|
char *key;
|
||||||
struct Texture *value;
|
struct Texture *value;
|
||||||
} *texhash = NULL;
|
} *texhash = NULL;
|
||||||
|
|
||||||
struct Texture *tex_default;
|
struct Texture *tex_default;
|
||||||
|
|
||||||
struct Texture *texture_notex()
|
struct Texture *texture_notex() {
|
||||||
{
|
|
||||||
return texture_pullfromfile("./icons/no_tex.png");
|
return texture_pullfromfile("./icons/no_tex.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If an empty string or null is put for path, loads default texture */
|
/* If an empty string or null is put for path, loads default texture */
|
||||||
struct Texture *texture_pullfromfile(const char *path)
|
struct Texture *texture_pullfromfile(const char *path) {
|
||||||
{
|
if (!path) return texture_notex();
|
||||||
if (!path) return texture_notex();
|
|
||||||
|
|
||||||
int index = shgeti(texhash, path);
|
int index = shgeti(texhash, path);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
return texhash[index].value;
|
return texhash[index].value;
|
||||||
|
|
||||||
YughInfo("Loading texture %s.", path);
|
YughInfo("Loading texture %s.", path);
|
||||||
struct Texture *tex = calloc(1, sizeof(*tex));
|
struct Texture *tex = calloc(1, sizeof(*tex));
|
||||||
tex->opts.sprite = 1;
|
tex->opts.sprite = 1;
|
||||||
tex->opts.mips = 0;
|
tex->opts.mips = 0;
|
||||||
tex->opts.gamma = 0;
|
tex->opts.gamma = 0;
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
||||||
return texture_notex();
|
return texture_notex();
|
||||||
}
|
}
|
||||||
tex->data = data;
|
tex->data = data;
|
||||||
|
|
||||||
int filter;
|
int filter;
|
||||||
if (tex->opts.sprite) {
|
if (tex->opts.sprite) {
|
||||||
if (tex->opts.mips)
|
filter = SG_FILTER_NEAREST;
|
||||||
filter = SG_FILTER_NEAREST_MIPMAP_NEAREST;
|
} else {
|
||||||
else
|
filter = SG_FILTER_LINEAR;
|
||||||
filter = SG_FILTER_NEAREST;
|
}
|
||||||
} else {
|
|
||||||
if (tex->opts.mips)
|
|
||||||
filter = SG_FILTER_LINEAR_MIPMAP_LINEAR;
|
|
||||||
else
|
|
||||||
filter = SG_FILTER_LINEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
tex->id = sg_make_image(&(sg_image_desc){
|
tex->id = sg_make_image(&(sg_image_desc){
|
||||||
.type = SG_IMAGETYPE_2D,
|
.type = SG_IMAGETYPE_2D,
|
||||||
.width = tex->width,
|
.width = tex->width,
|
||||||
.height = tex->height,
|
.height = tex->height,
|
||||||
.usage = SG_USAGE_IMMUTABLE,
|
.usage = SG_USAGE_IMMUTABLE,
|
||||||
.min_filter = filter,
|
.min_filter = filter,
|
||||||
.mag_filter = filter,
|
.mag_filter = filter,
|
||||||
|
.max_anisotropy = 16,
|
||||||
.data.subimage[0][0] = {
|
.data.subimage[0][0] = {
|
||||||
.ptr = data,
|
.ptr = data,
|
||||||
.size = tex->width*tex->height*4
|
.size = tex->width * tex->height * 4}});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
if (shlen(texhash) == 0)
|
||||||
|
sh_new_arena(texhash);
|
||||||
|
|
||||||
if (shlen(texhash) == 0)
|
shput(texhash, path, tex);
|
||||||
sh_new_arena(texhash);
|
|
||||||
|
|
||||||
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.");
|
YughWarn("Need to implement texture sync.");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *tex_get_path(struct Texture *tex) {
|
char *tex_get_path(struct Texture *tex) {
|
||||||
for (int i = 0; i < shlen(texhash); i++) {
|
for (int i = 0; i < shlen(texhash); i++) {
|
||||||
if (tex == texhash[i].value) {
|
if (tex == texhash[i].value) {
|
||||||
YughInfo("Found key %s", texhash[i].key);
|
YughInfo("Found key %s", texhash[i].key);
|
||||||
return texhash[i].key;
|
return texhash[i].key;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Texture *texture_loadfromfile(const char *path)
|
struct Texture *texture_loadfromfile(const char *path) {
|
||||||
{
|
struct Texture *new = texture_pullfromfile(path);
|
||||||
struct Texture *new = texture_pullfromfile(path);
|
/*
|
||||||
/*
|
if (new->id == 0) {
|
||||||
if (new->id == 0) {
|
glGenTextures(1, &new->id);
|
||||||
glGenTextures(1, &new->id);
|
|
||||||
|
|
||||||
//tex_gpu_load(new);
|
//tex_gpu_load(new);
|
||||||
|
|
||||||
YughInfo("Loaded texture path %s", path);
|
YughInfo("Loaded texture path %s", path);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_gpu_reload(struct Texture *tex)
|
void tex_gpu_reload(struct Texture *tex) {
|
||||||
{
|
tex_gpu_free(tex);
|
||||||
tex_gpu_free(tex);
|
|
||||||
|
|
||||||
//tex_gpu_load(tex);
|
// tex_gpu_load(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_calc(struct anim2d *anim)
|
void anim_calc(struct anim2d *anim) {
|
||||||
{
|
anim->size[0] = anim->anim->tex->width * st_s_w(anim->anim->st_frames[anim->frame]);
|
||||||
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]);
|
||||||
anim->size[1] = anim->anim->tex->height * st_s_h(anim->anim->st_frames[anim->frame]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_incr(struct anim2d *anim)
|
void anim_incr(struct anim2d *anim) {
|
||||||
{
|
anim->frame = (anim->frame + 1) % arrlen(anim->anim->st_frames);
|
||||||
anim->frame = (anim->frame + 1) % arrlen(anim->anim->st_frames);
|
|
||||||
|
|
||||||
if (!anim->anim->loop && anim->frame == arrlen(anim->anim->st_frames))
|
if (!anim->anim->loop && anim->frame == arrlen(anim->anim->st_frames))
|
||||||
anim_pause(anim);
|
anim_pause(anim);
|
||||||
|
|
||||||
anim_calc(anim);
|
anim_calc(anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_decr(struct anim2d *anim)
|
void anim_decr(struct anim2d *anim) {
|
||||||
{
|
anim->frame = (anim->frame + arrlen(anim->anim->st_frames) - 1) % arrlen(anim->anim->st_frames);
|
||||||
anim->frame = (anim->frame + arrlen(anim->anim->st_frames) - 1) % arrlen(anim->anim->st_frames);
|
anim_calc(anim);
|
||||||
anim_calc(anim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct glrect anim_get_rect(struct anim2d *anim)
|
struct glrect anim_get_rect(struct anim2d *anim) {
|
||||||
{
|
return anim->anim->st_frames[anim->frame];
|
||||||
return anim->anim->st_frames[anim->frame];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_setframe(struct anim2d *anim, int frame)
|
void anim_setframe(struct anim2d *anim, int frame) {
|
||||||
{
|
anim->frame = frame;
|
||||||
anim->frame = frame;
|
anim_calc(anim);
|
||||||
anim_calc(anim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps)
|
struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps) {
|
||||||
{
|
struct TexAnim *anim = malloc(sizeof(*anim));
|
||||||
struct TexAnim *anim = malloc(sizeof(*anim));
|
anim->tex = texture_loadfromfile(path);
|
||||||
anim->tex = texture_loadfromfile(path);
|
texanim_fromframes(anim, frames);
|
||||||
texanim_fromframes(anim, frames);
|
anim->ms = (float)1 / fps;
|
||||||
anim->ms = (float)1/fps;
|
|
||||||
|
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
void texanim_fromframes(struct TexAnim *anim, int frames)
|
void texanim_fromframes(struct TexAnim *anim, int frames) {
|
||||||
{
|
if (anim->st_frames) {
|
||||||
if (anim->st_frames) {
|
free(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++) {
|
for (int i = 0; i < frames; i++) {
|
||||||
anim->st_frames[i].s0 = width*i;
|
anim->st_frames[i].s0 = width * i;
|
||||||
anim->st_frames[i].s1 = width*(i+1);
|
anim->st_frames[i].s1 = width * (i + 1);
|
||||||
anim->st_frames[i].t0 = 0.f;
|
anim->st_frames[i].t0 = 0.f;
|
||||||
anim->st_frames[i].t1 = 1.f;
|
anim->st_frames[i].t1 = 1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_gpu_free(struct Texture *tex)
|
void tex_gpu_free(struct Texture *tex) {
|
||||||
{
|
/*
|
||||||
/*
|
if (tex->id != 0) {
|
||||||
if (tex->id != 0) {
|
glDeleteTextures(1, &tex->id);
|
||||||
glDeleteTextures(1, &tex->id);
|
tex->id = 0;
|
||||||
tex->id = 0;
|
}
|
||||||
}
|
*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int anim_frames(struct TexAnim *a)
|
int anim_frames(struct TexAnim *a) {
|
||||||
{
|
return arrlen(a->st_frames);
|
||||||
return arrlen(a->st_frames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct glrect tex_get_rect(struct Texture *tex)
|
struct glrect tex_get_rect(struct Texture *tex) {
|
||||||
{
|
return ST_UNIT;
|
||||||
return ST_UNIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpVect tex_get_dimensions(struct Texture *tex)
|
cpVect tex_get_dimensions(struct Texture *tex) {
|
||||||
{
|
|
||||||
if (!tex) return cpvzero;
|
if (!tex) return cpvzero;
|
||||||
cpVect d;
|
cpVect d;
|
||||||
d.x = tex->width;
|
d.x = tex->width;
|
||||||
|
@ -210,78 +186,69 @@ cpVect tex_get_dimensions(struct Texture *tex)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tex_bind(struct Texture *tex)
|
void tex_bind(struct Texture *tex) {
|
||||||
{
|
/* glActiveTexture(GL_TEXTURE0);
|
||||||
/* glActiveTexture(GL_TEXTURE0);
|
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, tex->id);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex->id);
|
*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** ANIM2D ****************/
|
/********************** ANIM2D ****************/
|
||||||
|
|
||||||
void anim_load(struct anim2d *anim, const char *path)
|
void anim_load(struct anim2d *anim, const char *path) {
|
||||||
{
|
anim->anim = &texture_pullfromfile(path)->anim;
|
||||||
anim->anim = &texture_pullfromfile(path)->anim;
|
anim->anim->tex->opts.animation = 1;
|
||||||
anim->anim->tex->opts.animation = 1;
|
anim_stop(anim);
|
||||||
anim_stop(anim);
|
anim_play(anim);
|
||||||
anim_play(anim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_play(struct anim2d *anim)
|
void anim_play(struct anim2d *anim) {
|
||||||
{
|
if (anim->playing)
|
||||||
if (anim->playing)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (anim->frame == anim_frames(anim->anim))
|
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;
|
|
||||||
anim->frame = 0;
|
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)
|
void anim_stop(struct anim2d *anim) {
|
||||||
{
|
if (!anim->playing)
|
||||||
if (!anim->playing)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
anim->playing = 0;
|
anim->playing = 0;
|
||||||
timer_pause(anim->timer);
|
anim->frame = 0;
|
||||||
|
anim->pausetime = 0;
|
||||||
|
timer_stop(anim->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_fwd(struct anim2d *anim)
|
void anim_pause(struct anim2d *anim) {
|
||||||
{
|
if (!anim->playing)
|
||||||
anim_incr(anim);
|
return;
|
||||||
|
|
||||||
|
anim->playing = 0;
|
||||||
|
timer_pause(anim->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim_bkwd(struct anim2d *anim)
|
void anim_fwd(struct anim2d *anim) {
|
||||||
{
|
anim_incr(anim);
|
||||||
anim_decr(anim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float st_s_w(struct glrect st)
|
void anim_bkwd(struct anim2d *anim) {
|
||||||
{
|
anim_decr(anim);
|
||||||
return (st.s1 - st.s0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float st_s_h(struct glrect st)
|
float st_s_w(struct glrect st) {
|
||||||
{
|
return (st.s1 - st.s0);
|
||||||
return (st.t1 - st.t0);
|
}
|
||||||
|
|
||||||
|
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)
|
#elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
|
||||||
#define NK_SIZE_TYPE unsigned __int32
|
#define NK_SIZE_TYPE unsigned __int32
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
#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
|
#define NK_SIZE_TYPE unsigned long
|
||||||
#else
|
#else
|
||||||
#define NK_SIZE_TYPE unsigned int
|
#define NK_SIZE_TYPE unsigned int
|
||||||
|
@ -387,7 +387,7 @@ extern "C" {
|
||||||
#elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
|
#elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
|
||||||
#define NK_POINTER_TYPE unsigned __int32
|
#define NK_POINTER_TYPE unsigned __int32
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
#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
|
#define NK_POINTER_TYPE unsigned long
|
||||||
#else
|
#else
|
||||||
#define NK_POINTER_TYPE unsigned int
|
#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_byte) == 1);
|
||||||
NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
|
NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
|
||||||
NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
|
NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
|
||||||
//NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
|
NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
|
||||||
//NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
|
NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
|
||||||
#ifdef NK_INCLUDE_STANDARD_BOOL
|
#ifdef NK_INCLUDE_STANDARD_BOOL
|
||||||
NK_STATIC_ASSERT(sizeof(nk_bool) == sizeof(bool));
|
NK_STATIC_ASSERT(sizeof(nk_bool) == sizeof(bool));
|
||||||
#else
|
#else
|
||||||
|
@ -1127,7 +1127,7 @@ NK_API void nk_input_end(struct nk_context*);
|
||||||
/// cfg.curve_segment_count = 22;
|
/// cfg.curve_segment_count = 22;
|
||||||
/// cfg.arc_segment_count = 22;
|
/// cfg.arc_segment_count = 22;
|
||||||
/// cfg.global_alpha = 1.0f;
|
/// cfg.global_alpha = 1.0f;
|
||||||
/// cfg.null = dev->null;
|
/// cfg.tex_null = dev->tex_null;
|
||||||
/// //
|
/// //
|
||||||
/// // setup buffers and convert
|
/// // setup buffers and convert
|
||||||
/// struct nk_buffer cmds, verts, idx;
|
/// 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 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 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 */
|
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 */
|
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_size; /* sizeof one vertex for vertex packing */
|
||||||
nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
|
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_RECT_PACK_IMPLEMENTATION
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
#define STBTT_STATIC
|
|
||||||
|
|
||||||
/* Allow consumer to define own STBTT_malloc/STBTT_free, and use the font atlas' allocator otherwise */
|
/* Allow consumer to define own STBTT_malloc/STBTT_free, and use the font atlas' allocator otherwise */
|
||||||
#ifndef STBTT_malloc
|
#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_API int
|
||||||
nk_str_append_str_utf8(struct nk_str *str, const char *text)
|
nk_str_append_str_utf8(struct nk_str *str, const char *text)
|
||||||
{
|
{
|
||||||
int runes = 0;
|
|
||||||
int byte_len = 0;
|
int byte_len = 0;
|
||||||
int num_runes = 0;
|
int num_runes = 0;
|
||||||
int glyph_len = 0;
|
int glyph_len = 0;
|
||||||
|
@ -8454,7 +8452,7 @@ nk_str_append_str_utf8(struct nk_str *str, const char *text)
|
||||||
num_runes++;
|
num_runes++;
|
||||||
}
|
}
|
||||||
nk_str_append_text_char(str, text, byte_len);
|
nk_str_append_text_char(str, text, byte_len);
|
||||||
return runes;
|
return num_runes;
|
||||||
}
|
}
|
||||||
NK_API int
|
NK_API int
|
||||||
nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
|
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_API int
|
||||||
nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
|
nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
|
||||||
{
|
{
|
||||||
int runes = 0;
|
|
||||||
int byte_len = 0;
|
int byte_len = 0;
|
||||||
int num_runes = 0;
|
int num_runes = 0;
|
||||||
int glyph_len = 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++;
|
num_runes++;
|
||||||
}
|
}
|
||||||
nk_str_insert_at_rune(str, pos, text, byte_len);
|
nk_str_insert_at_rune(str, pos, text, byte_len);
|
||||||
return runes;
|
return num_runes;
|
||||||
}
|
}
|
||||||
NK_API int
|
NK_API int
|
||||||
nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
|
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);
|
NK_ASSERT(list);
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
if (!list->cmd_count) {
|
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 {
|
} else {
|
||||||
struct nk_draw_command *prev = nk_draw_list_command_last(list);
|
struct nk_draw_command *prev = nk_draw_list_command_last(list);
|
||||||
if (prev->elem_count == 0)
|
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 */
|
/* fill vertices */
|
||||||
for (i = 0; i < points_count; ++i) {
|
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, 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+0], uv, col_trans);
|
||||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], 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 */
|
/* add vertices */
|
||||||
for (i = 0; i < points_count; ++i) {
|
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+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+1], uv, col);
|
||||||
vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], 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) {
|
for (i1 = 0; i1 < count; ++i1) {
|
||||||
float dx, dy;
|
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 nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
|
||||||
const struct nk_vec2 p1 = points[i1];
|
const struct nk_vec2 p1 = points[i1];
|
||||||
const struct nk_vec2 p2 = points[i2];
|
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 */
|
/* add vertices + indexes */
|
||||||
for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
|
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 n0 = normals[i0];
|
||||||
struct nk_vec2 n1 = normals[i1];
|
struct nk_vec2 n1 = normals[i1];
|
||||||
struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
|
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;
|
if (!vtx || !ids) return;
|
||||||
for (i = 0; i < vtx_count; ++i)
|
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) {
|
for (i = 2; i < points_count; ++i) {
|
||||||
ids[0] = (nk_draw_index)index;
|
ids[0] = (nk_draw_index)index;
|
||||||
ids[1] = (nk_draw_index)(index+ i - 1);
|
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);
|
nk_draw_list_add_clip(list, nk_null_rect);
|
||||||
|
|
||||||
cmd = nk_draw_list_command_last(list);
|
cmd = nk_draw_list_command_last(list);
|
||||||
if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
|
if (cmd && cmd->texture.ptr != list->config.tex_null.texture.ptr)
|
||||||
nk_draw_list_push_image(list, list->config.null.texture);
|
nk_draw_list_push_image(list, list->config.tex_null.texture);
|
||||||
|
|
||||||
points = nk_draw_list_alloc_path(list, 1);
|
points = nk_draw_list_alloc_path(list, 1);
|
||||||
if (!points) return;
|
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);
|
NK_ASSERT(list);
|
||||||
if (!list) return;
|
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;
|
index = (nk_draw_index)list->vertex_count;
|
||||||
vtx = nk_draw_list_alloc_vertices(list, 4);
|
vtx = nk_draw_list_alloc_vertices(list, 4);
|
||||||
idx = nk_draw_list_alloc_elements(list, 6);
|
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[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);
|
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.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.null.uv, col_top);
|
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.null.uv, col_right);
|
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.null.uv, col_bottom);
|
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_API void
|
||||||
nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
|
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,
|
0x3000, 0x30FF,
|
||||||
0x31F0, 0x31FF,
|
0x31F0, 0x31FF,
|
||||||
0xFF00, 0xFFEF,
|
0xFF00, 0xFFEF,
|
||||||
0x4e00, 0x9FAF,
|
0x4E00, 0x9FAF,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
return ranges;
|
return ranges;
|
||||||
|
@ -16622,7 +16619,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
|
||||||
struct stbtt_fontinfo *font_info = &baker->build[i++].info;
|
struct stbtt_fontinfo *font_info = &baker->build[i++].info;
|
||||||
font_info->userdata = alloc;
|
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;
|
return nk_false;
|
||||||
} while ((it = it->n) != config_iter);
|
} while ((it = it->n) != config_iter);
|
||||||
}
|
}
|
||||||
|
@ -17704,20 +17701,20 @@ failed:
|
||||||
}
|
}
|
||||||
NK_API void
|
NK_API void
|
||||||
nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
|
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;
|
int i = 0;
|
||||||
struct nk_font *font_iter;
|
struct nk_font *font_iter;
|
||||||
NK_ASSERT(atlas);
|
NK_ASSERT(atlas);
|
||||||
if (!atlas) {
|
if (!atlas) {
|
||||||
if (!null) return;
|
if (!tex_null) return;
|
||||||
null->texture = texture;
|
tex_null->texture = texture;
|
||||||
null->uv = nk_vec2(0.5f,0.5f);
|
tex_null->uv = nk_vec2(0.5f,0.5f);
|
||||||
}
|
}
|
||||||
if (null) {
|
if (tex_null) {
|
||||||
null->texture = texture;
|
tex_null->texture = texture;
|
||||||
null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
|
tex_null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
|
||||||
null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
|
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) {
|
for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
|
||||||
font_iter->texture = texture;
|
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))
|
text+text_len, 1))
|
||||||
{
|
{
|
||||||
nk_textedit_makeundo_insert(state, state->cursor, 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;
|
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
|
/// - [y]: Minor version with non-breaking API and library changes
|
||||||
/// - [z]: Patch version with no direct changes to the API
|
/// - [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/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
|
/// - 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
|
/// 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 "timer.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
|
|
||||||
struct timer *timers;
|
struct timer *timers;
|
||||||
static int first = -1;
|
static int first = -1;
|
||||||
|
|
||||||
void check_timer(struct timer *t, double dt)
|
void check_timer(struct timer *t, double dt) {
|
||||||
{
|
if (!t->on)
|
||||||
if (!t->on)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
t->remain_time -= dt;
|
t->remain_time -= dt;
|
||||||
|
|
||||||
if (t->remain_time <= 0) {
|
if (t->remain_time <= 0) {
|
||||||
t->cb(t->data);
|
t->cb(t->data);
|
||||||
if (t->repeat) {
|
if (t->repeat) {
|
||||||
t->remain_time = t->interval;
|
t->remain_time = t->interval;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
timer_pause(t);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer_pause(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_update(double dt) {
|
void timer_update(double dt) {
|
||||||
for (int i = 0; i < arrlen(timers); i++)
|
for (int i = 0; i < arrlen(timers); i++)
|
||||||
check_timer(&timers[i], dt);
|
check_timer(&timers[i], dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_make(double interval, void (*callback)(void *param), void *param, int own) {
|
int timer_make(double interval, void (*callback)(void *param), void *param, int own) {
|
||||||
struct timer new;
|
struct timer new;
|
||||||
new.remain_time = interval;
|
new.remain_time = interval;
|
||||||
new.interval = interval;
|
new.interval = interval;
|
||||||
new.cb = callback;
|
new.cb = callback;
|
||||||
new.data = param;
|
new.data = param;
|
||||||
new.repeat = 1;
|
new.repeat = 1;
|
||||||
new.owndata = own;
|
new.owndata = own;
|
||||||
new.next = -1;
|
new.next = -1;
|
||||||
|
|
||||||
if (first < 0) {
|
if (first < 0) {
|
||||||
timer_start(&new);
|
timer_start(&new);
|
||||||
arrput(timers, new);
|
arrput(timers, new);
|
||||||
return arrlen(timers)-1;
|
return arrlen(timers) - 1;
|
||||||
} else {
|
} else {
|
||||||
int retid = first;
|
int retid = first;
|
||||||
first = id2timer(first)->next;
|
first = id2timer(first)->next;
|
||||||
*id2timer(retid) = new;
|
*id2timer(retid) = new;
|
||||||
timer_start(id2timer(retid));
|
timer_start(id2timer(retid));
|
||||||
return retid;
|
return retid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_pause(struct timer *t) {
|
void timer_pause(struct timer *t) {
|
||||||
if (!t->on) return;
|
if (!t->on) return;
|
||||||
t->on = 0;
|
t->on = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_stop(struct timer *t) {
|
void timer_stop(struct timer *t) {
|
||||||
if (!t->on) return;
|
if (!t->on) return;
|
||||||
t->on = 0;
|
t->on = 0;
|
||||||
t->remain_time = t->interval;
|
t->remain_time = t->interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_start(struct timer *t) {
|
void timer_start(struct timer *t) {
|
||||||
if (t->on) return;
|
if (t->on) return;
|
||||||
t->on = 1;
|
t->on = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_remove(int id) {
|
void timer_remove(int id) {
|
||||||
struct timer *t = id2timer(id);
|
struct timer *t = id2timer(id);
|
||||||
if (t->owndata) free(t->data);
|
if (t->owndata) free(t->data);
|
||||||
t->next = first;
|
t->next = first;
|
||||||
first = id;
|
first = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerr_settime(struct timer *t, double interval) {
|
void timerr_settime(struct timer *t, double interval) {
|
||||||
t->remain_time += (interval - t->interval);
|
t->remain_time += (interval - t->interval);
|
||||||
t->interval = interval;
|
t->interval = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timer *id2timer(int id)
|
struct timer *id2timer(int id) {
|
||||||
{
|
return &timers[id];
|
||||||
return &timers[id];
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,52 +1,44 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[4], float scale)
|
struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[4], float scale) {
|
||||||
{
|
struct mTransform newT;
|
||||||
struct mTransform newT;
|
memcpy(newT.position, pos, sizeof(*pos));
|
||||||
memcpy(newT.position, pos, sizeof(*pos));
|
memcpy(newT.rotation, rotation, sizeof(*rotation));
|
||||||
memcpy(newT.rotation, rotation, sizeof(*rotation));
|
newT.scale = scale;
|
||||||
newT.scale = scale;
|
return newT;
|
||||||
return newT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_forward(mfloat_t * res,
|
mfloat_t *trans_forward(mfloat_t *res,
|
||||||
const struct mTransform *const trans)
|
const struct mTransform *const trans) {
|
||||||
{
|
// YughLog(0, SDL_LOG_PRIORITY_WARN, "Rotation is %f", trans->rotation[0]);
|
||||||
// YughLog(0, SDL_LOG_PRIORITY_WARN, "Rotation is %f", trans->rotation[0]);
|
return vec3_rotate_quat(res, FORWARD, trans->rotation);
|
||||||
return vec3_rotate_quat(res, FORWARD, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_back(mfloat_t * res, const struct mTransform *trans)
|
mfloat_t *trans_back(mfloat_t *res, const struct mTransform *trans) {
|
||||||
{
|
return vec3_rotate_quat(res, BACK, trans->rotation);
|
||||||
return vec3_rotate_quat(res, BACK, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_up(mfloat_t * res, const struct mTransform *trans)
|
mfloat_t *trans_up(mfloat_t *res, const struct mTransform *trans) {
|
||||||
{
|
return vec3_rotate_quat(res, UP, trans->rotation);
|
||||||
return vec3_rotate_quat(res, UP, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_down(mfloat_t * res, const struct mTransform *trans)
|
mfloat_t *trans_down(mfloat_t *res, const struct mTransform *trans) {
|
||||||
{
|
return vec3_rotate_quat(res, DOWN, trans->rotation);
|
||||||
return vec3_rotate_quat(res, DOWN, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_right(mfloat_t * res, const struct mTransform *trans)
|
mfloat_t *trans_right(mfloat_t *res, const struct mTransform *trans) {
|
||||||
{
|
return vec3_rotate_quat(res, RIGHT, trans->rotation);
|
||||||
return vec3_rotate_quat(res, RIGHT, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfloat_t *trans_left(mfloat_t * res, const struct mTransform *trans)
|
mfloat_t *trans_left(mfloat_t *res, const struct mTransform *trans) {
|
||||||
{
|
return vec3_rotate_quat(res, LEFT, trans->rotation);
|
||||||
return vec3_rotate_quat(res, LEFT, trans->rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "nuke.h"
|
#include "nuke.h"
|
||||||
|
|
||||||
void trans_drawgui(struct mTransform *T)
|
void trans_drawgui(struct mTransform *T) {
|
||||||
{
|
nuke_property_float3("Position", -1000.f, T->position, 1000.f, 1.f, 1.f);
|
||||||
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_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);
|
||||||
nuke_property_float("Scale", 0.f, &T->scale, 1000.f, 0.1f, 0.1f);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include <string.h>
|
|
||||||
#include "texture.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "script.h"
|
#include "log.h"
|
||||||
#include "nuke.h"
|
#include "nuke.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "openglrender.h"
|
#include "openglrender.h"
|
||||||
|
|
||||||
|
@ -18,277 +18,248 @@ static struct window *windows = NULL;
|
||||||
|
|
||||||
struct Texture *icon = NULL;
|
struct Texture *icon = NULL;
|
||||||
|
|
||||||
int is_win(struct window *s, GLFWwindow *w)
|
int is_win(struct window *s, GLFWwindow *w) {
|
||||||
{
|
return s->window == 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)
|
struct window *winfind(GLFWwindow *w) {
|
||||||
{
|
for (int i = 0; i < arrlen(windows); i++) {
|
||||||
for (int i = 0; i < arrlen(windows); i++) {
|
if (windows[i].window == w)
|
||||||
if (windows[i].window == w)
|
return &windows[i];
|
||||||
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;
|
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)
|
void window_set_icon(const char *png) {
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
icon = texture_pullfromfile(png);
|
icon = texture_pullfromfile(png);
|
||||||
window_seticon(mainwin, icon);
|
window_seticon(mainwin, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_destroy(struct window *w)
|
void window_destroy(struct window *w) {
|
||||||
{
|
glfwDestroyWindow(w->window);
|
||||||
glfwDestroyWindow(w->window);
|
arrdelswap(windows, w->id);
|
||||||
arrdelswap(windows, w->id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct window *window_i(int index) {
|
struct window *window_i(int index) {
|
||||||
return &windows[index];
|
return &windows[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_handle_event(struct window *w)
|
void window_handle_event(struct window *w) {
|
||||||
{
|
/*
|
||||||
/*
|
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
|
||||||
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
|
switch (e->window.event) {
|
||||||
switch (e->window.event) {
|
case SDL_WINDOWEVENT_SHOWN:
|
||||||
case SDL_WINDOWEVENT_SHOWN:
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
|
w->shown = true;
|
||||||
w->shown = true;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_HIDDEN:
|
case SDL_WINDOWEVENT_HIDDEN:
|
||||||
w->shown = false;
|
w->shown = false;
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
|
|
||||||
w->width = e->window.data1;
|
w->width = e->window.data1;
|
||||||
w->height = e->window.data2;
|
w->height = e->window.data2;
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Changed size of window %d: width %d, height %d.",
|
"Changed size of window %d: width %d, height %d.",
|
||||||
w->id, w->width, w->height);
|
w->id, w->width, w->height);
|
||||||
window_makecurrent(w);
|
window_makecurrent(w);
|
||||||
w->render = true;
|
w->render = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
|
||||||
w->render = true;
|
w->render = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_ENTER:
|
case SDL_WINDOWEVENT_ENTER:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
|
||||||
w->mouseFocus = true;
|
w->mouseFocus = true;
|
||||||
SDL_RaiseWindow(w->window);
|
SDL_RaiseWindow(w->window);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_LEAVE:
|
case SDL_WINDOWEVENT_LEAVE:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
|
||||||
w->mouseFocus = false;
|
w->mouseFocus = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Lost focus on window %d.", w->id);
|
"Lost focus on window %d.", w->id);
|
||||||
w->keyboardFocus = false;
|
w->keyboardFocus = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Gained focus on window %d.", w->id);
|
"Gained focus on window %d.", w->id);
|
||||||
w->keyboardFocus = true;
|
w->keyboardFocus = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_MINIMIZED:
|
case SDL_WINDOWEVENT_MINIMIZED:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Minimized window %d.", w->id);
|
"Minimized window %d.", w->id);
|
||||||
w->minimized = true;
|
w->minimized = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Maximized window %d.", w->id);
|
"Maximized window %d.", w->id);
|
||||||
w->minimized = false;
|
w->minimized = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_RESTORED:
|
case SDL_WINDOWEVENT_RESTORED:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
YughLog(0, SDL_LOG_PRIORITY_INFO,
|
||||||
"Restored window %d.", w->id);
|
"Restored window %d.", w->id);
|
||||||
w->minimized = false;
|
w->minimized = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_CLOSE:
|
case SDL_WINDOWEVENT_CLOSE:
|
||||||
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
|
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_all_handle_events()
|
void window_all_handle_events() {
|
||||||
{
|
for (int i = 0; i < arrlen(windows); i++)
|
||||||
for (int i = 0; i < arrlen(windows); i++)
|
window_handle_event(&windows[i]);
|
||||||
window_handle_event(&windows[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_makefullscreen(struct window *w)
|
void window_makefullscreen(struct window *w) {
|
||||||
{
|
if (!w->fullscreen)
|
||||||
if (!w->fullscreen)
|
window_togglefullscreen(w);
|
||||||
window_togglefullscreen(w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_unfullscreen(struct window *w)
|
void window_unfullscreen(struct window *w) {
|
||||||
{
|
if (w->fullscreen)
|
||||||
if (w->fullscreen)
|
window_togglefullscreen(w);
|
||||||
window_togglefullscreen(w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_togglefullscreen(struct window *w)
|
void window_togglefullscreen(struct window *w) {
|
||||||
{
|
w->fullscreen = !w->fullscreen;
|
||||||
w->fullscreen = !w->fullscreen;
|
|
||||||
|
|
||||||
if (w->fullscreen) {
|
|
||||||
glfwMaximizeWindow(w->window);
|
|
||||||
} else {
|
|
||||||
glfwRestoreWindow(w->window);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (w->fullscreen) {
|
||||||
|
glfwMaximizeWindow(w->window);
|
||||||
|
} else {
|
||||||
|
glfwRestoreWindow(w->window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_makecurrent(struct window *w)
|
void window_makecurrent(struct window *w) {
|
||||||
{
|
|
||||||
|
|
||||||
if (w->window != glfwGetCurrentContext())
|
|
||||||
glfwMakeContextCurrent(w->window);
|
|
||||||
glViewport(0, 0, w->width, w->height);
|
|
||||||
|
|
||||||
|
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];
|
static GLFWimage images[1];
|
||||||
images[0].width = icon->width;
|
images[0].width = icon->width;
|
||||||
images[0].height = icon->height;
|
images[0].height = icon->height;
|
||||||
images[0].pixels = icon->data;
|
images[0].pixels = icon->data;
|
||||||
glfwSetWindowIcon(w->window, 1, images);
|
glfwSetWindowIcon(w->window, 1, images);
|
||||||
}
|
}
|
||||||
|
|
||||||
int window_hasfocus(struct window *w)
|
int window_hasfocus(struct window *w) {
|
||||||
{
|
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
|
||||||
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_render(struct window *w) {
|
void window_render(struct window *w) {
|
||||||
window_makecurrent(w);
|
window_makecurrent(w);
|
||||||
openglRender(w);
|
openglRender(w);
|
||||||
window_swap(w);
|
window_swap(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_renderall() {
|
void window_renderall() {
|
||||||
//arrwalk(windows, window_render);
|
// arrwalk(windows, window_render);
|
||||||
for (int i = 0; i < arrlen(windows); i++)
|
for (int i = 0; i < arrlen(windows); i++)
|
||||||
window_render(&windows[i]);
|
window_render(&windows[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include "yugine.h"
|
#include "yugine.h"
|
||||||
|
|
||||||
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "window.h"
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "gameobject.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "openglrender.h"
|
#include "openglrender.h"
|
||||||
#include "gameobject.h"
|
#include "window.h"
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
|
@ -16,8 +15,8 @@
|
||||||
|
|
||||||
#include "quickjs/quickjs.h"
|
#include "quickjs/quickjs.h"
|
||||||
|
|
||||||
#include "script.h"
|
|
||||||
#include "ffi.h"
|
#include "ffi.h"
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -25,28 +24,26 @@
|
||||||
|
|
||||||
#include "2dphysics.h"
|
#include "2dphysics.h"
|
||||||
|
|
||||||
|
#include <execinfo.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <execinfo.h>
|
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
|
||||||
#define SOKOL_TRACE_HOOKS
|
#define SOKOL_TRACE_HOOKS
|
||||||
#define SOKOL_GFX_IMPL
|
#define SOKOL_GFX_IMPL
|
||||||
#define SOKOL_GLCORE33
|
#define SOKOL_GLCORE33
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
|
|
||||||
|
|
||||||
int physOn = 0;
|
int physOn = 0;
|
||||||
|
|
||||||
double renderlag = 0;
|
double renderlag = 0;
|
||||||
double physlag = 0;
|
double physlag = 0;
|
||||||
double updatelag = 0;
|
double updatelag = 0;
|
||||||
|
|
||||||
double renderMS = 1/165.f;
|
double renderMS = 1 / 165.f;
|
||||||
double physMS = 1/120.f;
|
double physMS = 1 / 120.f;
|
||||||
double updateMS = 1/60.f;
|
double updateMS = 1 / 60.f;
|
||||||
|
|
||||||
static int ed = 1;
|
static int ed = 1;
|
||||||
static int sim_play = 0;
|
static int sim_play = 0;
|
||||||
|
@ -65,39 +62,37 @@ int fps;
|
||||||
#define SIM_PAUSE 2
|
#define SIM_PAUSE 2
|
||||||
#define SIM_STEP 3
|
#define SIM_STEP 3
|
||||||
|
|
||||||
void print_stacktrace()
|
void print_stacktrace() {
|
||||||
{
|
void *ents[512];
|
||||||
void *ents[512];
|
size_t size;
|
||||||
size_t size;
|
|
||||||
|
|
||||||
size = backtrace(ents, 512);
|
size = backtrace(ents, 512);
|
||||||
|
|
||||||
YughCritical("====================BACKTRACE====================");
|
YughCritical("====================BACKTRACE====================");
|
||||||
char **stackstr = backtrace_symbols(ents, size);
|
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++)
|
for (int i = 0; i < size; i++)
|
||||||
YughCritical(stackstr[i]);
|
YughCritical(stackstr[i]);
|
||||||
|
|
||||||
js_stacktrace();
|
js_stacktrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
void seghandle(int sig) {
|
void seghandle(int sig) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (strsignal(sig))
|
if (strsignal(sig))
|
||||||
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
||||||
|
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_script(const char *file)
|
void compile_script(const char *file) {
|
||||||
{
|
|
||||||
const char *script = slurp_text(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;
|
size_t out_len;
|
||||||
uint8_t *out;
|
uint8_t *out;
|
||||||
out = JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE);
|
out = JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE);
|
||||||
|
@ -107,159 +102,157 @@ void compile_script(const char *file)
|
||||||
fclose(f);
|
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);
|
mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **args) {
|
int main(int argc, char **args) {
|
||||||
int logout = 1;
|
int logout = 1;
|
||||||
ed = 1;
|
ed = 1;
|
||||||
|
|
||||||
script_startup();
|
script_startup();
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (args[i][0] == '-') {
|
if (args[i][0] == '-') {
|
||||||
switch(args[i][1]) {
|
switch (args[i][1]) {
|
||||||
case 'p':
|
case 'p':
|
||||||
ed = 0;
|
ed = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
if (i+1 < argc && args[i+1][0] != '-') {
|
if (i + 1 < argc && args[i + 1][0] != '-') {
|
||||||
log_setfile(args[i+1]);
|
log_setfile(args[i + 1]);
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else {
|
YughError("Expected a file for command line arg '-l'.");
|
||||||
YughError("Expected a file for command line arg '-l'.");
|
exit(1);
|
||||||
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 '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 DBG
|
||||||
if (logout) {
|
if (logout) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
char fname[100];
|
char fname[100];
|
||||||
snprintf(fname, 100, "yugine-%d.log", now);
|
snprintf(fname, 100, "yugine-%d.log", now);
|
||||||
log_setfile(fname);
|
log_setfile(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
YughInfo("Starting yugine version %s.", VER);
|
YughInfo("Starting yugine version %s.", VER);
|
||||||
|
|
||||||
FILE *sysinfo = NULL;
|
FILE *sysinfo = NULL;
|
||||||
/* sysinfo = popen("uname -a", "r");
|
/* sysinfo = popen("uname -a", "r");
|
||||||
if (!sysinfo) {
|
if (!sysinfo) {
|
||||||
YughWarn("Failed to get sys info.");
|
YughWarn("Failed to get sys info.");
|
||||||
} else {
|
} else {
|
||||||
log_cat(sysinfo);
|
log_cat(sysinfo);
|
||||||
pclose(sysinfo);
|
pclose(sysinfo);
|
||||||
}*/
|
}*/
|
||||||
signal(SIGSEGV, seghandle);
|
signal(SIGSEGV, seghandle);
|
||||||
signal(SIGABRT, seghandle);
|
signal(SIGABRT, seghandle);
|
||||||
signal(SIGFPE, seghandle);
|
signal(SIGFPE, seghandle);
|
||||||
signal(SIGBUS, seghandle);
|
signal(SIGBUS, seghandle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
engine_init();
|
engine_init();
|
||||||
|
|
||||||
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||||
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
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 = {
|
.logger = {
|
||||||
.func = sg_logging,
|
.func = sg_logging,
|
||||||
.user_data = NULL,
|
.user_data = NULL,
|
||||||
},
|
},
|
||||||
});
|
.buffer_pool_size = 1024,
|
||||||
|
.context.sample_count = 1,
|
||||||
|
});
|
||||||
|
|
||||||
input_init();
|
input_init();
|
||||||
openglInit();
|
openglInit();
|
||||||
|
|
||||||
if (ed)
|
if (ed)
|
||||||
script_dofile("scripts/editor.js");
|
script_dofile("scripts/editor.js");
|
||||||
else
|
else
|
||||||
script_dofile("scripts/play.js");
|
script_dofile("scripts/play.js");
|
||||||
|
|
||||||
while (!want_quit()) {
|
while (!want_quit()) {
|
||||||
double elapsed = glfwGetTime() - lastTick;
|
double elapsed = glfwGetTime() - lastTick;
|
||||||
deltaT = elapsed;
|
deltaT = elapsed;
|
||||||
lastTick = glfwGetTime();
|
lastTick = glfwGetTime();
|
||||||
double wait = fmax(0, renderMS-elapsed);
|
double wait = fmax(0, renderMS - elapsed);
|
||||||
input_poll(wait);
|
input_poll(wait);
|
||||||
window_all_handle_events();
|
window_all_handle_events();
|
||||||
|
|
||||||
framems[framei++] = elapsed;
|
framems[framei++] = elapsed;
|
||||||
|
|
||||||
if (framei == FPSBUF) framei = 0;
|
if (framei == FPSBUF) framei = 0;
|
||||||
|
|
||||||
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
|
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
|
||||||
timer_update(elapsed * timescale);
|
timer_update(elapsed * timescale);
|
||||||
physlag += elapsed;
|
physlag += elapsed;
|
||||||
call_updates(elapsed * timescale);
|
call_updates(elapsed * timescale);
|
||||||
while (physlag >= physMS) {
|
while (physlag >= physMS) {
|
||||||
phys_step = 1;
|
phys_step = 1;
|
||||||
physlag -= physMS;
|
physlag -= physMS;
|
||||||
phys2d_update(physMS * timescale);
|
phys2d_update(physMS * timescale);
|
||||||
call_physics(physMS * timescale);
|
call_physics(physMS * timescale);
|
||||||
if (sim_play == SIM_STEP) sim_pause();
|
if (sim_play == SIM_STEP) sim_pause();
|
||||||
phys_step = 0;
|
phys_step = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
renderlag += elapsed;
|
|
||||||
|
|
||||||
if (renderlag >= renderMS) {
|
|
||||||
renderlag -= renderMS;
|
|
||||||
window_renderall();
|
|
||||||
}
|
|
||||||
|
|
||||||
gameobjects_cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
renderlag += elapsed;
|
||||||
|
|
||||||
|
if (renderlag >= renderMS) {
|
||||||
|
renderlag -= renderMS;
|
||||||
|
window_renderall();
|
||||||
|
}
|
||||||
|
|
||||||
|
gameobjects_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int frame_fps()
|
int frame_fps() {
|
||||||
{
|
double fpsms = 0;
|
||||||
double fpsms = 0;
|
for (int i = 0; i < FPSBUF; i++) {
|
||||||
for (int i = 0; i < FPSBUF; i++) {
|
fpsms += framems[i];
|
||||||
fpsms += framems[i];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return FPSBUF / fpsms;
|
return FPSBUF / fpsms;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sim_playing() { return sim_play == SIM_PLAY; }
|
int sim_playing() { return sim_play == SIM_PLAY; }
|
||||||
|
@ -275,19 +268,19 @@ void sim_pause() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_stop() {
|
void sim_stop() {
|
||||||
/* Revert starting state of everything from sim_start */
|
/* Revert starting state of everything from sim_start */
|
||||||
sim_play = SIM_STOP;
|
sim_play = SIM_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int phys_stepping() { return phys_step; }
|
int phys_stepping() { return phys_step; }
|
||||||
|
|
||||||
void sim_step() {
|
void sim_step() {
|
||||||
if (sim_paused()) {
|
if (sim_paused()) {
|
||||||
YughInfo("Step");
|
YughInfo("Step");
|
||||||
sim_play = SIM_STEP;
|
sim_play = SIM_STEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_timescale(float val) {
|
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;
|
out vec4 color;
|
||||||
|
|
||||||
uniform float radius;
|
//in int thickness;
|
||||||
uniform int thickness;
|
in float radius;
|
||||||
uniform vec3 dbgColor;
|
//in bool fill;
|
||||||
uniform bool fill;
|
in vec3 fcolor;
|
||||||
uniform float zoom;
|
in vec2 pos;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
int thickness = 1;
|
||||||
|
bool fill = false;
|
||||||
|
|
||||||
// int tt = thickness + 1;
|
// int tt = thickness + 1;
|
||||||
float R1 = 1.f;
|
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));
|
float dist = sqrt(dot(coords, coords));
|
||||||
|
|
||||||
if (dist >= R2 && dist <= R1)
|
if (dist >= R2 && dist <= R1)
|
||||||
color = vec4(dbgColor, 1.f);
|
color = vec4(fcolor, 1.f);
|
||||||
else if (dist < R2)
|
else if (dist < R2)
|
||||||
color = vec4(dbgColor, 0.1f);
|
color = vec4(fcolor, 0.1f);
|
||||||
else
|
else
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
#version 330 core
|
#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 vec2 coords;
|
||||||
|
|
||||||
|
out float radius;
|
||||||
|
out vec3 fcolor;
|
||||||
|
|
||||||
uniform mat4 proj;
|
uniform mat4 proj;
|
||||||
uniform vec2 res;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = proj * vec4(vertex.xy, 0.0, 1.0);
|
gl_Position = proj * vec4((vertex * aradius) + apos, 0.0, 1.0);
|
||||||
coords = vertex.zw;
|
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
|
#version 330
|
||||||
out vec4 color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
in vec2 apos;
|
in vec2 apos;
|
||||||
vec2 bpos;
|
vec2 bpos;
|
||||||
uniform int thickness;
|
uniform float thickness; /* thickness in pixels */
|
||||||
uniform int span;
|
uniform float span;
|
||||||
|
uniform vec3 color;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
float t = thickness / 2.f;
|
float t = thickness / span;
|
||||||
bpos.x = mod(apos.x, span);
|
t /= 2.0;
|
||||||
bpos.y = mod(apos.y, span);
|
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)))
|
float comp = min(bpos.x, bpos.y);
|
||||||
discard;
|
|
||||||
|
|
||||||
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
|
#version 330
|
||||||
layout (location = 0) in vec2 pos;
|
layout (location = 0) in vec2 pos;
|
||||||
out vec2 apos;
|
|
||||||
|
|
||||||
uniform vec2 offset;
|
out vec2 apos;
|
||||||
|
|
||||||
layout (std140) uniform Projection {
|
layout (std140) uniform Projection {
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uniform vec2 offset;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 ipos = inverse(projection) * vec4(pos, 0.f, 1.f);
|
// vec4 ipos = inverse(projection) * vec4(pos, 0.f, 1.f);
|
||||||
apos = ipos.xy + offset;
|
apos = pos * vec2(600, 360);
|
||||||
|
// apos = pos + offset;
|
||||||
|
|
||||||
|
|
||||||
gl_Position = vec4(pos, 0.f, 1.f);
|
gl_Position = vec4(pos, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,5 @@ uniform float alpha;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
color = vec4(linecolor, alpha);
|
color = vec4(1.f,1.f,1.f,1.f);
|
||||||
}
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
#version 330
|
#version 330
|
||||||
layout (location = 0) in vec2 pos;
|
layout (location = 0) in vec2 pos;
|
||||||
|
|
||||||
layout (std140) uniform Projection {
|
uniform mat4 proj;
|
||||||
mat4 projection;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main()
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
|
color = vec4(fColor.xyz, texture(text, TexCoords).r);
|
||||||
// color = vec4(fColor.xyz, texture(text, TexCoords).r);
|
// color = vec4(1.f, 1.f, 1.f, texture(text, TexCoords).r);
|
||||||
color = vec4(1.f,1.f,1.f, texture(text, TexCoords).r);
|
|
||||||
if (color.a <= 0.1f)
|
if (color.a <= 0.1f)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue