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:
parent
d1af898609
commit
10b48368e7
75
src/format.h
75
src/format.h
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
109
src/level.h
109
src/level.h
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user