1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 03:12:36 +01:00

Disabled atlas, fixed texture loading

This commit is contained in:
Daniel Evans 2013-09-14 02:46:14 +00:00
parent 3801bdff23
commit 1e83463e71
5 changed files with 106 additions and 85 deletions

View File

@ -49,7 +49,7 @@ const char *fragmentShaderSource = "#version 130\n"
"void main()"
"{"
" vec4 c = texture2D(texture, TexCoords);"
" if(c.a < 0.5) discard;"
//" if(c.a < 0.9) discard;"
" float fogZ = (gl_FragCoord.z / gl_FragCoord.w);"
" float fogfac = clamp( (FogEnd-fogZ)/(FogEnd-FogStart), 0.0, 1.0 );"
//" float l = clamp(dot(Normal, SunDirection), 0.0, 1);"
@ -273,7 +273,7 @@ void GTARenderer::renderWorld()
glEnableVertexAttribArray(texAttrib);
glEnableVertexAttribArray(normalAttrib);
glEnableVertexAttribArray(colourAttrib);
glBindTexture(GL_TEXTURE_2D, engine->gameData.textures["water_old"].atlas->getName());
glBindTexture(GL_TEXTURE_2D, engine->gameData.textures["water_old"].texName);
for( size_t w = 0; w < engine->gameData.waterRects.size(); ++w) {
GTATypes::WaterRect& r = engine->gameData.waterRects[w];
@ -450,16 +450,26 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
glEnableVertexAttribArray(normalAttrib);
glEnableVertexAttribArray(colourAttrib);
for(size_t sg = 0; sg <1 && sg < model->geometries[g].subgeom.size(); ++sg)
{
if (model->geometries[g].materials.size() > model->geometries[g].subgeom[sg].material) {
Model::Material& mat = model->geometries[g].materials[model->geometries[g].subgeom[sg].material];
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].EBO);
if(mat.textures.size() > 0 && engine->gameData.textures[mat.textures[0].name].atlas) {
if(! engine->gameData.textures[mat.textures[0].name].atlas->isFinalized()) {
engine->gameData.textures[mat.textures[0].name].atlas->finalize();
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
{
auto& subgeom = model->geometries[g].subgeom[sg];
if (model->geometries[g].materials.size() > subgeom.material) {
Model::Material& mat = model->geometries[g].materials[subgeom.material];
if(mat.textures.size() > 0 ) {
TextureInfo& tex = engine->gameData.textures[mat.textures[0].name];
if(tex.atlas) {
if(! tex.atlas->isFinalized()) {
tex.atlas->finalize();
}
glBindTexture(GL_TEXTURE_2D, tex.atlas->getName());
}
else {
glBindTexture(GL_TEXTURE_2D, tex.texName);
}
glBindTexture(GL_TEXTURE_2D, engine->gameData.textures[mat.textures[0].name].atlas->getName());
}
if( (model->geometries[g].flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
@ -488,11 +498,11 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
glUniform1f(uniMatAmbient, mat.ambientIntensity);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].EBO);
rendered++;
glDrawElements((model->geometries[g].facetype == Model::Triangles ? GL_TRIANGLES : GL_TRIANGLE_STRIP), model->geometries[g].indicesCount, GL_UNSIGNED_INT, NULL);
glDrawElements((model->geometries[g].facetype == Model::Triangles ?
GL_TRIANGLES : GL_TRIANGLE_STRIP),
subgeom.indices.size(), GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * subgeom.start));
}
}

View File

@ -204,23 +204,23 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
geometryStruct.subgeom[i].indices.resize(plgHeader.numverts);
// Find texture info if applicable
TextureInfo* tInf = nullptr;
/*TextureInfo* tInf = nullptr;
if(geometryStruct.materials[plgHeader.index].textures.size() > 0) {
auto texInfoIt = availableTextures.find(geometryStruct.materials[plgHeader.index].textures[0].name);
tInf = &texInfoIt->second;
}
std::set<uint32_t> toUpdate;
std::set<uint32_t> toUpdate;*/
for (int j = 0; j < plgHeader.numverts; ++j) {
uint32_t idx = extsec.readSubStructure<uint32_t>(meshplgI);
geometryStruct.subgeom[i].indices[j] = idx;
meshplgI += sizeof(uint32_t);
if(tInf && toUpdate.find(idx) == toUpdate.end()) {
/*if(tInf && toUpdate.find(idx) == toUpdate.end()) {
toUpdate.insert(idx);
}
}*/
}
for(std::set<uint32_t>::iterator k = toUpdate.begin();
/*for(std::set<uint32_t>::iterator k = toUpdate.begin();
k != toUpdate.end();
++k) {
// Update verticies with atlas UV coordinates.
@ -228,7 +228,7 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
= tInf->rect.x + geometryStruct.texcoords[*k].u * tInf->rect.z;
geometryStruct.texcoords[*k].v
= tInf->rect.y + geometryStruct.texcoords[*k].v * tInf->rect.w;
}
}*/
}
}
}
@ -264,13 +264,6 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
// OpenGL buffer stuff
glGenBuffers(1, &geometryStruct.VBO);
glGenBuffers(1, &geometryStruct.EBO);
size_t Ecount = 0;
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
{
Ecount += geometryStruct.subgeom[i].indices.size();
//glGenBuffers(1, &(geometryStruct.subgeom[i].EBO));
}
geometryStruct.indicesCount = Ecount;
size_t buffsize = (geometryStruct.vertices.size() * sizeof(float) * 3)
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
@ -331,13 +324,13 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
i += 3;
}
/*glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(indicies),
indicies,
GL_STATIC_DRAW
);*/
size_t Ecount = 0;
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
{
geometryStruct.subgeom[i].start = Ecount;
Ecount += geometryStruct.subgeom[i].indices.size();
}
geometryStruct.indicesCount = Ecount;
// Allocate complete EBO buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
@ -347,16 +340,14 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
nullptr,
GL_STATIC_DRAW);
// Upload each subgeometry chunk.
size_t subOffset = 0;
// Upload each subgeometry
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
{
glBufferSubData(
GL_ELEMENT_ARRAY_BUFFER,
subOffset,
geometryStruct.subgeom[i].start * sizeof(uint32_t),
sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size(),
&(geometryStruct.subgeom[i].indices[0]));
subOffset += sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size();
}
geometryStruct.clumpNum = clumpID;

View File

@ -22,7 +22,7 @@ bool TextureLoader::loadFromFile(std::string filename, GTAData* gameData)
return loadFromMemory(data, gameData);
}
GLuint gErrorTextureData[] = { 0x00FF00FF, 0x00FFFFFF, 0x00FFFFFF, 0x00FF00FF };
GLuint gErrorTextureData[] = { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000 };
bool TextureLoader::loadFromMemory(char *data, GTAData *gameData)
{
@ -43,6 +43,7 @@ bool TextureLoader::loadFromMemory(char *data, GTAData *gameData)
std::cerr << "Unsupported texture platform " << std::dec << texNative.platform << std::endl;
continue;
}
bool isPal4 = (texNative.rasterformat & RW::BSTextureNative::FORMAT_EXT_PAL4) == RW::BSTextureNative::FORMAT_EXT_PAL4;
bool isPal8 = (texNative.rasterformat & RW::BSTextureNative::FORMAT_EXT_PAL8) == RW::BSTextureNative::FORMAT_EXT_PAL8;
bool isFulc = texNative.rasterformat == RW::BSTextureNative::FORMAT_1555 ||
texNative.rasterformat == RW::BSTextureNative::FORMAT_8888 ||
@ -52,46 +53,47 @@ bool TextureLoader::loadFromMemory(char *data, GTAData *gameData)
continue;
}
TextureAtlas* atlas;
glm::vec4 texRect;
size_t ai = 0;
size_t texW = texNative.width, texH = texNative.height;
do {
atlas = gameData->getAtlas(ai++);
} while(! atlas->canPack(&texW, &texH, 1));
bool useAtlas = false;
GLuint textureName = 0;
TextureAtlas* atlas = nullptr;
glm::vec4 texRect(0.f, 0.f, 1.f, 1.f);
if(useAtlas) {
size_t ai = 0;
size_t texW = texNative.width, texH = texNative.height;
do {
atlas = gameData->getAtlas(ai++);
} while(! atlas->canPack(&texW, &texH, 1));
}
if(isPal8)
{
uint32_t fullColor[texNative.width * texNative.height];
size_t paletteSize = sizeof(uint32_t) * 256;
size_t paletteSize = 1024;
uint8_t* coldata = reinterpret_cast<uint8_t*>(rootSection.raw() + sizeof(RW::BSSectionHeader) + sizeof(RW::BSTextureNative) + paletteSize);
uint32_t* palette = reinterpret_cast<uint32_t*>(rootSection.raw() + sizeof(RW::BSSectionHeader) + sizeof(RW::BSTextureNative) - 4);
if((texNative.rasterformat & RW::BSTextureNative::FORMAT_8888) == RW::BSTextureNative::FORMAT_8888) {
uint32_t* palette = reinterpret_cast<uint32_t*>(rootSection.raw() + sizeof(RW::BSSectionHeader) + sizeof(RW::BSTextureNative) - 4);
for(size_t j = 0, iTex = 0; j < texNative.width * texNative.height; ++j)
{
iTex = j;
fullColor[iTex] = palette[coldata[j]];
}
for(size_t j = 0, iTex = 0, iPal = 0; j < texNative.width * texNative.height; ++j)
{
iTex = j;
iPal = coldata[j];
fullColor[iTex] = palette[iPal];
}
if(atlas) {
atlas->packTextureFormat(
fullColor, GL_BGRA, GL_UNSIGNED_BYTE,
texNative.width, texNative.height,
texRect.x, texRect.y, texRect.z, texRect.w);
}
else {
uint32_t* palette = reinterpret_cast<uint32_t*>(rootSection.raw() + sizeof(RW::BSSectionHeader) + sizeof(RW::BSTextureNative) - 4);
for(size_t j = 0, iTex = 0, iPal = 0; j < texNative.width * texNative.height; ++j)
{
iTex = j;
iPal = coldata[j];
fullColor[iTex] = 0xFF000000 | palette[iPal];
}
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_2D, textureName);
glTexImage2D(
GL_TEXTURE_2D, 0, texNative.alpha ? GL_RGBA : GL_RGB,
texNative.width, texNative.height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, fullColor
);
}
atlas->packTextureFormat(
fullColor, GL_RGBA, GL_UNSIGNED_BYTE,
texNative.width, texNative.height,
texRect.x, texRect.y, texRect.z, texRect.w);
}
else if(isFulc)
{
@ -106,30 +108,43 @@ bool TextureLoader::loadFromMemory(char *data, GTAData *gameData)
type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case RW::BSTextureNative::FORMAT_8888:
format = GL_BGRA;
format = GL_RGBA;
type = GL_UNSIGNED_INT_8_8_8_8_REV;
break;
case RW::BSTextureNative::FORMAT_888:
format = GL_BGR;
format = GL_BGRA;
type = GL_UNSIGNED_BYTE;
break;
}
atlas->packTextureFormat(
coldata, format, type,
texNative.width, texNative.height,
texRect.x, texRect.y, texRect.z, texRect.w);
if(atlas) {
atlas->packTextureFormat(
coldata, format, type,
texNative.width, texNative.height,
texRect.x, texRect.y, texRect.z, texRect.w);
}
else {
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_2D, textureName);
glTexImage2D(
GL_TEXTURE_2D, 0, texNative.alpha ? GL_RGBA : GL_RGB,
texNative.width, texNative.height, 0,
format, type, coldata
);
}
}
// todo: not completely ignore everything the TXD says.
/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);*/
std::string name = std::string(texNative.diffuseName);
gameData->textures.insert({name, {atlas, texRect}});
// todo: not completely ignore everything the TXD says.
if(!atlas) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}
gameData->textures.insert({name, {textureName, atlas, texRect}});
}
return true;

View File

@ -18,15 +18,20 @@ class TextureAtlas;
/**
* @brief The TextureInfo struct
* Contains metadata about where a texture can be found in each atlas.
* Contains metadata about where a texture can be found.
*/
struct TextureInfo
{
/// Texture Name
GLuint texName;
/// Atlas (if applicable)
TextureAtlas* atlas;
glm::vec4 rect; /// X/Y base coord, Z/W UV scale.
TextureInfo(TextureAtlas* a, const glm::vec4&r) : atlas(a), rect(r) {}
TextureInfo() : atlas(nullptr) {}
TextureInfo(GLuint tex, TextureAtlas* a, const glm::vec4&r)
: texName(tex), atlas(a), rect(r) {}
TextureInfo()
: texName(0), atlas(nullptr) {}
};
/**

View File

@ -37,7 +37,7 @@ public:
};
struct SubGeometry {
//GLuint EBO;
GLuint start = 0;
size_t material;
std::vector<uint32_t> indices;
};