Skip to content

Commit

Permalink
Sprite renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
UnrealKaraulov committed Dec 30, 2023
1 parent 5630e2f commit f862679
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/bsp/Bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ Bsp::Bsp(std::string fpath)
is_mdl_model = true;
if (fileExists(fpath))
{
mdl = AddNewModelToRender(fpath.c_str());
mdl = AddNewModelToRender(fpath);
}
init_empty_bsp();
return;
Expand Down
117 changes: 81 additions & 36 deletions src/bsp/Sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include "Sprite.h"
#include "util.h"
#include "lodepng.h"
#include "Renderer.h"
#include "Settings.h"
#include "forcecrc32.h"

Sprite::~Sprite()
{
Expand All @@ -13,6 +16,10 @@ Sprite::~Sprite()
{
delete s.texture;
}
if (s.spriteCube)
{
delete s.spriteCube;
}
}
g.sprites.clear();
}
Expand All @@ -25,7 +32,7 @@ Sprite::Sprite(const std::string& filename)
{
return;
}

this->name = stripExt(basename(filename));

std::ifstream spr(filename, std::ios::binary);
Expand All @@ -36,7 +43,7 @@ Sprite::Sprite(const std::string& filename)

int id, version;
spr.read(reinterpret_cast<char*>(&id), sizeof(id));
if (id != 'PSDI')
if (id != 'PSDI')
{
print_log(PRINT_RED, "Not a sprite {}\n", filename);
return;
Expand All @@ -55,70 +62,108 @@ Sprite::Sprite(const std::string& filename)

sprite_groups.resize(header.numframes);

for (int i = 0; i < header.numframes; ++i) {
for (int i = 0; i < header.numframes; ++i)
{
int is_group;
spr.read(reinterpret_cast<char*>(&is_group), sizeof(int));

if (is_group == 0) {
SpriteImage tmpSpriteImage{};
int group_frames = 1;

if (is_group != 0) {
spr.read(reinterpret_cast<char*>(&group_frames), sizeof(int));
sprite_groups[i].sprites.resize(group_frames);
for (int j = 0; j < group_frames; ++j) {
spr.read(reinterpret_cast<char*>(&sprite_groups[i].sprites[j].interval), sizeof(float));
sprite_groups[i].totalinterval += sprite_groups[i].sprites[j].interval;
}
}
else
{
sprite_groups[i].sprites.resize(group_frames);
sprite_groups[i].totalinterval = 0.1f;
sprite_groups[i].sprites[0].interval = 0.1f;
}

for (int j = 0; j < group_frames; ++j)
{
SpriteImage& tmpSpriteImage = sprite_groups[i].sprites[j];

spr.read(reinterpret_cast<char*>(&tmpSpriteImage.frameinfo), sizeof(dspriteframe_t));

int frame_size = tmpSpriteImage.frameinfo.width * tmpSpriteImage.frameinfo.height;
tmpSpriteImage.raw_image.resize(frame_size);

spr.read(reinterpret_cast<char*>(tmpSpriteImage.raw_image.data()), frame_size);

tmpSpriteImage.image.reserve(frame_size);
tmpSpriteImage.image.resize(frame_size);
for (int s = 0; s < frame_size; s++)
{
tmpSpriteImage.image.push_back(palette[tmpSpriteImage.raw_image[s]]);
tmpSpriteImage.image[s] = palette[tmpSpriteImage.raw_image[s]];
}
sprite_groups[i].totalinterval = tmpSpriteImage.interval = 0.1f;

tmpSpriteImage.spriteCube = new EntCube();
tmpSpriteImage.spriteCube->mins = { -4.0f, 0.0f, 0.0f };
tmpSpriteImage.spriteCube->maxs = { 4.0f, tmpSpriteImage.frameinfo.width * 1.0f, tmpSpriteImage.frameinfo.height * 1.0f };
tmpSpriteImage.spriteCube->mins += vec3(0.0f, tmpSpriteImage.frameinfo.origin[0] * 1.0f, tmpSpriteImage.frameinfo.origin[1] * -1.0f);
tmpSpriteImage.spriteCube->maxs += vec3(0.0f, tmpSpriteImage.frameinfo.origin[0] * 1.0f, tmpSpriteImage.frameinfo.origin[1] * -1.0f);
tmpSpriteImage.spriteCube->Textured = true;
g_app->pointEntRenderer->genCubeBuffers(tmpSpriteImage.spriteCube);

tmpSpriteImage.texture = new Texture(tmpSpriteImage.frameinfo.width,
tmpSpriteImage.frameinfo.height, (unsigned char*)&tmpSpriteImage.image[0], fmt::format("{}_g{}_f{}", name, i, 1),false,false);
sprite_groups[i].sprites.push_back(tmpSpriteImage);
continue;
tmpSpriteImage.frameinfo.height, (unsigned char*)&tmpSpriteImage.image[0], fmt::format("{}_g{}_f{}", name, i, j), false, false);
tmpSpriteImage.texture->upload(Texture::TEXTURE_TYPE::TYPE_DECAL);
}
}
}

int group_frames;
spr.read(reinterpret_cast<char*>(&group_frames), sizeof(int));

sprite_groups[i].sprites.resize(group_frames);

for (int j = 0; j < group_frames; ++j) {
spr.read(reinterpret_cast<char*>(&sprite_groups[i].sprites[j].interval), sizeof(float));
sprite_groups[i].totalinterval += sprite_groups[i].sprites[j].interval;
}
std::map<int, Sprite*> spr_models;

for (int j = 0; j < group_frames; ++j) {
spr.read(reinterpret_cast<char*>(&sprite_groups[i].sprites[j].frameinfo), sizeof(dspriteframe_t));
int frame_size = sprite_groups[i].sprites[j].frameinfo.width * sprite_groups[i].sprites[j].frameinfo.height;
sprite_groups[i].sprites[j].raw_image.resize(frame_size);
spr.read(reinterpret_cast<char*>(sprite_groups[i].sprites[j].raw_image.data()), frame_size);

sprite_groups[i].sprites[j].image.reserve(frame_size);
for (int s = 0; s < frame_size; s++)
{
sprite_groups[i].sprites[j].image.push_back(palette[sprite_groups[i].sprites[j].raw_image[s]]);
}
Sprite* AddNewSpriteToRender(const std::string & path, unsigned int sum)
{
unsigned int crc32 = GetCrc32InMemory((unsigned char*)path.data(), path.size(), sum);

sprite_groups[i].sprites[j].texture = new Texture(sprite_groups[i].sprites[j].frameinfo.width,
sprite_groups[i].sprites[j].frameinfo.height, (unsigned char*)&sprite_groups[i].sprites[j].image[0], fmt::format("{}_g{}_f{}", name, i, j), false, false);
}
if (spr_models.find(crc32) != spr_models.end())
{
return spr_models[crc32];
}
else
{
Sprite* newModel = new Sprite(path);
spr_models[crc32] = newModel;
return newModel;
}
}



void TestSprite()
{
Sprite tmpSprite("d:\\SteamLibrary\\steamapps\\common\\Half-Life\\cstrike\\sprites\\pistol_smoke1.spr");
Sprite * tmpSprite = AddNewSpriteToRender("d:\\SteamLibrary\\steamapps\\common\\Half-Life\\cstrike\\sprites\\pistol_smoke1.spr");
int fileid = 0;
int groupid = 0;
for (auto& g : tmpSprite.sprite_groups)
for (auto& g : tmpSprite->sprite_groups)
{
groupid++;
for (auto& s : g.sprites)
{
fileid++;
lodepng_encode24_file(fmt::format("TestFile_group{}_file{}.png", groupid, fileid).c_str(), (unsigned char*)&s.image[0], s.frameinfo.width, s.frameinfo.height);
lodepng_encode24_file(fmt::format("{}_group{}_file{}.png", tmpSprite->name, groupid, fileid).c_str(), (unsigned char*)&s.image[0], s.frameinfo.width, s.frameinfo.height);
}
fileid = 0;
}
}
tmpSprite = AddNewSpriteToRender("d:/SteamLibrary/steamapps/common/Half-Life/valve/sprites/glow01.spr");
fileid = 0;
groupid = 0;
for (auto& g : tmpSprite->sprite_groups)
{
groupid++;
for (auto& s : g.sprites)
{
fileid++;
lodepng_encode24_file(fmt::format("{}_group{}_file{}.png", tmpSprite->name, groupid, fileid).c_str(), (unsigned char*)&s.image[0], s.frameinfo.width, s.frameinfo.height);
}
fileid = 0;
}
}
9 changes: 7 additions & 2 deletions src/bsp/Sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <array>
#include "Wad.h"
#include "Texture.h"
#include "PointEntRenderer.h"

#pragma pack(push, 1)

Expand Down Expand Up @@ -44,6 +45,8 @@ struct dspriteframe_t {
int width;
int height;
};
#pragma pack(pop)


struct SpriteImage
{
Expand All @@ -52,6 +55,7 @@ struct SpriteImage
std::vector<unsigned char> raw_image;
float interval;
Texture* texture;
EntCube* spriteCube;
};

struct SpriteGroup
Expand All @@ -71,6 +75,7 @@ class Sprite {
std::vector<SpriteGroup> sprite_groups;
};

#pragma pack(pop)
void TestSprite();

void TestSprite();
extern std::map<int, Sprite*> spr_models;
Sprite* AddNewSpriteToRender(const std::string & path, unsigned int sum = 0);
Loading

0 comments on commit f862679

Please sign in to comment.