- added willvarfars vbo surface code when VBO is enabled in the video card, otherwise fallback to original code

This commit is contained in:
Mark Vejvoda 2011-07-08 16:45:55 +00:00
parent 3584a831cf
commit 0d248958c3
3 changed files with 191 additions and 6 deletions

View File

@ -2324,21 +2324,164 @@ void Renderer::ReleaseSurfaceVBOs() {
mapSurfaceVBOCache.clear();
}
Renderer::MapRenderer::Layer::~Layer() {
if(vbo_vertices) glDeleteBuffersARB(1,&vbo_vertices);
if(vbo_normals) glDeleteBuffersARB(1,&vbo_normals);
if(vbo_fowTexCoords) glDeleteBuffersARB(1,&vbo_fowTexCoords);
if(vbo_surfTexCoords) glDeleteBuffersARB(1,&vbo_surfTexCoords);
if(vbo_indices) glDeleteBuffersARB(1,&vbo_indices);
}
template<typename T> void _loadVBO(GLuint &vbo,std::vector<T> buf,int target=GL_ARRAY_BUFFER_ARB) {
assert(buf.size());
if(true /* vbo enabled? */) {
glGenBuffersARB(1,&vbo);
assert(vbo);
glBindBufferARB(target,vbo);
glBufferDataARB(target,sizeof(T)*buf.size(),&buf[0],GL_STATIC_DRAW_ARB);
glBindBuffer(target,0);
assertGl();
buf.clear();
}
}
void Renderer::MapRenderer::Layer::load_vbos() {
_loadVBO(vbo_vertices,vertices);
_loadVBO(vbo_normals,normals);
_loadVBO(vbo_fowTexCoords,fowTexCoords);
_loadVBO(vbo_surfTexCoords,surfTexCoords);
indexCount = indices.size();
_loadVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB);
}
void Renderer::MapRenderer::load(float coordStep) {
// we create a layer for each texture in the map
for(int y=0; y<map->getSurfaceH()-1; y++) {
for(int x=0; x<map->getSurfaceW()-1; x++) {
SurfaceCell *tc[4] = {
map->getSurfaceCell(x,y),
map->getSurfaceCell(x+1,y),
map->getSurfaceCell(x,y+1),
map->getSurfaceCell(x+1,y+1)
};
int textureHandle = static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture())->getHandle();
Layer* layer = NULL;
for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) {
if((*it)->textureHandle == textureHandle) {
layer = *it;
break;
}
}
if(!layer) {
layer = new Layer(textureHandle);
layers.push_back(layer);
}
// we'll be super-lazy and re-emit all four corners just because its easier
int index[4];
int loopIndexes[4] = { 2,0,3,1 };
for(int i=0; i < 4; i++) {
index[i] = layer->vertices.size();
SurfaceCell *corner = tc[loopIndexes[i]];
layer->vertices.push_back(corner->getVertex());
layer->normals.push_back(corner->getNormal());
}
// the texture coords are all on the current texture obviously
layer->fowTexCoords.push_back(tc[loopIndexes[0]]->getFowTexCoord());
layer->fowTexCoords.push_back(tc[loopIndexes[1]]->getFowTexCoord());
layer->fowTexCoords.push_back(tc[loopIndexes[2]]->getFowTexCoord());
layer->fowTexCoords.push_back(tc[loopIndexes[3]]->getFowTexCoord());
layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,coordStep));
layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,0));
layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,coordStep));
layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,0));
// and make two triangles (no strip, we may be disjoint)
layer->indices.push_back(index[0]);
layer->indices.push_back(index[1]);
layer->indices.push_back(index[2]);
layer->indices.push_back(index[1]);
layer->indices.push_back(index[3]);
layer->indices.push_back(index[2]);
}
}
// turn them into vbos
for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){
(*layer)->load_vbos();
}
}
template<typename T> void* _bindVBO(GLuint vbo,std::vector<T> buf,int target=GL_ARRAY_BUFFER_ARB) {
if(vbo) {
glBindBuffer(target,vbo);
return NULL;
} else {
return &buf[0];
}
}
void Renderer::MapRenderer::Layer::render() {
glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices));
glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals));
glClientActiveTexture(Renderer::fowTexUnit);
glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords));
glClientActiveTexture(Renderer::baseTexUnit);
glBindTexture(GL_TEXTURE_2D,textureHandle);
glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords));
glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB));
}
void Renderer::MapRenderer::render(const Map* map,float coordStep) {
if(map != this->map) {
destroy(); // clear any previous map data
this->map = map;
load(coordStep);
}
glClientActiveTexture(fowTexUnit);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(baseTexUnit);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer)
(*layer)->render();
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
glDisableClientState(GL_NORMAL_ARRAY);
glClientActiveTexture(fowTexUnit);
glBindTexture(GL_TEXTURE_2D,0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(baseTexUnit);
glBindTexture(GL_TEXTURE_2D,0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
assertGl();
}
void Renderer::MapRenderer::destroy() {
while(layers.size()) {
delete layers.back();
layers.pop_back();
}
map = NULL;
}
void Renderer::renderSurface(const int renderFps) {
IF_DEBUG_EDITION(
if (getDebugRenderer().willRenderSurface()) {
getDebugRenderer().renderSurface(visibleQuad / Map::cellScale);
} else {
)
int lastTex=-1;
int currTex=-1;
assertGl();
const World *world= game->getWorld();
const Map *map= world->getMap();
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep();
assertGl();
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT);
@ -2371,10 +2514,20 @@ void Renderer::renderSurface(const int renderFps) {
}
}
int lastTex=-1;
int currTex=-1;
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
glActiveTexture(baseTexUnit);
VisibleQuadContainerCache &qCache = getQuadCache();
if(qCache.visibleScaledCellList.size() > 0) {
bool useVBORendering = getVBOSupported();
if(useVBORendering == true) {
mapRenderer.render(map,coordStep);
}
else if(qCache.visibleScaledCellList.size() > 0) {
Quad2i snapshotOfvisibleQuad = visibleQuad;

View File

@ -284,6 +284,37 @@ private:
void ReleaseSurfaceVBOs();
std::map<string,std::pair<Chrono, std::vector<SurfaceData> > > mapSurfaceData;
static bool rendererEnded;
class MapRenderer {
public:
MapRenderer(): map(NULL) {}
~MapRenderer() { destroy(); }
void render(const Map* map,float coordStep);
void destroy();
private:
void load(float coordStep);
const Map* map;
struct Layer {
Layer(int th):
vbo_vertices(0), vbo_normals(0),
vbo_fowTexCoords(0), vbo_surfTexCoords(0),
vbo_indices(0), indexCount(0),
textureHandle(th) {}
~Layer();
void load_vbos();
void render();
std::vector<Vec3f> vertices, normals;
std::vector<Vec2f> fowTexCoords, surfTexCoords;
std::vector<GLuint> indices;
GLuint vbo_vertices, vbo_normals,
vbo_fowTexCoords, vbo_surfTexCoords,
vbo_indices;
int indexCount;
const int textureHandle;
};
typedef std::vector<Layer*> Layers;
Layers layers;
} mapRenderer;
private:
Renderer();
~Renderer();

View File

@ -99,6 +99,7 @@ public:
delete iterMap->second;
iterMap->second = NULL;
}
itemCacheMutexList.clear();
}
template <typename T>