shaders
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
#ifndef THREEDPHYSICS_H
|
||||
#define THREEDPHYSICS_H
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,26 +42,26 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
||||
glm::vec3 p1 = CalculateCenter();
|
||||
|
||||
glm::vec3 p2 =
|
||||
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
||||
FloatWidths.
|
||||
x) : GetExtentsOffset(TFOR.Right(),
|
||||
FloatWidths.x,
|
||||
TargetOffset.x,
|
||||
AnchorWidths.x);
|
||||
XDirPosts ? GetPostsOffset(TFOR.Right(),
|
||||
FloatWidths.
|
||||
x) : GetExtentsOffset(TFOR.Right(),
|
||||
FloatWidths.x,
|
||||
TargetOffset.x,
|
||||
AnchorWidths.x);
|
||||
glm::vec3 p3 =
|
||||
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
||||
FloatWidths.
|
||||
y) : GetExtentsOffset(TFOR.Up(),
|
||||
FloatWidths.y,
|
||||
TargetOffset.y,
|
||||
AnchorWidths.y);
|
||||
YDirPosts ? GetPostsOffset(TFOR.Up(),
|
||||
FloatWidths.
|
||||
y) : GetExtentsOffset(TFOR.Up(),
|
||||
FloatWidths.y,
|
||||
TargetOffset.y,
|
||||
AnchorWidths.y);
|
||||
glm::vec3 p4 =
|
||||
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
||||
FloatWidths.
|
||||
z) : GetExtentsOffset(TFOR.Back(),
|
||||
FloatWidths.z,
|
||||
TargetOffset.z,
|
||||
AnchorWidths.z);
|
||||
ZDirPosts ? GetPostsOffset(TFOR.Back(),
|
||||
FloatWidths.
|
||||
z) : GetExtentsOffset(TFOR.Back(),
|
||||
FloatWidths.z,
|
||||
TargetOffset.z,
|
||||
AnchorWidths.z);
|
||||
|
||||
return p1 + p2 + p3 + p4;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ glm::vec3 ThirdPersonFollow::CalculatePosition()
|
||||
glm::vec3 ThirdPersonFollow::CalculateCenter()
|
||||
{
|
||||
return Target->get_global_translation() +
|
||||
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
||||
TFOR.TransformDirection(Offset) + (mytransform->Back() * Distance);
|
||||
}
|
||||
|
||||
glm::vec3 ThirdPersonFollow::
|
||||
@@ -82,37 +82,37 @@ GetPostsOffset(const glm::vec3 & DirectionVector, float AnchorWidth)
|
||||
|
||||
glm::vec3 ThirdPersonFollow::
|
||||
GetExtentsOffset(const glm::vec3 & DirectionVector, float AnchorWidth,
|
||||
float TOffset, float Width)
|
||||
float TOffset, float Width)
|
||||
{
|
||||
|
||||
float negated_offset_sign = ((0 <= TOffset) - (TOffset < 0)) * -1.f;
|
||||
float TotalWidth = AnchorWidth + Width;
|
||||
|
||||
if (glm::abs(TOffset) > TotalWidth
|
||||
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
||||
return DirectionVector * TotalWidth * negated_offset_sign;
|
||||
&& !glm::epsilonEqual(glm::abs(TOffset), TotalWidth, 0.5f))
|
||||
return DirectionVector * TotalWidth * negated_offset_sign;
|
||||
else {
|
||||
if (glm::abs(TOffset) >= AnchorWidth)
|
||||
return DirectionVector * AnchorWidth * negated_offset_sign;
|
||||
else
|
||||
return DirectionVector * TOffset * -1.f;
|
||||
if (glm::abs(TOffset) >= AnchorWidth)
|
||||
return DirectionVector * AnchorWidth * negated_offset_sign;
|
||||
else
|
||||
return DirectionVector * TOffset * -1.f;
|
||||
}
|
||||
|
||||
return glm::vec3(0.f);
|
||||
}
|
||||
|
||||
glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds,
|
||||
float Tick)
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds,
|
||||
float Tick)
|
||||
{
|
||||
// Previously "FORTransform.TransformVector(Speeds)
|
||||
glm::vec3 TSpeed = glm::abs(TFOR.TransformDirection(Speeds));
|
||||
glm::vec3 TOffset = glm::abs(TFOR.TransformDirection(TargetOffset));
|
||||
glm::vec3 TAnchorWidths =
|
||||
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
||||
glm::abs(TFOR.TransformDirection(AnchorWidths));
|
||||
glm::vec3 TFloatWidths =
|
||||
glm::abs(TFOR.TransformDirection(FloatWidths));
|
||||
glm::abs(TFOR.TransformDirection(FloatWidths));
|
||||
|
||||
|
||||
|
||||
@@ -124,14 +124,14 @@ glm::vec3 ThirdPersonFollow::FrameBasedVectorLerp(const glm::vec3 & From,
|
||||
|
||||
|
||||
float xAlpha =
|
||||
glm::clamp((bUseX ? AnchorSpeed : TSpeed.x) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseX ? AnchorSpeed : TSpeed.x) * Tick, 0.f, 1.f);
|
||||
float yAlpha =
|
||||
glm::clamp((bUseY ? AnchorSpeed : TSpeed.y) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseY ? AnchorSpeed : TSpeed.y) * Tick, 0.f, 1.f);
|
||||
float zAlpha =
|
||||
glm::clamp((bUseZ ? AnchorSpeed : TSpeed.z) * Tick, 0.f, 1.f);
|
||||
glm::clamp((bUseZ ? AnchorSpeed : TSpeed.z) * Tick, 0.f, 1.f);
|
||||
|
||||
return VectorLerpPiecewise(From, To,
|
||||
glm::vec3(xAlpha, yAlpha, zAlpha));
|
||||
glm::vec3(xAlpha, yAlpha, zAlpha));
|
||||
}
|
||||
|
||||
int float_epsilon(mfloat_t a, mfloat_t b, mfloat_t e)
|
||||
@@ -165,11 +165,11 @@ void ThirdPersonFollow::CalculateTargets()
|
||||
// For rotation
|
||||
// TODO: Check of this implementation is the same as UKismetMath FindLookAtRotation
|
||||
TargetRotation =
|
||||
RemoveLockedRotation(glm::quat
|
||||
(mytransform->
|
||||
get_global_transform()->get_origin() -
|
||||
Target->
|
||||
get_global_transform()->get_origin()));
|
||||
RemoveLockedRotation(glm::quat
|
||||
(mytransform->
|
||||
get_global_transform()->get_origin() -
|
||||
Target->
|
||||
get_global_transform()->get_origin()));
|
||||
}
|
||||
|
||||
follow_removelockedrot()
|
||||
@@ -185,11 +185,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
||||
//
|
||||
|
||||
NewRotator.x =
|
||||
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
||||
LockRoll ? mytransform->get_rotation().x : CurrentRotator.x;
|
||||
NewRotator.y =
|
||||
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
||||
LockPitch ? mytransform->get_rotation().y : CurrentRotator.y;
|
||||
NewRotator.z =
|
||||
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
||||
LockYaw ? mytransform->get_rotation().z : CurrentRotator.z;
|
||||
|
||||
return glm::quat(NewRotator);
|
||||
}
|
||||
@@ -199,11 +199,11 @@ RemoveLockedRotation(const glm::quat & CurrentRotation)
|
||||
void ThirdPersonFollow::CalculateTargetOffset()
|
||||
{
|
||||
glm::vec3 p1 =
|
||||
(mytransform->Forward() * Distance) +
|
||||
TFOR.TransformDirection(Offset) +
|
||||
mytransform->get_global_translation();
|
||||
(mytransform->Forward() * Distance) +
|
||||
TFOR.TransformDirection(Offset) +
|
||||
mytransform->get_global_translation();
|
||||
glm::vec3 p2 =
|
||||
TFOR.InverseTransformDirection(Target->get_global_translation());
|
||||
TFOR.InverseTransformDirection(Target->get_global_translation());
|
||||
glm::vec3 p3 = TFOR.InverseTransformDirection(p1);
|
||||
|
||||
TargetOffset = p2 - p3;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "transform.h"
|
||||
|
||||
struct follow {
|
||||
float distance;
|
||||
mfloat_t target_rot[4];
|
||||
float distance;
|
||||
mfloat_t target_rot[4];
|
||||
};
|
||||
|
||||
mfloat_t *follow_calccenter();
|
||||
@@ -31,45 +31,45 @@ class ThirdPersonFollow {
|
||||
|
||||
public:
|
||||
enum CameraType {
|
||||
STATIONARY,
|
||||
TRANSLATING,
|
||||
ROTATING,
|
||||
SPLINE
|
||||
STATIONARY,
|
||||
TRANSLATING,
|
||||
ROTATING,
|
||||
SPLINE
|
||||
};
|
||||
|
||||
enum CameraTransition {
|
||||
NONE,
|
||||
CROSSDISSOLVE,
|
||||
WIPE,
|
||||
DIP
|
||||
NONE,
|
||||
CROSSDISSOLVE,
|
||||
WIPE,
|
||||
DIP
|
||||
};
|
||||
|
||||
enum FrameOfReference {
|
||||
LOCAL,
|
||||
WORLD,
|
||||
EXTERNAL
|
||||
LOCAL,
|
||||
WORLD,
|
||||
EXTERNAL
|
||||
};
|
||||
|
||||
ThirdPersonFollow() {
|
||||
// Rotation
|
||||
RotationSpeed = 10.0f;
|
||||
LockPitch = LockYaw = LockRoll = true;
|
||||
// Rotation
|
||||
RotationSpeed = 10.0f;
|
||||
LockPitch = LockYaw = LockRoll = true;
|
||||
|
||||
XDirPosts = false;
|
||||
YDirPosts = false;
|
||||
ZDirPosts = false;
|
||||
XDirPosts = false;
|
||||
YDirPosts = false;
|
||||
ZDirPosts = false;
|
||||
|
||||
|
||||
// Translation
|
||||
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
||||
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
||||
//TranslationScales = glm::vec3(1, 1, 1);
|
||||
// Translation
|
||||
//FloatWidths = AnchorWidths = CenterVector = glm::vec3(0, 0, 0);
|
||||
PositionSpeeds = glm::vec3(2.f, 2.f, 2.f);
|
||||
//TranslationScales = glm::vec3(1, 1, 1);
|
||||
|
||||
// Frame settings
|
||||
Offset = glm::vec3(0.f, 0.f, 0.f);
|
||||
Distance = 10;
|
||||
// Frame settings
|
||||
Offset = glm::vec3(0.f, 0.f, 0.f);
|
||||
Distance = 10;
|
||||
|
||||
AnchorSpeed = 80;
|
||||
AnchorSpeed = 80;
|
||||
} ~ThirdPersonFollow() {
|
||||
}
|
||||
|
||||
@@ -81,14 +81,14 @@ class ThirdPersonFollow {
|
||||
|
||||
|
||||
void SetExternalFrame(Transform * val) {
|
||||
ExternalFrame = val;
|
||||
ExternalFrame = val;
|
||||
}
|
||||
|
||||
// The target the camera "looks" at, used for calculations
|
||||
Transform *Target = nullptr;
|
||||
|
||||
void SetTarget(Transform * val) {
|
||||
Target = val;
|
||||
Target = val;
|
||||
}
|
||||
|
||||
// Offset from the target
|
||||
@@ -158,25 +158,25 @@ class ThirdPersonFollow {
|
||||
|
||||
/// Given a direction and width, find the offsets.
|
||||
glm::vec3 GetPostsOffset(const glm::vec3 & DirectionVector,
|
||||
float AnchorWidth);
|
||||
float AnchorWidth);
|
||||
|
||||
/// Given anchors, what's the anchor width?
|
||||
glm::vec3 GetExtentsOffset(const glm::vec3 & DirectionVector,
|
||||
float AnchorWidth, float TOffset,
|
||||
float Width);
|
||||
float AnchorWidth, float TOffset,
|
||||
float Width);
|
||||
|
||||
glm::quat RemoveLockedRotation(const glm::quat & CurrentRotation);
|
||||
|
||||
glm::vec3 FrameBasedVectorLerp(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds, float Tick);
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Speeds, float Tick);
|
||||
|
||||
glm::vec3 VectorLerpPiecewise(const glm::vec3 & From,
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Alpha);
|
||||
const glm::vec3 & To,
|
||||
const glm::vec3 & Alpha);
|
||||
|
||||
bool GetLerpParam(const float Offst, const float AnchorWidth,
|
||||
const float FloatWidth);
|
||||
const float FloatWidth);
|
||||
|
||||
/// Set to a value that gives good clamping, smoothly. Activates when
|
||||
/// the target is out of range.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "light.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/*
|
||||
void Light::serialize(FILE * file)
|
||||
{
|
||||
@@ -30,20 +29,20 @@ struct mDirectionalLight *dLight = NULL;
|
||||
struct mDirectionalLight *MakeDLight()
|
||||
{
|
||||
if (dLight != NULL) {
|
||||
dLight =
|
||||
(struct mDirectionalLight *)
|
||||
malloc(sizeof(struct mDirectionalLight));
|
||||
quat_from_euler(dLight->light.obj.transform.rotation,
|
||||
dlight_init_rot);
|
||||
dLight =
|
||||
(struct mDirectionalLight *)
|
||||
malloc(sizeof(struct mDirectionalLight));
|
||||
quat_from_euler(dLight->light.obj.transform.rotation,
|
||||
dlight_init_rot);
|
||||
|
||||
return dLight;
|
||||
return dLight;
|
||||
}
|
||||
|
||||
return dLight;
|
||||
}
|
||||
|
||||
void dlight_prepshader(struct mDirectionalLight *light,
|
||||
struct shader *shader)
|
||||
struct shader *shader)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
trans_forward(fwd, &light->light.obj.transform);
|
||||
@@ -61,14 +60,14 @@ static int numLights = 0;
|
||||
struct mPointLight *MakePointlight()
|
||||
{
|
||||
if (numLights < 4) {
|
||||
struct mPointLight *light =
|
||||
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
||||
pointLights[numLights++] = light;
|
||||
light->light.strength = 0.2f;
|
||||
light->constant = 1.f;
|
||||
light->linear = 0.9f;
|
||||
light->quadratic = 0.032f;
|
||||
return light;
|
||||
struct mPointLight *light =
|
||||
(struct mPointLight *) malloc(sizeof(struct mPointLight));
|
||||
pointLights[numLights++] = light;
|
||||
light->light.strength = 0.2f;
|
||||
light->constant = 1.f;
|
||||
light->linear = 0.9f;
|
||||
light->quadratic = 0.032f;
|
||||
return light;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -82,11 +81,11 @@ static void prepstring(char *buffer, char *prepend, const char *append)
|
||||
void pointlights_prepshader(struct shader *shader)
|
||||
{
|
||||
for (int i = 0; i < numLights; i++)
|
||||
pointlight_prepshader(pointLights[i], shader, i);
|
||||
pointlight_prepshader(pointLights[i], shader, i);
|
||||
}
|
||||
|
||||
void pointlight_prepshader(struct mPointLight *light,
|
||||
struct shader *shader, int num)
|
||||
struct shader *shader, int num)
|
||||
{
|
||||
shader_use(shader);
|
||||
char prepend[100] = { '\0' };
|
||||
@@ -121,10 +120,10 @@ static int numSpots = 0;
|
||||
struct mSpotLight *MakeSpotlight()
|
||||
{
|
||||
if (numSpots < 4) {
|
||||
struct mSpotLight *light =
|
||||
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
||||
spotLights[numSpots++] = light;
|
||||
return light;
|
||||
struct mSpotLight *light =
|
||||
(struct mSpotLight *) malloc(sizeof(struct mSpotLight));
|
||||
spotLights[numSpots++] = light;
|
||||
return light;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -135,17 +134,17 @@ struct mSpotLight *MakeSpotlight()
|
||||
void spotlights_prepshader(struct shader *shader)
|
||||
{
|
||||
for (int i = 0; i < numSpots; i++)
|
||||
spotlight_prepshader(spotLights[i], shader, i);
|
||||
spotlight_prepshader(spotLights[i], shader, i);
|
||||
}
|
||||
|
||||
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||
int num)
|
||||
int num)
|
||||
{
|
||||
mfloat_t fwd[3] = { 0.f };
|
||||
trans_forward(fwd, &light->light.obj.transform);
|
||||
shader_use(shader);
|
||||
shader_setvec3(shader, "spotLight.position",
|
||||
light->light.obj.transform.position);
|
||||
light->light.obj.transform.position);
|
||||
shader_setvec3(shader, "spotLight.direction", fwd);
|
||||
shader_setvec3(shader, "spotLight.color", light->light.color);
|
||||
shader_setfloat(shader, "spotLight.strength", light->light.strength);
|
||||
@@ -165,10 +164,10 @@ void light_gui(struct mLight *light)
|
||||
object_gui(&light->obj);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Light", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Strength", 0.f, &light->strength, 1.f, 0.01f, 0.001f);
|
||||
// ImGui::ColorEdit3("Color", &light->color[0]);
|
||||
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Strength", 0.f, &light->strength, 1.f, 0.01f, 0.001f);
|
||||
// ImGui::ColorEdit3("Color", &light->color[0]);
|
||||
nk_checkbox_label(ctx, "Dynamic", (bool *) &light->dynamic);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,10 +177,10 @@ void pointlight_gui(struct mPointLight *light)
|
||||
light_gui(&light->light);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Point Light", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Constant", 0.f, &light->constant, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Linear", 0.f, &light->linear, 0.3f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &light->quadratic, 0.3f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Constant", 0.f, &light->constant, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Linear", 0.f, &light->linear, 0.3f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &light->quadratic, 0.3f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -191,12 +190,12 @@ void spotlight_gui(struct mSpotLight *spot)
|
||||
light_gui(&spot->light);
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_NODE, "Spotlight", NK_MINIMIZED)) {
|
||||
nk_property_float(ctx, "Linear", 0.f, &spot->linear, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &spot->quadratic, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Distance", 0.f, &spot->distance, 200.f, 1.f, 0.1f, 200.f);
|
||||
nk_property_float(ctx, "Cutoff Degrees", 0.f, &spot->cutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Outer Cutoff Degrees", 0.f, &spot->outerCutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
nk_property_float(ctx, "Linear", 0.f, &spot->linear, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Quadratic", 0.f, &spot->quadratic, 1.f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Distance", 0.f, &spot->distance, 200.f, 1.f, 0.1f, 200.f);
|
||||
nk_property_float(ctx, "Cutoff Degrees", 0.f, &spot->cutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_property_float(ctx, "Outer Cutoff Degrees", 0.f, &spot->outerCutoff, 0.7f, 0.01f, 0.001f);
|
||||
nk_tree_pop(ctx);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct mLight {
|
||||
struct gameobject *go;
|
||||
uint8_t color[3];
|
||||
float strength;
|
||||
int dynamic;
|
||||
int on;
|
||||
struct gameobject *go;
|
||||
uint8_t color[3];
|
||||
float strength;
|
||||
int dynamic;
|
||||
int on;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -21,7 +21,7 @@ struct mPointLight {
|
||||
|
||||
struct mPointLight *MakePointlight();
|
||||
void pointlight_prepshader(struct mPointLight *light,
|
||||
struct shader *shader, int num);
|
||||
struct shader *shader, int num);
|
||||
void pointlights_prepshader(struct shader *shader);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct mSpotLight {
|
||||
struct mSpotLight *MakeSpotlight();
|
||||
void spotlight_gui(struct mSpotLight *light);
|
||||
void spotlight_prepshader(struct mSpotLight *light, struct shader *shader,
|
||||
int num);
|
||||
int num);
|
||||
void spotlights_prepshader(struct shader *shader);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ struct mDirectionalLight {
|
||||
};
|
||||
|
||||
void dlight_prepshader(struct mDirectionalLight *light,
|
||||
struct shader *shader);
|
||||
struct shader *shader);
|
||||
struct mDirectionalLight *MakeDLight();
|
||||
|
||||
extern struct mDirectionalLight *dLight;
|
||||
|
||||
@@ -4,122 +4,94 @@
|
||||
#include "shader.h"
|
||||
#include "texture.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader)
|
||||
{
|
||||
// bind appropriate textures
|
||||
uint32_t diffuseNr = 1;
|
||||
uint32_t specularNr = 1;
|
||||
uint32_t normalNr = 1;
|
||||
uint32_t heightNr = 1;
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader) {
|
||||
// bind appropriate textures
|
||||
uint32_t diffuseNr = 1;
|
||||
uint32_t specularNr = 1;
|
||||
uint32_t normalNr = 1;
|
||||
uint32_t heightNr = 1;
|
||||
|
||||
for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
||||
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||
// retrieve texture number (the N in diffuse_textureN)
|
||||
char number = 0;
|
||||
// TODO: malloc every single frame ... nope! Change to stack
|
||||
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
||||
/*
|
||||
if (mesh->textures[i].type == TEX_DIFF)
|
||||
number = diffuseNr++;
|
||||
else if (mesh->textures[i].type == TEX_SPEC)
|
||||
number = specularNr++;
|
||||
else if (mesh->textures[i].type == TEX_NORM)
|
||||
number = normalNr++;
|
||||
else if (mesh->textures[i].type == TEX_HEIGHT)
|
||||
number = heightNr++;
|
||||
// for (int i = 0; i < (mesh->te - mesh->textures); i++) {
|
||||
// glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||
// retrieve texture number (the N in diffuse_textureN)
|
||||
// char number = 0;
|
||||
// TODO: malloc every single frame ... nope! Change to stack
|
||||
/*char *name = malloc(sizeof(char) *(strlen(mesh->textures[i].type) + 2));*/
|
||||
/*
|
||||
// if (mesh->textures[i].type == TEX_DIFF)
|
||||
// number = diffuseNr++;
|
||||
// else if (mesh->textures[i].type == TEX_SPEC)
|
||||
// number = specularNr++;
|
||||
// else if (mesh->textures[i].type == TEX_NORM)
|
||||
// number = normalNr++;
|
||||
// else if (mesh->textures[i].type == TEX_HEIGHT)
|
||||
// number = heightNr++;
|
||||
*/
|
||||
|
||||
/*
|
||||
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
||||
free(name);
|
||||
*/
|
||||
}
|
||||
|
||||
// draw mesh
|
||||
glBindVertexArray(mesh->VAO);
|
||||
DrawMeshAgain(mesh);
|
||||
|
||||
// DEBUG
|
||||
// triCount += indices.size() / 3;
|
||||
/*
|
||||
glUniform1i(glGetUniformLocation(shader->id, name), i);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh->textures[i].id);
|
||||
free(name);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void DrawMeshAgain(struct mesh *mesh)
|
||||
{
|
||||
void DrawMeshAgain(struct mesh *mesh) {
|
||||
}
|
||||
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
||||
uint32_t * indices, uint32_t * ie,
|
||||
struct Texture *textures, struct Texture *te)
|
||||
{
|
||||
struct mesh *newmesh = (struct mesh *) malloc(sizeof(struct mesh));
|
||||
newmesh->vertices = vertices;
|
||||
newmesh->ve = ve;
|
||||
newmesh->indices = indices;
|
||||
newmesh->ie = ie;
|
||||
newmesh->textures = textures;
|
||||
newmesh->te = te;
|
||||
void setupmesh(struct mesh *mesh) {
|
||||
/*
|
||||
// create buffers/arrays
|
||||
glGenVertexArrays(1, &mesh->VAO);
|
||||
glGenBuffers(1, &mesh->VBO);
|
||||
glGenBuffers(1, &mesh->EBO);
|
||||
|
||||
setupmesh(newmesh);
|
||||
return newmesh;
|
||||
}
|
||||
|
||||
void setupmesh(struct mesh *mesh)
|
||||
{
|
||||
/*
|
||||
// create buffers/arrays
|
||||
glGenVertexArrays(1, &mesh->VAO);
|
||||
glGenBuffers(1, &mesh->VBO);
|
||||
glGenBuffers(1, &mesh->EBO);
|
||||
|
||||
glBindVertexArray(mesh->VAO);
|
||||
// load data into vertex buffers
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||
|
||||
|
||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to vevc array which
|
||||
// again translates to 3/2 floats which translates to a byte array.
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
||||
&mesh->vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
||||
&mesh->indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// set the vertex attribute pointers
|
||||
// vertex Positions
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
||||
// vertex normals
|
||||
glEnableVertexAttribArray(1);
|
||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
||||
// vertex texture coords
|
||||
glEnableVertexAttribArray(2);
|
||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
||||
// vertex tangent
|
||||
glEnableVertexAttribArray(3);
|
||||
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
||||
// vertex bitangent
|
||||
glEnableVertexAttribArray(4);
|
||||
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
||||
|
||||
// Bone ids
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex,
|
||||
m_BoneIDs
|
||||
[MAX_BONE_INFLUENCE]));
|
||||
|
||||
// Weights
|
||||
glEnableVertexAttribArray(6);
|
||||
// glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, m_Weights));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
*/
|
||||
glBindVertexArray(mesh->VAO);
|
||||
// load data into vertex buffers
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||
|
||||
|
||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to vevc array which
|
||||
// again translates to 3/2 floats which translates to a byte array.
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
(mesh->ve - mesh->vertices) * sizeof(struct Vertex),
|
||||
&mesh->vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
(mesh->ie - mesh->indices) * sizeof(uint32_t),
|
||||
&mesh->indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// set the vertex attribute pointers
|
||||
// vertex Positions
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), NULL);
|
||||
// vertex normals
|
||||
glEnableVertexAttribArray(1);
|
||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Normal[3]));
|
||||
// vertex texture coords
|
||||
glEnableVertexAttribArray(2);
|
||||
// glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, TexCoords[2]));
|
||||
// vertex tangent
|
||||
glEnableVertexAttribArray(3);
|
||||
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Tangent[3]));
|
||||
// vertex bitangent
|
||||
glEnableVertexAttribArray(4);
|
||||
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, Bitangent[3]));
|
||||
|
||||
// Bone ids
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex,
|
||||
m_BoneIDs
|
||||
[MAX_BONE_INFLUENCE]));
|
||||
|
||||
// Weights
|
||||
glEnableVertexAttribArray(6);
|
||||
// glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), offsetof(struct Vertex, m_Weights));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -2,40 +2,20 @@
|
||||
#define MESH_H
|
||||
|
||||
#include "mathc.h"
|
||||
#include "sokol/sokol_gfx.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct shader;
|
||||
struct Texture;
|
||||
|
||||
#define MAX_BONE_INFLUENCE 4
|
||||
|
||||
struct Vertex {
|
||||
mfloat_t Position[3];
|
||||
mfloat_t Normal[3];
|
||||
mfloat_t TexCoords[2];
|
||||
mfloat_t Tangent[3];
|
||||
mfloat_t Bitangent[3];
|
||||
|
||||
int m_BoneIDs[MAX_BONE_INFLUENCE];
|
||||
|
||||
float m_Weights[MAX_BONE_INFLUENCE];
|
||||
};
|
||||
|
||||
struct mesh {
|
||||
struct Vertex *vertices;
|
||||
struct Vertex *ve;
|
||||
uint32_t *indices;
|
||||
uint32_t *ie;
|
||||
struct Texture *textures;
|
||||
struct Texture *te;
|
||||
uint32_t VAO, VBO, EBO;
|
||||
sg_bindings bind;
|
||||
uint32_t face_count;
|
||||
};
|
||||
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve,
|
||||
uint32_t * indices, uint32_t * ie,
|
||||
struct Texture *textures, struct Texture *te);
|
||||
void setupmesh(struct mesh *mesh); /* Loads mesh into the GPU */
|
||||
struct mesh *MakeMesh(struct Vertex *vertices, struct Vertex *ve, uint32_t *indices, uint32_t *ie, struct Texture *textures, struct Texture *te);
|
||||
void setupmesh(struct mesh *mesh); /* Loads mesh into the GPU */
|
||||
void DrawMesh(struct mesh *mesh, struct shader *shader);
|
||||
void DrawMeshAgain(struct mesh *mesh); /* Draws whatever mesh was drawn last */
|
||||
void DrawMeshAgain(struct mesh *mesh); /* Draws whatever mesh was drawn last */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,10 +5,27 @@
|
||||
#include "resources.h"
|
||||
#include "shader.h"
|
||||
#include "stb_ds.h"
|
||||
#include "font.h"
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
// #define HANDMADE_MATH_USE_TURNS
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#include "math.h"
|
||||
#include "time.h"
|
||||
|
||||
#define CGLTF_IMPLEMENTATION
|
||||
#include <cgltf.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#include "mathc.h"
|
||||
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
struct Texture *value;
|
||||
@@ -18,6 +35,59 @@ static void processnode();
|
||||
static void processmesh();
|
||||
static void processtexture();
|
||||
|
||||
static sg_shader model_shader;
|
||||
static sg_pipeline model_pipe;
|
||||
|
||||
void model_init() {
|
||||
YughWarn("Creating model");
|
||||
model_shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/diffuse_v.glsl"),
|
||||
.fs.source = slurp_text("shaders/diffuse_f.glsl"),
|
||||
.vs.uniform_blocks[0] = {
|
||||
.size = sizeof(float) * 16 * 4,
|
||||
.uniforms = {
|
||||
[0] = {.name = "vp", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[1] = {.name = "model", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[2] = {.name = "proj", .type = SG_UNIFORMTYPE_MAT4},
|
||||
[3] = {.name = "lsm", .type = SG_UNIFORMTYPE_MAT4},
|
||||
}},
|
||||
|
||||
.fs.uniform_blocks[0] = {
|
||||
.size = sizeof(float) * 3 * 5,
|
||||
.uniforms = {
|
||||
[0] = {.name = "point_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[1] = {.name = "dir_dir", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[2] = {.name = "view_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[3] = {.name = "spot_pos", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
[4] = {.name = "spot_dir", .type = SG_UNIFORMTYPE_FLOAT3},
|
||||
},
|
||||
},
|
||||
|
||||
.fs.images[0] = {.name = "diffuse", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
.fs.images[1] = { .name = "normmap", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
.fs.images[2] = {.name = "shadow_map", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT},
|
||||
|
||||
});
|
||||
|
||||
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = model_shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[0].buffer_index = 0, /* position */
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].buffer_index = 1, /* tex coords */
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].buffer_index = 2, /* normal */
|
||||
},
|
||||
},
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_FRONT,
|
||||
.depth.write_enabled = true,
|
||||
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||
});
|
||||
}
|
||||
|
||||
struct model *GetExistingModel(const char *path) {
|
||||
if (!path || path[0] == '\0') return NULL;
|
||||
|
||||
@@ -27,8 +97,18 @@ struct model *GetExistingModel(const char *path) {
|
||||
return MakeModel(path);
|
||||
}
|
||||
|
||||
/* TODO: Make this a hash compare for speedup */
|
||||
cgltf_attribute *get_attr_type(cgltf_primitive p, cgltf_attribute_type t)
|
||||
{
|
||||
for (int i = 0; i < p.attributes_count; i++) {
|
||||
if (p.attributes[i].type == t)
|
||||
return &p.attributes[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct model *MakeModel(const char *path) {
|
||||
YughWarn("Making the model from %s.", path);
|
||||
cgltf_options options = {0};
|
||||
cgltf_data *data = NULL;
|
||||
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
||||
@@ -45,188 +125,166 @@ struct model *MakeModel(const char *path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct model *model = malloc(sizeof(struct model));
|
||||
struct model *model = calloc(1, sizeof(*model));
|
||||
/* TODO: Optimize by grouping by material. One material per draw. */
|
||||
YughWarn("Model has %d materials.", data->materials_count);
|
||||
|
||||
model->meshes = malloc(sizeof(struct mesh) * data->meshes_count);
|
||||
float vs[65535*3];
|
||||
uint16_t idxs[65535];
|
||||
|
||||
for (int i = 0; i < data->nodes_count; i++) {
|
||||
|
||||
if (data->nodes[i].mesh) {
|
||||
cgltf_mesh *mesh = data->nodes[i].mesh;
|
||||
|
||||
for (int j = 0; j < mesh->primitives_count; j++) {
|
||||
cgltf_primitive primitive = mesh->primitives[j];
|
||||
|
||||
for (int k = 0; k < primitive.attributes_count; k++) {
|
||||
cgltf_attribute attribute = primitive.attributes[k];
|
||||
|
||||
switch (attribute.type) {
|
||||
|
||||
case cgltf_attribute_type_position:
|
||||
// float *vs = malloc(sizeof(float) * cgltf_accessor_unpack_floats(attribute.accessor, NULL, attribute.accessor.count);
|
||||
// cgltf_accessor_unpack_floats(attribute.accessor, vs, attribute.accessor.count);
|
||||
for (int i = 0; i < data->meshes_count; i++) {
|
||||
cgltf_mesh *mesh = &data->meshes[i];
|
||||
struct mesh newmesh = {0};
|
||||
arrput(model->meshes,newmesh);
|
||||
|
||||
YughWarn("Making mesh %d. It has %d primitives.", i, mesh->primitives_count);
|
||||
|
||||
for (int j = 0; j < mesh->primitives_count; j++) {
|
||||
cgltf_primitive primitive = mesh->primitives[j];
|
||||
|
||||
if (primitive.indices) {
|
||||
int c = primitive.indices->count;
|
||||
memcpy(idxs, cgltf_buffer_view_data(primitive.indices->buffer_view), sizeof(uint16_t) * c);
|
||||
|
||||
model->meshes[j].bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = idxs,
|
||||
.data.size = sizeof(uint16_t) * c,
|
||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||
|
||||
model->meshes[j].face_count = c;
|
||||
} else {
|
||||
YughWarn("Model does not have indices. Generating them.");
|
||||
int c = primitive.attributes[0].data->count;
|
||||
model->meshes[j].face_count = c;
|
||||
for (int z = 0; z < c; z++)
|
||||
idxs[z] = z;
|
||||
|
||||
model->meshes[j].bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = idxs,
|
||||
.data.size = sizeof(uint16_t) * c,
|
||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||
}
|
||||
|
||||
if (primitive.material->has_pbr_metallic_roughness && primitive.material->pbr_metallic_roughness.base_color_texture.texture) {
|
||||
// YughWarn("Texture is %s.", primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri);
|
||||
|
||||
model->meshes[j].bind.fs_images[0] = texture_pullfromfile(primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri)->id;
|
||||
} else
|
||||
model->meshes[j].bind.fs_images[0] = texture_pullfromfile("k")->id;
|
||||
|
||||
cgltf_texture *tex;
|
||||
if (tex = primitive.material->normal_texture.texture) {
|
||||
model->meshes[j].bind.fs_images[1] = texture_pullfromfile(tex->image->uri)->id;
|
||||
} else
|
||||
model->meshes[j].bind.fs_images[1] = texture_pullfromfile("k")->id;
|
||||
|
||||
model->meshes[j].bind.fs_images[2] = ddimg;
|
||||
|
||||
int has_norm = 0;
|
||||
|
||||
for (int k = 0; k < primitive.attributes_count; k++) {
|
||||
cgltf_attribute attribute = primitive.attributes[k];
|
||||
|
||||
int n = cgltf_accessor_unpack_floats(attribute.data, NULL, 0); /* floats per element x num elements */
|
||||
|
||||
cgltf_accessor_unpack_floats(attribute.data, vs, n);
|
||||
|
||||
switch (attribute.type) {
|
||||
case cgltf_attribute_type_position:
|
||||
model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_normal:
|
||||
break;
|
||||
case cgltf_attribute_type_normal:
|
||||
has_norm = 1;
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_tangent:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_tangent:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_texcoord:
|
||||
break;
|
||||
}
|
||||
case cgltf_attribute_type_texcoord:
|
||||
model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_norm) {
|
||||
YughWarn("Model does not have normals. Generating them.");
|
||||
float norms[3 * model->meshes[j].face_count];
|
||||
|
||||
|
||||
cgltf_attribute *pa = get_attr_type(primitive, cgltf_attribute_type_position);
|
||||
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
||||
float ps[n];
|
||||
cgltf_accessor_unpack_floats(pa->data,ps,n);
|
||||
|
||||
for (int i = 0; i < model->meshes[j].face_count/3; i++) {
|
||||
int o = i*9;
|
||||
HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]};
|
||||
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
|
||||
for (int j = 0; j < 3; j++) {
|
||||
norms[i*9+j*3+0] = norm.X;
|
||||
norms[i*9+j*3+1] = norm.Y;
|
||||
norms[i*9+j*3+2] = norm.Z;
|
||||
}
|
||||
}
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = norms,
|
||||
.data.size = sizeof(float) * model->meshes[j].face_count * 3
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
HMM_Vec3 eye = {50,10,5};
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
||||
HMM_Mat4 proj = HMM_Perspective_RH_ZO(45, 1200.f / 720, 0.1, 10000);
|
||||
HMM_Vec3 center = {0.f, 0.f, 0.f};
|
||||
HMM_Vec3 up = {0.f, 1.f, 0.f};
|
||||
HMM_Mat4 view = HMM_LookAt_RH(eye, center, up);
|
||||
|
||||
HMM_Mat4 vp = HMM_MulM4(proj, view);
|
||||
HMM_Mat4 mvp = HMM_MulM4(vp, amodel);
|
||||
|
||||
HMM_Vec3 lp = {1, 1, 1};
|
||||
HMM_Vec3 dir_dir = HMM_NormV3(HMM_SubV3(center, dirl_pos));
|
||||
|
||||
HMM_Mat4 m2[4];
|
||||
m2[0] = view;
|
||||
m2[1] = amodel;
|
||||
m2[2] = proj;
|
||||
m2[3] = lsm;
|
||||
|
||||
HMM_Vec3 f_ubo[5];
|
||||
f_ubo[0] = lp;
|
||||
f_ubo[1] = dir_dir;
|
||||
f_ubo[2] = eye;
|
||||
f_ubo[3] = eye;
|
||||
f_ubo[4] = eye;
|
||||
|
||||
sg_apply_pipeline(model_pipe);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(m2));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(f_ubo));
|
||||
|
||||
|
||||
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||
sg_apply_bindings(&model->meshes[i].bind);
|
||||
sg_draw(0, model->meshes[i].face_count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: DELETE
|
||||
static void processnode() {
|
||||
|
||||
for (uint32_t i = 0; i < node->mNumMeshes; i++) {
|
||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
*mp = processMesh(mesh, scene);
|
||||
mp++;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < node->mNumChildren; i++) {
|
||||
processnode(node->mChildren[i], scene);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
static void processmesh() {
|
||||
/*
|
||||
Vertex *vertices =
|
||||
(Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices);
|
||||
Vertex *vp = vertices + mesh->mNumVertices;
|
||||
Vertex *p = vertices;
|
||||
for (int i = 0; i < mesh->mNumVertices; i++) {
|
||||
// positions
|
||||
(p + i)->Position.x = mesh->mVertices[i][0];
|
||||
(p + i)->Position.y = mesh->mVertices[i][1];
|
||||
(p + i)->Position.z = mesh->mVertices[i][2];
|
||||
|
||||
|
||||
// normals
|
||||
if (mesh->HasNormals()) {
|
||||
(p + i)->Normal.x = mesh->mNormals[i][0];
|
||||
(p + i)->Normal.y = mesh->mNormals[i].y;
|
||||
(p + i)->Normal.z = mesh->mNormals[i].z;
|
||||
}
|
||||
|
||||
// texture coordinates
|
||||
if (mesh->mTextureCoords[0]) {
|
||||
glm::vec2 vec;
|
||||
// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
|
||||
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
|
||||
(p + i)->TexCoords.x = mesh->mTextureCoords[0][i].x;
|
||||
(p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y;
|
||||
|
||||
// tangent
|
||||
(p + i)->Tangent.x = mesh->mTangents[i].x;
|
||||
(p + i)->Tangent.y = mesh->mTangents[i].y;
|
||||
(p + i)->Tangent.z = mesh->mTangents[i].z;
|
||||
|
||||
// bitangent
|
||||
(p + i)->Bitangent.x = mesh->mBitangents[i].x;
|
||||
(p + i)->Bitangent.y = mesh->mBitangents[i].y;
|
||||
(p + i)->Bitangent.z = mesh->mBitangents[i].z;
|
||||
|
||||
} else
|
||||
(p + i)->TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Done quickly, find better way. Go through for loop twice!
|
||||
int numindices = 0;
|
||||
// now walk through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
|
||||
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
numindices += mesh->mFaces[i].mNumIndices;
|
||||
}
|
||||
|
||||
uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices);
|
||||
uint32_t *ip = indices;
|
||||
|
||||
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) {
|
||||
*ip = mesh->mFaces[i].mIndices[j];
|
||||
ip++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// std::vector<Texture> textures;
|
||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
// TODO: Allocating 100 to be safe, can probably be way less
|
||||
textures_loaded = (Texture *) malloc(sizeof(Texture) * 100);
|
||||
tp = textures_loaded;
|
||||
// we assume a convention for sampler names in the shaders. Each diffuse texture should be named
|
||||
// as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
|
||||
// Same applies to other texture as the following list summarizes:
|
||||
// diffuse: texture_diffuseN
|
||||
// specular: texture_specularN
|
||||
// normal: texture_normalN
|
||||
|
||||
// 1. diffuse maps
|
||||
loadMaterialTextures(material, aiTextureType_DIFFUSE,
|
||||
"texture_diffuse");
|
||||
|
||||
// 2. specular maps
|
||||
loadMaterialTextures(material, aiTextureType_SPECULAR,
|
||||
"texture_specular");
|
||||
|
||||
// 3. normal maps
|
||||
loadMaterialTextures(material, aiTextureType_NORMALS,
|
||||
"texture_normal");
|
||||
|
||||
// 4. height maps
|
||||
loadMaterialTextures(material, aiTextureType_AMBIENT,
|
||||
"texture_height");
|
||||
|
||||
|
||||
// return a mesh object created from the extracted mesh data
|
||||
return Mesh(vertices, vp, indices, ip, textures_loaded, tp);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO: This routine mallocs inside the function
|
||||
static void processtexture() {
|
||||
/*
|
||||
for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
for (Texture * tpp = textures_loaded; tpp != tp; tpp++) {
|
||||
if (strcmp(tpp->path, str.data) == 0)
|
||||
goto next; // Check if we already have this texture
|
||||
}
|
||||
|
||||
tp->id = TextureFromFile(str.data, this->directory);
|
||||
tp->type = (char *) malloc(sizeof(char) * strlen(typeName));
|
||||
strcpy(tp->type, typeName);
|
||||
tp->path = (char *) malloc(sizeof(char) * strlen(str.data));
|
||||
strcpy(tp->path, str.data);
|
||||
|
||||
tp++;
|
||||
|
||||
next:;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void draw_models(struct model *model, struct shader *shader)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TODO: Come back to this; simple optimization
|
||||
void draw_model(struct model *model, struct shader *shader) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
struct mesh;
|
||||
#include "mesh.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
extern HMM_Vec3 eye;
|
||||
struct shader;
|
||||
|
||||
struct model {
|
||||
struct mesh *meshes;
|
||||
struct mesh *mp;
|
||||
struct mesh *meshes;
|
||||
};
|
||||
|
||||
/* Get the model at a path, or create and return if it doesn't exist */
|
||||
@@ -18,7 +20,9 @@ struct model *MakeModel(const char *path);
|
||||
/* Load a model from memory into the GPU */
|
||||
void loadmodel(struct model *model);
|
||||
|
||||
void draw_model(struct model *model, struct shader *shader);
|
||||
void model_init();
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm);
|
||||
void draw_models(struct model *model, struct shader *shader);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "skybox.h"
|
||||
|
||||
#include "shader.h"
|
||||
#include "camera.h"
|
||||
#include <string.h>
|
||||
#include "shader.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "openglrender.h"
|
||||
|
||||
@@ -48,82 +48,79 @@ static const float skyboxVertices[216] = {
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f
|
||||
};
|
||||
1.0f, -1.0f, 1.0f};
|
||||
|
||||
struct mSkybox *MakeSkybox(const char *cubemap)
|
||||
{
|
||||
/*
|
||||
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
||||
struct mSkybox *MakeSkybox(const char *cubemap) {
|
||||
/*
|
||||
struct mSkybox *newskybox = malloc(sizeof(struct mSkybox));
|
||||
|
||||
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
||||
shader_compile(newskybox->shader);
|
||||
newskybox->shader = MakeShader("skyvert.glsl", "skyfrag.glsl");
|
||||
shader_compile(newskybox->shader);
|
||||
|
||||
glGenVertexArrays(1, &newskybox->VAO);
|
||||
glGenBuffers(1, &newskybox->VBO);
|
||||
glBindVertexArray(newskybox->VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
||||
(void *) 0);
|
||||
glGenVertexArrays(1, &newskybox->VAO);
|
||||
glGenBuffers(1, &newskybox->VBO);
|
||||
glBindVertexArray(newskybox->VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, newskybox->VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
|
||||
(void *) 0);
|
||||
|
||||
shader_use(newskybox->shader);
|
||||
shader_setint(newskybox->shader, "skybox", 0);
|
||||
*/
|
||||
/*
|
||||
const char *faces[6] =
|
||||
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
||||
"back.jpg"
|
||||
};
|
||||
*/
|
||||
/*
|
||||
glGenTextures(1, &newskybox->id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
||||
*/
|
||||
/*char buf[100] = { '\0' };*/
|
||||
shader_use(newskybox->shader);
|
||||
shader_setint(newskybox->shader, "skybox", 0);
|
||||
*/
|
||||
/*
|
||||
const char *faces[6] =
|
||||
{ "right.jpg", "left.jpg", "top.jpg", "bottom.jpg", "front.jpg",
|
||||
"back.jpg"
|
||||
};
|
||||
*/
|
||||
/*
|
||||
glGenTextures(1, &newskybox->id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, newskybox->id);
|
||||
*/
|
||||
/*char buf[100] = { '\0' };*/
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
/*
|
||||
buf[0] = '\0';
|
||||
strcat(buf, cubemap);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, faces[i]);
|
||||
IMG_Load(buf);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
||||
2048, 0, GL_RGB, GL_UNSIGNED_BYTE, data->pixels);
|
||||
buf[0] = '\0';
|
||||
strcat(buf, cubemap);
|
||||
strcat(buf, "/");
|
||||
strcat(buf, faces[i]);
|
||||
IMG_Load(buf);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 2048,
|
||||
2048, 0, GL_RGB, GL_UNSIGNED_BYTE, data->pixels);
|
||||
*/
|
||||
}
|
||||
/*
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
/*
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
||||
return newskybox;
|
||||
*/
|
||||
return newskybox;
|
||||
*/
|
||||
}
|
||||
|
||||
void skybox_draw(const struct mSkybox *skybox,
|
||||
const struct mCamera *camera)
|
||||
{
|
||||
/*
|
||||
shader_use(skybox->shader);
|
||||
const struct mCamera *camera) {
|
||||
/*
|
||||
shader_use(skybox->shader);
|
||||
|
||||
mfloat_t view[16] = { 0.f };
|
||||
getviewmatrix(view, camera);
|
||||
shader_setmat4(skybox->shader, "skyview", view);
|
||||
mfloat_t view[16] = { 0.f };
|
||||
getviewmatrix(view, camera);
|
||||
shader_setmat4(skybox->shader, "skyview", view);
|
||||
|
||||
// skybox cube
|
||||
glBindVertexArray(skybox->VAO);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
*/
|
||||
// skybox cube
|
||||
glBindVertexArray(skybox->VAO);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
struct mCamera;
|
||||
|
||||
struct mSkybox {
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
unsigned int id;
|
||||
struct shader *shader;
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
unsigned int id;
|
||||
struct shader *shader;
|
||||
};
|
||||
|
||||
struct mSkybox *MakeSkybox(const char *cubemap);
|
||||
void skybox_draw(const struct mSkybox *skybox,
|
||||
const struct mCamera *camera);
|
||||
const struct mCamera *camera);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user