New cars, static model rendering and stuff
This commit is contained in:
parent
899b0f990c
commit
7e1496bd70
@ -26,10 +26,14 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
|
||||
glm::vec3 angles;
|
||||
|
||||
iss >> obj.transform.position.x >> obj.transform.position.y >> obj.transform.position.z;
|
||||
auto trans = &obj.node.local;
|
||||
|
||||
iss >> trans->position.x >> trans->position.y >> trans->position.z;
|
||||
iss >> angles.x >> angles.y >> angles.z;
|
||||
obj.transform.SetAngles(angles);
|
||||
iss >> obj.transform.scale;
|
||||
trans->SetAngles(angles);
|
||||
iss >> trans->scale;
|
||||
|
||||
obj.node.UpdateMatrix();
|
||||
|
||||
std::string flag;
|
||||
while (iss >> flag)
|
||||
@ -62,5 +66,22 @@ void assets::Map::Draw(gfx::DrawList& dlist) const
|
||||
cmd.surface = &surface;
|
||||
dlist.AddSurface(cmd);
|
||||
}
|
||||
|
||||
for (const auto& obj : static_objects_)
|
||||
{
|
||||
if (!obj.model || !obj.model->GetMesh())
|
||||
continue;
|
||||
|
||||
const auto& surfaces = obj.model->GetMesh()->surfaces;
|
||||
|
||||
for (const auto& surface : surfaces)
|
||||
{
|
||||
gfx::DrawSurfaceCmd cmd;
|
||||
cmd.surface = &surface;
|
||||
cmd.matrices = &obj.node.matrix;
|
||||
// cmd.color_mod = glm::vec4(obj.color, 1.0f);
|
||||
dlist.AddSurface(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CLIENT
|
||||
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "model.hpp"
|
||||
#include "utils/transform.hpp"
|
||||
#include "game/transform_node.hpp"
|
||||
|
||||
#ifdef CLIENT
|
||||
#include "gfx/draw_list.hpp"
|
||||
@ -15,7 +15,7 @@ namespace assets
|
||||
|
||||
struct MapStaticObject
|
||||
{
|
||||
Transform transform;
|
||||
game::TransformNode node;
|
||||
std::shared_ptr<const Model> model;
|
||||
glm::vec3 color = glm::vec3(1.0f);
|
||||
};
|
||||
|
||||
@ -76,14 +76,21 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
{
|
||||
CLIENT_ONLY(sflags |= gfx::SF_2SIDED;)
|
||||
}
|
||||
else if (flag == "+transparent")
|
||||
{
|
||||
CLIENT_ONLY(sflags |= gfx::SF_TRANSPARENT;)
|
||||
}
|
||||
else if (flag == "+ocolor")
|
||||
{
|
||||
CLIENT_ONLY(sflags |= gfx::SF_OBJECT_COLOR;)
|
||||
}
|
||||
else if (flag == "+blend")
|
||||
{
|
||||
std::string blend_str;
|
||||
iss >> blend_str;
|
||||
|
||||
CLIENT_ONLY(
|
||||
sflags |= gfx::SF_BLEND;
|
||||
if (blend_str == "additive")
|
||||
sflags |= gfx::SF_BLEND_ADDITIVE;
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CLIENT_ONLY(
|
||||
@ -128,7 +135,8 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
|
||||
// Optional but recommended
|
||||
auto shape_hull = std::make_unique<btShapeHull>(temp_hull.get());
|
||||
shape_hull->buildHull(temp_hull->getMargin());
|
||||
// shape_hull->buildHull(temp_hull->getMargin());
|
||||
shape_hull->buildHull(0.01f);
|
||||
|
||||
model->cshape_ = std::make_unique<btConvexHullShape>((btScalar*)shape_hull->getVertexPointer(), shape_hull->numVertices(), sizeof(btVector3));
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ void App::Frame()
|
||||
float aspect = static_cast<float>(viewport_size_.x) / static_cast<float>(viewport_size_.y);
|
||||
|
||||
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
||||
renderer_.ClearColor(glm::vec3(0.3f, 0.9f, 1.0f));
|
||||
renderer_.ClearColor(glm::vec3(0.5f, 0.7f, 1.0f));
|
||||
renderer_.ClearDepth();
|
||||
|
||||
dlist_.Clear();
|
||||
|
||||
@ -15,7 +15,11 @@
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#pragma comment(lib, "ws2_32")
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#include <WinSock2.h>
|
||||
#include <windows.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#include "app.hpp"
|
||||
@ -391,11 +395,26 @@ static void Main() {
|
||||
emscripten_set_main_loop(Frame, 0, true);
|
||||
#else
|
||||
|
||||
#ifdef _WIN32
|
||||
timeBeginPeriod(1);
|
||||
#endif
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
|
||||
auto frame_dur = std::chrono::milliseconds(5);
|
||||
|
||||
while (!s_quit)
|
||||
{
|
||||
auto t_start = std::chrono::steady_clock::now();
|
||||
|
||||
Frame();
|
||||
|
||||
auto t_next = t_start + frame_dur;
|
||||
auto t_now = std::chrono::steady_clock::now();
|
||||
|
||||
if (t_now < t_next)
|
||||
{
|
||||
std::this_thread::sleep_for(t_next - t_now);
|
||||
}
|
||||
}
|
||||
|
||||
s_app.reset();
|
||||
|
||||
@ -38,7 +38,7 @@ void collision::DynamicsWorld::AddMapCollision()
|
||||
// add static objects
|
||||
for (const auto& sobjs = map_->GetStaticObjects(); const auto& sobj : sobjs)
|
||||
{
|
||||
AddModelInstance(*sobj.model, sobj.transform);
|
||||
AddModelInstance(*sobj.model, sobj.node.local);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
#include "player.hpp"
|
||||
#include "vehicle.hpp"
|
||||
|
||||
game::OpenWorld::OpenWorld() : World("openworld") {}
|
||||
game::OpenWorld::OpenWorld() : World("openworld")
|
||||
{
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
void game::OpenWorld::PlayerJoined(Player& player)
|
||||
{
|
||||
@ -69,7 +72,7 @@ void game::OpenWorld::SpawnVehicle(Player& player)
|
||||
|
||||
// spawn him car
|
||||
// random model
|
||||
const char* vehicles[] = {"pickup", "passat"};
|
||||
const char* vehicles[] = {"pickup_hd", "passat", "twingo", "polskifiat"};
|
||||
auto vehicle_name = vehicles[rand() % (sizeof(vehicles) / sizeof(vehicles[0]))];
|
||||
|
||||
// ranodm color
|
||||
|
||||
@ -67,7 +67,7 @@ void game::view::ClientSession::Update(const UpdateInfo& info)
|
||||
|
||||
glm::mat4 game::view::ClientSession::GetViewMatrix() const
|
||||
{
|
||||
glm::vec3 center(0, 0, 3);
|
||||
glm::vec3 center(0.0f, 0.0f, 2.5f);
|
||||
|
||||
if (world_ && follow_ent_)
|
||||
{
|
||||
@ -82,7 +82,7 @@ glm::mat4 game::view::ClientSession::GetViewMatrix() const
|
||||
float pitch_sin = glm::sin(pitch_);
|
||||
glm::vec3 dir(yaw_sin * pitch_cos, yaw_cos * pitch_cos, pitch_sin);
|
||||
|
||||
float distance = 10.0f;
|
||||
float distance = 8.0f;
|
||||
|
||||
auto eye = center - dir * distance;
|
||||
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
|
||||
#include "client/gl.hpp"
|
||||
|
||||
#include "gfx/shader_sources.hpp"
|
||||
#include "shader_sources.hpp"
|
||||
#include "shader_defs.hpp"
|
||||
|
||||
gfx::Renderer::Renderer()
|
||||
{
|
||||
@ -81,15 +82,15 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
||||
const Surface* sa = a.surface;
|
||||
const Surface* sb = b.surface;
|
||||
|
||||
const bool trans_a = sa->sflags & SF_TRANSPARENT;
|
||||
const bool trans_b = sb->sflags & SF_TRANSPARENT;
|
||||
const bool blend_a = sa->sflags & SF_BLEND;
|
||||
const bool blend_b = sb->sflags & SF_BLEND;
|
||||
|
||||
if (trans_a != trans_b)
|
||||
return trans_b; // opaque first
|
||||
if (blend_a != blend_b)
|
||||
return blend_b; // opaque first
|
||||
|
||||
if (trans_a) // both transparent
|
||||
if (blend_a) // both blended
|
||||
{
|
||||
return a.dist > b.dist; // do not optimize transparent, sort by distance instead
|
||||
return a.dist > b.dist; // do not optimize blended, sort by distance instead
|
||||
}
|
||||
|
||||
if (auto cmp = sa <=> sb; cmp != 0)
|
||||
@ -104,22 +105,28 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
||||
return false;
|
||||
});
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
InvalidateShaders();
|
||||
glActiveTexture(GL_TEXTURE0); // for all future bindings
|
||||
|
||||
// cache to eliminate fake state changes
|
||||
const gfx::Texture* last_texture = nullptr;
|
||||
const gfx::VertexArray* last_vao = nullptr;
|
||||
InvalidateShaders();
|
||||
|
||||
// enable depth test
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
// reset face culling
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
bool last_twosided = false;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0); // for all future bindings
|
||||
// reset blending
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
bool last_blend = false;
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set to opacity blending default
|
||||
bool last_blend_additive = false;
|
||||
|
||||
for (const DrawSurfaceCmd& cmd : list)
|
||||
{
|
||||
@ -129,7 +136,7 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
||||
const bool skeletal_flag = surface->mflags & MF_SKELETAL;
|
||||
// surface flags
|
||||
const bool twosided_flag = surface->sflags & SF_2SIDED;
|
||||
const bool transparent_flag = surface->sflags & SF_TRANSPARENT;
|
||||
const bool blend_flag = surface->sflags & SF_BLEND;
|
||||
const bool object_color_flag = surface->sflags & SF_OBJECT_COLOR;
|
||||
|
||||
// sync 2sided
|
||||
@ -159,21 +166,56 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
||||
}
|
||||
|
||||
// set color
|
||||
bool cull_alpha = true;
|
||||
glm::vec4 color = glm::vec4(1.0f);
|
||||
int shflags = SHF_CULL_ALPHA;
|
||||
|
||||
glm::vec4 color = glm::vec4(1.0f);
|
||||
if (object_color_flag && cmd.color)
|
||||
{
|
||||
// use object color and disable alpha cull
|
||||
cull_alpha = false;
|
||||
shflags &= ~SHF_CULL_ALPHA;
|
||||
shflags |= SHF_BACKGROUND;
|
||||
color = glm::vec4(*cmd.color);
|
||||
}
|
||||
|
||||
// sync cull_alpha
|
||||
if (mshader.cull_alpha != cull_alpha)
|
||||
// sync blending
|
||||
if (blend_flag != last_blend)
|
||||
{
|
||||
glUniform1i(mshader.shader->U(SU_CULL_ALPHA), cull_alpha ? 1 : 0);
|
||||
mshader.cull_alpha = cull_alpha;
|
||||
if (blend_flag)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
last_blend = blend_flag;
|
||||
}
|
||||
|
||||
// sync blending type
|
||||
if (blend_flag)
|
||||
{
|
||||
shflags &= ~SHF_CULL_ALPHA;
|
||||
|
||||
const bool blend_additive = surface->sflags & SF_BLEND_ADDITIVE;
|
||||
if (blend_additive != last_blend_additive)
|
||||
{
|
||||
if (blend_additive)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
else
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
last_blend_additive = blend_additive;
|
||||
}
|
||||
|
||||
// sync cull_alpha
|
||||
if (mshader.flags != shflags)
|
||||
{
|
||||
glUniform1i(mshader.shader->U(SU_FLAGS), shflags);
|
||||
mshader.flags = shflags;
|
||||
}
|
||||
|
||||
// sync color
|
||||
@ -206,7 +248,8 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
||||
(void*)(first_tri * 3U * sizeof(GLuint)));
|
||||
}
|
||||
|
||||
|
||||
// reset this as it is rare and other stuff might not reset this
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ namespace gfx
|
||||
// cached state to avoid redundant uniform updates which are expensive especially on WebGL
|
||||
bool global_setup = false;
|
||||
glm::vec4 color = glm::vec4(-1.0f); // invalid to force initial setup
|
||||
bool cull_alpha = false;
|
||||
int flags = 0;
|
||||
};
|
||||
|
||||
class Renderer
|
||||
|
||||
@ -9,7 +9,7 @@ static const char* const s_uni_names[] = {
|
||||
"u_view_proj", // SU_VIEW_PROJ
|
||||
"u_tex", // SU_TEX
|
||||
"u_color", // SU_COLOR
|
||||
"u_cull_alpha", // SU_COLOR
|
||||
"u_flags", // SU_FLAGS
|
||||
};
|
||||
|
||||
// Vytvori shader z daneho zdroje
|
||||
|
||||
@ -14,7 +14,7 @@ namespace gfx
|
||||
SU_VIEW_PROJ,
|
||||
SU_TEX,
|
||||
SU_COLOR,
|
||||
SU_CULL_ALPHA,
|
||||
SU_FLAGS,
|
||||
|
||||
SU_COUNT
|
||||
};
|
||||
|
||||
@ -2,3 +2,6 @@
|
||||
|
||||
#define SD_MAX_LIGHTS 4
|
||||
#define SD_MAX_BONES 256
|
||||
|
||||
#define SHF_CULL_ALPHA 1
|
||||
#define SHF_BACKGROUND 2
|
||||
@ -40,12 +40,12 @@
|
||||
#define COMPUTE_LIGHTS_GLSL R"GLSL(
|
||||
// Example sun values (can later be uniforms)
|
||||
vec3 u_sun_direction = normalize(vec3(0.3, 0.5, -0.8)); // direction from which sunlight comes
|
||||
vec3 u_sun_color = vec3(1.0, 0.95, 0.7); // warm sunlight color
|
||||
vec3 u_sun_color = vec3(1.0, 0.95, 0.7) * 0.9; // warm sunlight color
|
||||
|
||||
vec3 ComputeLights(in vec3 sector_pos, in vec3 sector_normal)
|
||||
{
|
||||
// Base ambient
|
||||
vec3 color = vec3(0.5, 0.5, 0.5); // u_ambient_light
|
||||
vec3 color = vec3(0.5, 0.5, 0.5) * 0.9; // u_ambient_light
|
||||
|
||||
// Sunlight contribution
|
||||
float sun_dot = max(dot(sector_normal, -u_sun_direction), 0.0);
|
||||
@ -107,21 +107,24 @@ R"GLSL(
|
||||
in vec2 v_uv;
|
||||
in vec3 v_color;
|
||||
|
||||
#define SHF_CULL_ALPHA 1
|
||||
#define SHF_BACKGROUND 2
|
||||
|
||||
uniform sampler2D u_tex;
|
||||
uniform vec4 u_color;
|
||||
uniform bool u_cull_alpha;
|
||||
uniform int u_flags;
|
||||
|
||||
layout (location = 0) out vec4 o_color;
|
||||
|
||||
void main() {
|
||||
o_color = vec4(texture(u_tex, v_uv));
|
||||
|
||||
if (u_cull_alpha)
|
||||
if ((u_flags & SHF_CULL_ALPHA) > 0)
|
||||
{
|
||||
if (o_color.a < 0.5)
|
||||
discard;
|
||||
}
|
||||
else
|
||||
else if ((u_flags & SHF_BACKGROUND) > 0)
|
||||
{
|
||||
// blend with bg
|
||||
o_color = mix(u_color, o_color, o_color.a);
|
||||
|
||||
@ -20,9 +20,10 @@ using SurfaceFlags = uint8_t;
|
||||
enum SurfaceFlag : SurfaceFlags
|
||||
{
|
||||
SF_NONE = 0x00,
|
||||
SF_2SIDED = 0x01,
|
||||
SF_TRANSPARENT = 0x02,
|
||||
SF_OBJECT_COLOR = 0x08, // use object level tint
|
||||
SF_2SIDED = 0x01, // disable backface culling
|
||||
SF_BLEND = 0x02, // enable blending, disable depth write
|
||||
SF_BLEND_ADDITIVE = 0x04, // use additive blending instead of opacity
|
||||
SF_OBJECT_COLOR = 0x08, // use object color for background instead of alpha culling
|
||||
};
|
||||
|
||||
struct Surface
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user