mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
- added willvarfars vbo surface code when VBO is enabled in the video card, otherwise fallback to original code
This commit is contained in:
parent
3584a831cf
commit
0d248958c3
@ -2324,21 +2324,164 @@ void Renderer::ReleaseSurfaceVBOs() {
|
|||||||
mapSurfaceVBOCache.clear();
|
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) {
|
void Renderer::renderSurface(const int renderFps) {
|
||||||
IF_DEBUG_EDITION(
|
IF_DEBUG_EDITION(
|
||||||
if (getDebugRenderer().willRenderSurface()) {
|
if (getDebugRenderer().willRenderSurface()) {
|
||||||
getDebugRenderer().renderSurface(visibleQuad / Map::cellScale);
|
getDebugRenderer().renderSurface(visibleQuad / Map::cellScale);
|
||||||
} else {
|
} else {
|
||||||
)
|
)
|
||||||
int lastTex=-1;
|
assertGl();
|
||||||
int currTex=-1;
|
|
||||||
const World *world= game->getWorld();
|
const World *world= game->getWorld();
|
||||||
const Map *map= world->getMap();
|
const Map *map= world->getMap();
|
||||||
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
|
|
||||||
float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep();
|
float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep();
|
||||||
|
|
||||||
assertGl();
|
|
||||||
|
|
||||||
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
|
const Texture2D *fowTex= world->getMinimap()->getFowTexture();
|
||||||
|
|
||||||
glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT);
|
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);
|
glActiveTexture(baseTexUnit);
|
||||||
|
|
||||||
VisibleQuadContainerCache &qCache = getQuadCache();
|
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;
|
Quad2i snapshotOfvisibleQuad = visibleQuad;
|
||||||
|
|
||||||
|
@ -284,6 +284,37 @@ private:
|
|||||||
void ReleaseSurfaceVBOs();
|
void ReleaseSurfaceVBOs();
|
||||||
std::map<string,std::pair<Chrono, std::vector<SurfaceData> > > mapSurfaceData;
|
std::map<string,std::pair<Chrono, std::vector<SurfaceData> > > mapSurfaceData;
|
||||||
static bool rendererEnded;
|
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:
|
private:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
@ -99,6 +99,7 @@ public:
|
|||||||
delete iterMap->second;
|
delete iterMap->second;
|
||||||
iterMap->second = NULL;
|
iterMap->second = NULL;
|
||||||
}
|
}
|
||||||
|
itemCacheMutexList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user