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

View File

@ -62,7 +62,7 @@ namespace Game {
camera.znear = 0.1f;
camera.zfar = 1000.0f;
// 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.angle = vec3(0);
}

View File

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

View File

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

View File

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

View File

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