1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-08 06:06:51 +02:00

- pack all textures to one atlas (trivial)

This commit is contained in:
XProger
2016-08-18 23:20:13 +03:00
parent d1af898609
commit 10b48368e7
6 changed files with 114 additions and 89 deletions

View File

@@ -499,7 +499,7 @@ namespace TR {
// read version // read version
stream.read(version); stream.read(version);
// tiles // tiles
tiles = stream.readArray<Tile8>(stream.read(tilesCount)); stream.readArray(tiles, stream.read(tilesCount));
stream.read(unused); stream.read(unused);
// rooms // rooms
rooms = new Room[stream.read(roomsCount)]; rooms = new Room[stream.read(roomsCount)];
@@ -511,70 +511,69 @@ namespace TR {
// room data // room data
stream.read(d.size); stream.read(d.size);
int pos = stream.pos; int pos = stream.pos;
d.vertices = stream.readArray<Room::Data::Vertex>(stream.read(d.vCount)); stream.readArray(d.vertices, stream.read(d.vCount));
d.rectangles = stream.readArray<Rectangle>(stream.read(d.rCount)); stream.readArray(d.rectangles, stream.read(d.rCount));
d.triangles = stream.readArray<Triangle>(stream.read(d.tCount)); stream.readArray(d.triangles, stream.read(d.tCount));
d.sprites = stream.readArray<Room::Data::Sprite>(stream.read(d.sCount)); stream.readArray(d.sprites, stream.read(d.sCount));
stream.setPos(pos + d.size * 2); stream.setPos(pos + d.size * 2);
// portals // portals
r.portals = stream.readArray<Room::Portal>(stream.read(r.portalsCount)); stream.readArray(r.portals, stream.read(r.portalsCount));
// sectors // sectors
stream.read(r.zSectors); stream.read(r.zSectors);
stream.read(r.xSectors); stream.read(r.xSectors);
r.sectors = stream.readArray<Room::Sector>(r.zSectors * r.xSectors); stream.readArray(r.sectors, r.zSectors * r.xSectors);
// ambient light luminance // ambient light luminance
stream.read(r.ambient); stream.read(r.ambient);
// lights // lights
r.lights = stream.readArray<Room::Light>(stream.read(r.lightsCount)); stream.readArray(r.lights, stream.read(r.lightsCount));
// meshes // meshes
r.meshes = stream.readArray<Room::Mesh>(stream.read(r.meshesCount)); stream.readArray(r.meshes, stream.read(r.meshesCount));
stream.read(r.alternateRoom); stream.read(r.alternateRoom);
stream.read(r.flags); stream.read(r.flags);
} }
// floors // floors
floors = stream.readArray<uint16>(stream.read(floorsCount)); stream.readArray(floors, stream.read(floorsCount));
// meshes // meshes
meshData = stream.readArray<uint16>(stream.read(meshDataSize)); stream.readArray(meshData, stream.read(meshDataSize));
meshOffsets = stream.readArray<uint32>(stream.read(meshOffsetsCount)); stream.readArray(meshOffsets, stream.read(meshOffsetsCount));
// animations // animations
anims = stream.readArray<Animation>(stream.read(animsCount)); stream.readArray(anims, stream.read(animsCount));
states = stream.readArray<AnimState>(stream.read(statesCount)); stream.readArray(states, stream.read(statesCount));
ranges = stream.readArray<AnimRange>(stream.read(rangesCount)); stream.readArray(ranges, stream.read(rangesCount));
commands = stream.readArray<int16>(stream.read(commandsCount)); stream.readArray(commands, stream.read(commandsCount));
nodesData = stream.readArray<uint32>(stream.read(nodesDataSize)); stream.readArray(nodesData, stream.read(nodesDataSize));
frameData = stream.readArray<uint16>(stream.read(frameDataSize)); stream.readArray(frameData, stream.read(frameDataSize));
// models // models
models = stream.readArray<Model>(stream.read(modelsCount)); stream.readArray(models, stream.read(modelsCount));
staticMeshes = stream.readArray<StaticMesh>(stream.read(staticMeshesCount)); stream.readArray(staticMeshes, stream.read(staticMeshesCount));
// textures & UV // textures & UV
objectTextures = stream.readArray<ObjectTexture>(stream.read(objectTexturesCount)); stream.readArray(objectTextures, stream.read(objectTexturesCount));
spriteTextures = stream.readArray<SpriteTexture>(stream.read(spriteTexturesCount)); stream.readArray(spriteTextures, stream.read(spriteTexturesCount));
spriteSequences = stream.readArray<SpriteSequence>(stream.read(spriteSequencesCount)); stream.readArray(spriteSequences, stream.read(spriteSequencesCount));
// cameras // cameras
camera = stream.readArray<Camera>(stream.read(camerasCount)); stream.readArray(camera, stream.read(camerasCount));
// sound sources // sound sources
soundSources = stream.readArray<SoundSource>(stream.read(soundSourcesCount)); stream.readArray(soundSources, stream.read(soundSourcesCount));
// AI // AI
boxes = stream.readArray<Box>(stream.read(boxesCount)); stream.readArray(boxes, stream.read(boxesCount));
overlaps = stream.readArray<uint16>(stream.read(overlapsCount)); stream.readArray(overlaps, stream.read(overlapsCount));
zones = stream.readArray<Zone>(boxesCount); stream.readArray(zones, boxesCount);
// animated textures // animated textures
animTexturesData = stream.readArray<uint16>(stream.read(animTexturesDataSize)); stream.readArray(animTexturesData, stream.read(animTexturesDataSize));
// entities (enemies, items, lara etc.) // entities (enemies, items, lara etc.)
entities = stream.readArray<Entity>(stream.read(entitiesCount)); stream.readArray(entities, stream.read(entitiesCount));
// palette // palette
stream.seek(32 * 256); // skip lightmap palette stream.seek(32 * 256); // skip lightmap palette
palette = stream.readArray<RGB>(256); stream.readArray(palette, 256);
// cinematic frames for cameras // cinematic frames for cameras
cameraFrames = stream.readArray<CameraFrame>(stream.read(cameraFramesCount)); stream.readArray(cameraFrames, stream.read(cameraFramesCount));
// demo data // demo data
demoData = stream.readArray<uint8>(stream.read(demoDataSize)); stream.readArray(demoData, stream.read(demoDataSize));
// sounds // sounds
soundsMap = stream.readArray<int16>(256); stream.readArray(soundsMap, 256);
soundsInfo = stream.readArray<SoundInfo>(stream.read(soundsInfoCount)); stream.readArray(soundsInfo, stream.read(soundsInfoCount));
soundData = stream.readArray<uint8>(stream.read(soundDataSize)); stream.readArray(soundData, stream.read(soundDataSize));
soundOffsets = stream.readArray<uint32>(stream.read(soundOffsetsCount)); stream.readArray(soundOffsets, stream.read(soundOffsetsCount));
// modify palette colors from 6-bit Amiga colorspace // modify palette colors from 6-bit Amiga colorspace
int m = 0; int m = 0;

View File

@@ -62,7 +62,7 @@ namespace Game {
camera.znear = 0.1f; camera.znear = 0.1f;
camera.zfar = 1000.0f; camera.zfar = 1000.0f;
// camera.pos = vec3(-10, -2, 26); // camera.pos = vec3(-10, -2, 26);
camera.pos = vec3(-13.25, 0.42, 38.06); camera.pos = vec3(-13.25f, 0.42f, 38.06f);
// camera.pos = vec3(-36, -1, 2); // camera.pos = vec3(-36, -1, 2);
camera.angle = vec3(0); camera.angle = vec3(0);
} }

View File

@@ -1,54 +1,68 @@
#ifndef H_LEVEL #ifndef H_LEVEL
#define H_LEVEL #define H_LEVEL
#include "core.h"
#include "utils.h" #include "utils.h"
#include "format.h" #include "format.h"
#include "controller.h" #include "controller.h"
struct Level { struct Level {
TR::Level level; TR::Level level;
Texture **textures; Texture *atlas;
float time; float time;
Controller *lara; Controller *lara;
Level(const char *name) : level(Stream(name)), time(0.0f) { Level(const char *name) : level(Stream(name)), time(0.0f) {
if (level.tilesCount) { initAtlas();
textures = new Texture*[level.tilesCount];
for (int i = 0; i < level.tilesCount; i++) {
// sprintf(buf, "LEVEL1_%d.PVR", i);
// textures[i] = Core::load<Texture>(buf);
textures[i] = getTexture(i);
}
} else
textures = NULL;
lara = new Controller(&level); lara = new Controller(&level);
} }
~Level() { ~Level() {
for (int i = 0; i < level.tilesCount; i++) delete atlas;
delete textures[i];
delete[] textures;
} }
Texture *getTexture(int tile) { void initAtlas() {
TR::RGBA data[256 * 256]; if (!level.tilesCount) {
for (int i = 0; i < 256 * 256; i++) { atlas = NULL;
int index = level.tiles[tile].index[i]; return;
auto p = level.palette[index];
data[i].r = p.r;
data[i].g = p.g;
data[i].b = p.b;
data[i].a = index == 0 ? 0 : 255;
} }
return new Texture(256, 256, 0, data);
TR::RGBA *data = new TR::RGBA[1024 * 1024];
for (int i = 0; i < level.tilesCount; i++) {
int tx = (i % 4) * 256;
int ty = (i / 4) * 256;
TR::RGBA *ptr = &data[ty * 1024 + tx];
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
int index = level.tiles[i].index[y * 256 + x];
auto p = level.palette[index];
ptr[x].r = p.r;
ptr[x].g = p.g;
ptr[x].b = p.b;
ptr[x].a = index == 0 ? 0 : 255;
}
ptr += 1024;
}
}
atlas = new Texture(1024, 1024, 0, data);
delete[] data;
}
void bindTexture(int tile) {
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef((tile % 4) * 0.25f, (tile / 4) * 0.25f, 0.0f);
glScalef(0.25f, 0.25f, 1.0f);
glMatrixMode(GL_MODELVIEW);
} }
void setTexture(int objTexture) { void setTexture(int objTexture) {
auto &t = level.objectTextures[objTexture]; auto &t = level.objectTextures[objTexture];
Core::setBlending(t.attribute == 2 ? bmAdd : bmAlpha); Core::setBlending(t.attribute == 2 ? bmAdd : bmAlpha);
textures[t.tileAndFlag & 0x7FFF]->bind(0); bindTexture(t.tileAndFlag & 0x7FFF);
} }
TR::StaticMesh* getMeshByID(int id) { TR::StaticMesh* getMeshByID(int id) {
@@ -58,7 +72,6 @@ struct Level {
return NULL; return NULL;
} }
#define SCALE (1.0f / 1024.0f / 2.0f) #define SCALE (1.0f / 1024.0f / 2.0f)
void renderRoom(const TR::Room &room) { void renderRoom(const TR::Room &room) {
@@ -77,7 +90,7 @@ struct Level {
float a = 1.0f - v.lighting / 8191.0f; float a = 1.0f - v.lighting / 8191.0f;
glColor3f(a, a, a); glColor3f(a, a, a);
glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f); glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f);
glVertex3f(v.vertex.x, v.vertex.y, v.vertex.z); glVertex3sv((GLshort*)&v.vertex);
} }
glEnd(); glEnd();
} }
@@ -94,7 +107,7 @@ struct Level {
float a = 1.0f - v.lighting / 8191.0f; float a = 1.0f - v.lighting / 8191.0f;
glColor3f(a, a, a); glColor3f(a, a, a);
glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f); glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f);
glVertex3f(v.vertex.x, v.vertex.y, v.vertex.z); glVertex3sv((GLshort*)&v.vertex);
} }
glEnd(); glEnd();
} }
@@ -174,8 +187,8 @@ struct Level {
if (mesh.nCount > 0) { if (mesh.nCount > 0) {
auto vn = mesh.normals[f.vertices[k]]; auto vn = mesh.normals[f.vertices[k]];
vec3 n = vec3(vn.x, vn.y, vn.z).normal(); // vec3 n = vec3(vn.x, vn.y, vn.z).normal();
glNormal3f(n.x, n.y, n.z); glNormal3sv((GLshort*)&vn);
} else { } else {
auto l = mesh.lights[f.vertices[k]]; auto l = mesh.lights[f.vertices[k]];
float a = 1.0f - l / 8191.0f; float a = 1.0f - l / 8191.0f;
@@ -183,7 +196,7 @@ struct Level {
} }
glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f); glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f);
glVertex3f(v.x, v.y, v.z); glVertex3sv((GLshort*)&v);
} }
glEnd(); glEnd();
} }
@@ -200,15 +213,15 @@ struct Level {
if (mesh.nCount > 0) { if (mesh.nCount > 0) {
auto vn = mesh.normals[f.vertices[k]]; auto vn = mesh.normals[f.vertices[k]];
vec3 n = vec3(vn.x, vn.y, vn.z).normal(); // vec3 n = vec3(vn.x, vn.y, vn.z).normal();
glNormal3f(n.x, n.y, n.z); glNormal3sv((GLshort*)&vn);
} else { } else {
auto l = mesh.lights[f.vertices[k]]; auto l = mesh.lights[f.vertices[k]];
float a = 1.0f - l / 8191.0f; float a = 1.0f - l / 8191.0f;
glColor3f(a, a, a); glColor3f(a, a, a);
} }
glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f); glTexCoord2f(t.vertices[k].Xpixel / 256.0f, t.vertices[k].Ypixel / 256.0f);
glVertex3f(v.x, v.y, v.z); glVertex3sv((GLshort*)&v);
} }
glEnd(); glEnd();
} }
@@ -217,51 +230,53 @@ struct Level {
// debug normals // debug normals
// triangles (colored) // triangles (colored)
glBegin(GL_TRIANGLES);
for (int j = 0; j < mesh.ctCount; j++) { for (int j = 0; j < mesh.ctCount; j++) {
auto &f = mesh.ctriangles[j]; auto &f = mesh.ctriangles[j];
auto &c = level.palette[f.texture & 0xFF]; auto &c = level.palette[f.texture & 0xFF];
glBegin(GL_TRIANGLES);
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
auto &v = mesh.vertices[f.vertices[k]]; auto &v = mesh.vertices[f.vertices[k]];
if (mesh.nCount > 0) { if (mesh.nCount > 0) {
auto vn = mesh.normals[f.vertices[k]]; auto vn = mesh.normals[f.vertices[k]];
vec3 n = vec3(vn.x, vn.y, vn.z).normal(); // vec3 n = vec3(vn.x, vn.y, vn.z).normal();
glColor3f(c.r / 255.0f * color.x, c.g / 255.0f * color.y, c.b / 255.0f * color.z); glColor3f(c.r / 255.0f * color.x, c.g / 255.0f * color.y, c.b / 255.0f * color.z);
glNormal3f(n.x, n.y, n.z); glNormal3sv((GLshort*)&vn);
} else { } else {
auto l = mesh.lights[f.vertices[k]]; auto l = mesh.lights[f.vertices[k]];
float a = (1.0f - l / 8191.0f) / 255.0f; float a = (1.0f - l / 8191.0f) / 255.0f;
glColor3f(c.r * a, c.g * a, c.b * a); glColor3f(c.r * a, c.g * a, c.b * a);
} }
glVertex3f(v.x, v.y, v.z); glVertex3sv((GLshort*)&v);
}
} }
glEnd(); glEnd();
}
// rectangles (colored) // rectangles (colored)
glBegin(GL_QUADS);
for (int j = 0; j < mesh.crCount; j++) { for (int j = 0; j < mesh.crCount; j++) {
auto &f = mesh.crectangles[j]; auto &f = mesh.crectangles[j];
auto &c = level.palette[f.texture & 0xFF]; auto &c = level.palette[f.texture & 0xFF];
glBegin(GL_QUADS);
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
auto &v = mesh.vertices[f.vertices[k]]; auto &v = mesh.vertices[f.vertices[k]];
if (mesh.nCount > 0) { if (mesh.nCount > 0) {
auto vn = mesh.normals[f.vertices[k]]; auto vn = mesh.normals[f.vertices[k]];
vec3 n = vec3(vn.x, vn.y, vn.z).normal(); // vec3 n = vec3(vn.x, vn.y, vn.z).normal();
glColor3f(c.r / 255.0f * color.x, c.g / 255.0f * color.y, c.b / 255.0f * color.z); glColor3f(c.r / 255.0f * color.x, c.g / 255.0f * color.y, c.b / 255.0f * color.z);
glNormal3f(n.x, n.y, n.z); glNormal3sv((GLshort*)&vn);
} else { } else {
auto l = mesh.lights[f.vertices[k]]; auto l = mesh.lights[f.vertices[k]];
float a = (1.0f - l / 8191.0f) / 255.0f; float a = (1.0f - l / 8191.0f) / 255.0f;
glColor3f(c.r * a, c.g * a, c.b * a); glColor3f(c.r * a, c.g * a, c.b * a);
} }
glVertex3f(v.x, v.y, v.z); glVertex3sv((GLshort*)&v);
}
} }
glEnd(); glEnd();
}
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
if (mesh.nCount > 0) if (mesh.nCount > 0)
@@ -284,7 +299,7 @@ struct Level {
p[2] = right * sprite.l + up * sprite.t; p[2] = right * sprite.l + up * sprite.t;
p[3] = right * sprite.r + up * sprite.t; p[3] = right * sprite.r + up * sprite.t;
textures[sprite.tile]->bind(0); bindTexture(sprite.tile);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(u0, v1); glTexCoord2f(u0, v1);
glVertex3fv((GLfloat*)&p[0]); glVertex3fv((GLfloat*)&p[0]);
@@ -734,6 +749,8 @@ struct Level {
} }
void render() { void render() {
atlas->bind(0);
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.9f); glAlphaFunc(GL_GREATER, 0.9f);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);

View File

@@ -15,7 +15,7 @@ struct Mesh {
GLuint ID[2]; GLuint ID[2];
int iCount; int iCount;
int vCount; int vCount;
/*
Mesh(const char *name) { Mesh(const char *name) {
Stream stream(name); Stream stream(name);
Index *indices = stream.readArray<Index> (stream.read(iCount)); Index *indices = stream.readArray<Index> (stream.read(iCount));
@@ -29,7 +29,7 @@ struct Mesh {
delete[] indices; delete[] indices;
delete[] vertices; delete[] vertices;
} }
*/
virtual ~Mesh() { virtual ~Mesh() {
glDeleteBuffers(2, ID); glDeleteBuffers(2, ID);
} }

View File

@@ -449,10 +449,10 @@ struct Stream {
} }
template <typename T> template <typename T>
T* readArray(int count) { T* readArray(T *&a, int count) {
if (!count) if (!count)
return NULL; return NULL;
T *a = new T[count]; a = new T[count];
read(a, count * sizeof(T)); read(a, count * sizeof(T));
return a; return a;
} }

View File

@@ -190,6 +190,8 @@ int main() {
MSG msg; MSG msg;
msg.message = WM_PAINT; msg.message = WM_PAINT;
DWORD fps = 0, fpsTime = getTime() + 1000;
while (msg.message != WM_QUIT) while (msg.message != WM_QUIT)
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg); TranslateMessage(&msg);
@@ -207,6 +209,13 @@ int main() {
Game::render(); Game::render();
SwapBuffers(hDC); SwapBuffers(hDC);
if (fpsTime < getTime()) {
LOG("FPS: %d\n", fps);
fps = 0;
fpsTime = getTime() + 1000;
} else
fps++;
} }
Game::free(); Game::free();