mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Added TextureAtlas, broke rendering
This commit is contained in:
parent
2796ba5e25
commit
206b3979e8
@ -9,3 +9,5 @@ add_subdirectory(viewer)
|
|||||||
|
|
||||||
add_subdirectory(framework2)
|
add_subdirectory(framework2)
|
||||||
add_subdirectory(analyzer)
|
add_subdirectory(analyzer)
|
||||||
|
|
||||||
|
add_subdirectory(tests)
|
||||||
|
@ -422,9 +422,6 @@ void GTARenderer::renderNamedFrame(Model* model, const glm::mat4 &matrix, const
|
|||||||
culled++;
|
culled++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
rendered++;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderGeometry(model, g, matrix);
|
renderGeometry(model, g, matrix);
|
||||||
break;
|
break;
|
||||||
@ -452,7 +449,7 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
|
|||||||
glEnableVertexAttribArray(normalAttrib);
|
glEnableVertexAttribArray(normalAttrib);
|
||||||
glEnableVertexAttribArray(colourAttrib);
|
glEnableVertexAttribArray(colourAttrib);
|
||||||
|
|
||||||
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
|
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) {
|
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];
|
Model::Material& mat = model->geometries[g].materials[model->geometries[g].subgeom[sg].material];
|
||||||
@ -487,9 +484,11 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
|
|||||||
glUniform1f(uniMatAmbient, mat.ambientIntensity);
|
glUniform1f(uniMatAmbient, mat.ambientIntensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].subgeom[sg].EBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].EBO);
|
||||||
|
|
||||||
glDrawElements((model->geometries[g].facetype == Model::Triangles ? GL_TRIANGLES : GL_TRIANGLE_STRIP), model->geometries[g].subgeom[sg].indices.size(), GL_UNSIGNED_INT, NULL);
|
rendered++;
|
||||||
|
|
||||||
|
glDrawElements((model->geometries[g].facetype == Model::Triangles ? GL_TRIANGLES : GL_TRIANGLE_STRIP), model->geometries[g].indicesCount, GL_UNSIGNED_INT, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,9 +502,6 @@ void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAObj
|
|||||||
culled++;
|
culled++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
rendered++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t fi = model->atomics[a].frame;
|
int32_t fi = model->atomics[a].frame;
|
||||||
if( object && object->type() == GTAObject::Vehicle ) {
|
if( object && object->type() == GTAObject::Vehicle ) {
|
||||||
|
@ -230,10 +230,13 @@ Model* LoaderDFF::loadFromMemory(char *data)
|
|||||||
// OpenGL buffer stuff
|
// OpenGL buffer stuff
|
||||||
glGenBuffers(1, &geometryStruct.VBO);
|
glGenBuffers(1, &geometryStruct.VBO);
|
||||||
glGenBuffers(1, &geometryStruct.EBO);
|
glGenBuffers(1, &geometryStruct.EBO);
|
||||||
|
size_t Ecount = 0;
|
||||||
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
||||||
{
|
{
|
||||||
glGenBuffers(1, &(geometryStruct.subgeom[i].EBO));
|
Ecount += geometryStruct.subgeom[i].indices.size();
|
||||||
|
//glGenBuffers(1, &(geometryStruct.subgeom[i].EBO));
|
||||||
}
|
}
|
||||||
|
geometryStruct.indicesCount = Ecount;
|
||||||
|
|
||||||
size_t buffsize = (geometryStruct.vertices.size() * sizeof(float) * 3)
|
size_t buffsize = (geometryStruct.vertices.size() * sizeof(float) * 3)
|
||||||
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
|
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
|
||||||
@ -293,23 +296,33 @@ Model* LoaderDFF::loadFromMemory(char *data)
|
|||||||
indicies[i + 2] = tri.third;
|
indicies[i + 2] = tri.third;
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
|
|
||||||
|
/*glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
|
||||||
glBufferData(
|
glBufferData(
|
||||||
GL_ELEMENT_ARRAY_BUFFER,
|
GL_ELEMENT_ARRAY_BUFFER,
|
||||||
sizeof(indicies),
|
sizeof(indicies),
|
||||||
indicies,
|
indicies,
|
||||||
GL_STATIC_DRAW
|
GL_STATIC_DRAW
|
||||||
);
|
);*/
|
||||||
|
|
||||||
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
// Allocate complete EBO buffer.
|
||||||
{
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.subgeom[i].EBO);
|
|
||||||
glBufferData(
|
glBufferData(
|
||||||
GL_ELEMENT_ARRAY_BUFFER,
|
GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
sizeof(uint32_t) * geometryStruct.indicesCount,
|
||||||
|
nullptr,
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Upload each subgeometry chunk.
|
||||||
|
size_t subOffset = 0;
|
||||||
|
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
||||||
|
{
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
subOffset,
|
||||||
sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size(),
|
sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size(),
|
||||||
&(geometryStruct.subgeom[i].indices[0]),
|
&(geometryStruct.subgeom[i].indices[0]));
|
||||||
GL_STATIC_DRAW
|
subOffset += sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
geometryStruct.clumpNum = clumpID;
|
geometryStruct.clumpNum = clumpID;
|
||||||
|
58
framework2/TextureAtlas.cpp
Normal file
58
framework2/TextureAtlas.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include <renderwure/render/TextureAtlas.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
TextureAtlas::TextureAtlas(size_t w, size_t h)
|
||||||
|
: width(w), height(h), textureName(0), X(0), Y(0), rowHeight(0)
|
||||||
|
{
|
||||||
|
glGenTextures(1, &textureName);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureName);
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
width, height, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureAtlas::~TextureAtlas()
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &textureName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureAtlas::packTexture(uint8_t *data, size_t w, size_t h, float &s, float &t, float &sX, float &sY)
|
||||||
|
{
|
||||||
|
// Ignore null pointer data for testing purposes.
|
||||||
|
if( data != nullptr )
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureName);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, X, Y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
}
|
||||||
|
s = X/(float)width;
|
||||||
|
t = Y/(float)height;
|
||||||
|
sX = w/(float)width;
|
||||||
|
sY = h/(float)height;
|
||||||
|
|
||||||
|
rowHeight = std::max(rowHeight, h);
|
||||||
|
X += w;
|
||||||
|
if( X >= width ) {
|
||||||
|
Y += rowHeight;
|
||||||
|
X = rowHeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureAtlas::canPack(size_t *w, size_t *h, size_t n) const
|
||||||
|
{
|
||||||
|
size_t rwHeight = rowHeight;
|
||||||
|
size_t lX = X, lY = Y;
|
||||||
|
for(size_t i = 0; i < n; ++i) {
|
||||||
|
lX += (w[i]);
|
||||||
|
rwHeight = std::max(rwHeight, h[i]);
|
||||||
|
if(lX >= width) {
|
||||||
|
lY += rwHeight;
|
||||||
|
lX = rwHeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(lX <= width && lY <= height) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
@ -38,6 +38,8 @@ bool TextureLoader::loadFromMemory(char *data)
|
|||||||
|
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
|
|
||||||
|
std::cout << texNative.width << "x" << texNative.height << std::endl;
|
||||||
|
|
||||||
if(texNative.platform != 8)
|
if(texNative.platform != 8)
|
||||||
{
|
{
|
||||||
std::cerr << "Unsupported texture platform " << std::dec << texNative.platform << std::endl;
|
std::cerr << "Unsupported texture platform " << std::dec << texNative.platform << std::endl;
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SubGeometry {
|
struct SubGeometry {
|
||||||
GLuint EBO;
|
//GLuint EBO;
|
||||||
size_t material;
|
size_t material;
|
||||||
std::vector<uint32_t> indices;
|
std::vector<uint32_t> indices;
|
||||||
};
|
};
|
||||||
@ -56,6 +56,7 @@ public:
|
|||||||
std::vector<glm::vec4> colours;
|
std::vector<glm::vec4> colours;
|
||||||
std::vector<RW::BSTVector3> vertices;
|
std::vector<RW::BSTVector3> vertices;
|
||||||
std::vector<RW::BSTVector3> normals;
|
std::vector<RW::BSTVector3> normals;
|
||||||
|
uint32_t indicesCount;
|
||||||
|
|
||||||
std::vector<Material> materials;
|
std::vector<Material> materials;
|
||||||
std::vector<SubGeometry> subgeom;
|
std::vector<SubGeometry> subgeom;
|
||||||
|
43
framework2/include/renderwure/render/TextureAtlas.hpp
Normal file
43
framework2/include/renderwure/render/TextureAtlas.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _TEXTURE_ATLAS_HPP_
|
||||||
|
#define _TEXTURE_ATLAS_HPP_
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
class TextureAtlas
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief width Width of the backing texture.
|
||||||
|
*/
|
||||||
|
size_t width;
|
||||||
|
/**
|
||||||
|
* @brief height Height of the backing texture.
|
||||||
|
*/
|
||||||
|
size_t height;
|
||||||
|
|
||||||
|
GLuint textureName;
|
||||||
|
|
||||||
|
size_t X; // X edge of latest texture.
|
||||||
|
size_t Y; // Y of current row.
|
||||||
|
size_t rowHeight; // Maximum texture height for the current row.
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TextureAtlas(size_t w, size_t h);
|
||||||
|
|
||||||
|
~TextureAtlas();
|
||||||
|
|
||||||
|
void packTexture(uint8_t* data, size_t w, size_t h, float& s, float& t, float& sX, float& sY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief canPack Returns true if enough space remains in the atlas
|
||||||
|
* for the given texture sizes to be packed.
|
||||||
|
* @param w
|
||||||
|
* @param h
|
||||||
|
* @param n
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
*/
|
||||||
|
bool canPack(size_t* w, size_t* h, size_t n) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
16
tests/CMakeLists.txt
Normal file
16
tests/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
FILE(GLOB TEST_SOURCES "*.cpp")
|
||||||
|
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)
|
||||||
|
|
||||||
|
add_executable(run_tests ${TEST_SOURCES})
|
||||||
|
|
||||||
|
include_directories(include)
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/engine/include)
|
||||||
|
|
||||||
|
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
||||||
|
|
||||||
|
include_directories(../framework2/include)
|
||||||
|
|
||||||
|
target_link_libraries(run_tests renderware sfml-window sfml-system GL ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||||
|
|
||||||
|
add_test(UnitTests run_tests)
|
21
tests/main.cpp
Normal file
21
tests/main.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#define BOOST_TEST_MODULE gtfw
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#include <SFML/Window.hpp>
|
||||||
|
|
||||||
|
// Many tests require OpenGL be functional, seems like a reasonable solution.
|
||||||
|
|
||||||
|
class GlobalFixture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sf::Window wnd;
|
||||||
|
|
||||||
|
GlobalFixture() {
|
||||||
|
wnd.create(sf::VideoMode(640, 360), "Testing");
|
||||||
|
}
|
||||||
|
|
||||||
|
~GlobalFixture() {
|
||||||
|
wnd.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_GLOBAL_FIXTURE(GlobalFixture)
|
56
tests/test_atlas.cpp
Normal file
56
tests/test_atlas.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <renderwure/render/TextureAtlas.hpp>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(TextureAtlasTests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(atlas_fill_test)
|
||||||
|
{
|
||||||
|
TextureAtlas atlas(16, 16);
|
||||||
|
|
||||||
|
size_t dim = 16;
|
||||||
|
|
||||||
|
BOOST_CHECK( atlas.canPack(&dim, &dim, 1) );
|
||||||
|
|
||||||
|
float s, t, w, h;
|
||||||
|
|
||||||
|
atlas.packTexture(nullptr, dim, dim, s, t, w, h);
|
||||||
|
|
||||||
|
BOOST_CHECK( s == 0.f );
|
||||||
|
BOOST_CHECK( t == 0.f );
|
||||||
|
BOOST_CHECK( w == 1.f );
|
||||||
|
BOOST_CHECK( h == 1.f );
|
||||||
|
|
||||||
|
BOOST_CHECK( atlas.canPack(&dim, &dim, 1) == false );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(atlas_pack_test)
|
||||||
|
{
|
||||||
|
TextureAtlas atlas(4, 4);
|
||||||
|
size_t dim = 1;
|
||||||
|
|
||||||
|
uint8_t pixels[] = { 0xFF, 0x00, 0x00, 0xFF,
|
||||||
|
0x00, 0xFF, 0x00, 0xFF,
|
||||||
|
0x00, 0x00, 0xFF, 0xFF,
|
||||||
|
0x00, 0x00, 0x00, 0xFF };
|
||||||
|
|
||||||
|
float s, t, w, h;
|
||||||
|
|
||||||
|
atlas.packTexture(pixels+0, dim, dim, s, t, w, h);
|
||||||
|
BOOST_CHECK( s == 0.f && t == 0.f && w == 0.25f && h == 0.25f );
|
||||||
|
atlas.packTexture(pixels+4, dim, dim, s, t, w, h);
|
||||||
|
BOOST_CHECK( s == 0.25f && t == 0.f && w == 0.25f && h == 0.25f );
|
||||||
|
atlas.packTexture(pixels+8, dim, dim, s, t, w, h);
|
||||||
|
BOOST_CHECK( s == 0.5f && t == 0.f && w == 0.25f && h == 0.25f );
|
||||||
|
atlas.packTexture(pixels+12, dim, dim, s, t, w, h);
|
||||||
|
BOOST_CHECK( s == 0.75f && t == 0.f && w == 0.25f && h == 0.25f );
|
||||||
|
|
||||||
|
BOOST_CHECK( atlas.canPack(&dim, &dim, 1) == true );
|
||||||
|
|
||||||
|
uint8_t outPixels[4*4*4];
|
||||||
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, outPixels);
|
||||||
|
for(size_t p = 0; p < 16; ++p) {
|
||||||
|
BOOST_CHECK(outPixels[p] == pixels[p]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
@ -121,6 +121,10 @@ void init(std::string gtapath)
|
|||||||
debugDrawer->setShaderProgram(gta->renderer.worldProgram);
|
debugDrawer->setShaderProgram(gta->renderer.worldProgram);
|
||||||
debugDrawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
debugDrawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
||||||
gta->dynamicsWorld->setDebugDrawer(debugDrawer);
|
gta->dynamicsWorld->setDebugDrawer(debugDrawer);
|
||||||
|
|
||||||
|
std::cout << "Loaded "
|
||||||
|
<< gta->gameData.models.size() << " models, "
|
||||||
|
<< gta->gameData.textureLoader.textures.size() << " textures" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(float dt)
|
void update(float dt)
|
||||||
|
Loading…
Reference in New Issue
Block a user