- bugfixes for rendering (new ini setting toggles new quad cache and is called: UseQuadCache=true)

This commit is contained in:
Mark Vejvoda 2010-09-10 08:51:32 +00:00
parent 4d9bc556d6
commit 0783b23e12
10 changed files with 736 additions and 833 deletions

View File

@ -1549,7 +1549,7 @@ void Game::render2d(){
int visibleObjectCount = 0;
Map *map= world.getMap();
int thisTeamIndex= world.getThisTeamIndex();
PosQuadIterator pqi(map, visibleQuad, Map::cellScale);
PosQuadIterator pqi(visibleQuad, Map::cellScale);
while(pqi.next()){
const Vec2i &pos= pqi.getPos();
bool isPosVisible = map->isInside(pos.x, pos.y);

View File

@ -40,19 +40,6 @@ namespace Glest { namespace Game{
bool MeshCallbackTeamColor::noTeamColors = false;
bool RenderEntity::operator<(const RenderEntity &rhs) const {
if(this->type == retUnit || this->type == retUnitFast) {
return(this->unit->getLastRenderFrame() < rhs.unit->getLastRenderFrame());
}
else {
return(this->o->getLastRenderFrame() < rhs.o->getLastRenderFrame());
}
}
bool RenderEntity::operator()(const RenderEntity &lhs,const RenderEntity &rhs) const {
return lhs < lhs;
}
void MeshCallbackTeamColor::execute(const Mesh *mesh){
//team color
@ -156,6 +143,7 @@ const int MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD = 25;
// ==================== constructor and destructor ====================
Renderer::Renderer() {
this->useQuadCache = true;
this->allowRenderUnitTitles = false;
this->menu = NULL;
this->game = NULL;
@ -179,8 +167,9 @@ Renderer::Renderer(){
FactoryRepository &fr= FactoryRepository::getInstance();
Config &config= Config::getInstance();
no2DMouseRendering = config.getBool("No2DMouseRendering","false");
maxConsoleLines= config.getInt("ConsoleMaxLines");
this->useQuadCache = config.getBool("UseQuadCache","true");
this->no2DMouseRendering = config.getBool("No2DMouseRendering","false");
this->maxConsoleLines= config.getInt("ConsoleMaxLines");
gi.setFactory(fr.getGraphicsFactory(config.getString("FactoryGraphics")));
GraphicsFactory *graphicsFactory= GraphicsInterface::getInstance().getFactory();
@ -1303,9 +1292,11 @@ void Renderer::renderSurface(const int renderFps, const int worldFrameCount) {
glActiveTexture(baseTexUnit);
if(useQuadCache == true) {
VisibleQuadContainerCache &qCache = getQuadCache();
for(int visibleIndex = 0; visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) {
if(qCache.visibleScaledCellList.size() > 0) {
for(int visibleIndex = 0;
visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) {
Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y);
@ -1313,10 +1304,26 @@ void Renderer::renderSurface(const int renderFps, const int worldFrameCount) {
SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1);
SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1);
if(tc00 == NULL) {
throw runtime_error("tc00 == NULL");
}
if(tc10 == NULL) {
throw runtime_error("tc10 == NULL");
}
if(tc01 == NULL) {
throw runtime_error("tc01 == NULL");
}
if(tc11 == NULL) {
throw runtime_error("tc11 == NULL");
}
triangleCount+= 2;
pointCount+= 4;
//set texture
if(tc00->getSurfaceTexture() == NULL) {
throw runtime_error("tc00->getSurfaceTexture() == NULL");
}
currTex= static_cast<const Texture2DGl*>(tc00->getSurfaceTexture())->getHandle();
if(currTex != lastTex) {
lastTex = currTex;
@ -1350,11 +1357,12 @@ void Renderer::renderSurface(const int renderFps, const int worldFrameCount) {
glEnd();
}
/*
}
}
else {
Quad2i scaledQuad= visibleQuad/Map::cellScale;
PosQuadIterator pqi(map, scaledQuad);
PosQuadIterator pqi(scaledQuad);
while(pqi.next()) {
const Vec2i &pos= pqi.getPos();
if(mapBounds.isInside(pos)){
@ -1364,6 +1372,19 @@ void Renderer::renderSurface(const int renderFps, const int worldFrameCount) {
SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1);
SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1);
if(tc00 == NULL) {
throw runtime_error("tc00 == NULL");
}
if(tc10 == NULL) {
throw runtime_error("tc10 == NULL");
}
if(tc01 == NULL) {
throw runtime_error("tc01 == NULL");
}
if(tc11 == NULL) {
throw runtime_error("tc11 == NULL");
}
triangleCount+= 2;
pointCount+= 4;
@ -1403,7 +1424,7 @@ void Renderer::renderSurface(const int renderFps, const int worldFrameCount) {
}
}
//glEnd();
*/
}
//Restore
static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(false);
@ -1429,11 +1450,12 @@ void Renderer::renderObjects(const int renderFps, const int worldFrameCount) {
Vec3f baseFogColor;
int thisTeamIndex= world->getThisTeamIndex();
bool modelRenderStarted = false;
if(useQuadCache == true) {
VisibleQuadContainerCache &qCache = getQuadCache();
for(int visibleIndex = 0; visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) {
for(int visibleIndex = 0;
visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) {
Object *o = qCache.visibleObjectList[visibleIndex];
const Model *objModel= o->getModel();
@ -1494,12 +1516,12 @@ void Renderer::renderObjects(const int renderFps, const int worldFrameCount) {
//restore
static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
/*
}
else {
int thisTeamIndex= world->getThisTeamIndex();
bool modelRenderStarted = false;
PosQuadIterator pqi(map, visibleQuad, Map::cellScale);
PosQuadIterator pqi(visibleQuad, Map::cellScale);
while(pqi.next()) {
const Vec2i &pos= pqi.getPos();
if(map->isInside(pos)){
@ -1566,7 +1588,7 @@ void Renderer::renderObjects(const int renderFps, const int worldFrameCount) {
//restore
static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
*/
}
assertGl();
}
@ -1590,6 +1612,9 @@ void Renderer::renderWater(){
glEnable(GL_BLEND);
if(textures3D){
Texture3D *waterTex= world->getTileset()->getWaterTex();
if(waterTex == NULL) {
throw runtime_error("waterTex == NULL");
}
glEnable(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, static_cast<Texture3DGl*>(waterTex)->getHandle());
}
@ -1707,10 +1732,13 @@ void Renderer::renderUnits(const int renderFps, const int worldFrameCount) {
visibleFrameUnitList.clear();
bool modelRenderStarted = false;
int lastFactionIndex = -1;
if(useQuadCache == true) {
VisibleQuadContainerCache &qCache = getQuadCache();
for(int visibleUnitIndex = 0; visibleUnitIndex < qCache.visibleUnitList.size(); ++visibleUnitIndex) {
Unit *unit = qCache.visibleUnitList[visibleUnitIndex];
if(qCache.visibleQuadUnitList.size() > 0) {
for(int visibleUnitIndex = 0;
visibleUnitIndex < qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
meshCallbackTeamColor.setTeamTexture(unit->getFaction()->getTexture());
@ -1782,11 +1810,12 @@ void Renderer::renderUnits(const int renderFps, const int worldFrameCount) {
modelRenderer->end();
glPopAttrib();
}
}
//restore
static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
/*
}
else {
bool modelRenderStarted = false;
for(int i=0; i<world->getFactionCount(); ++i){
@ -1871,86 +1900,12 @@ void Renderer::renderUnits(const int renderFps, const int worldFrameCount) {
//restore
static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
*/
}
//assert
assertGl();
}
void Renderer::renderUnitList(std::vector<RenderEntity> &vctEntity,MeshCallbackTeamColor *meshCallbackTeamColor,const int renderFps, const int worldFrameCount) {
for(int idx=0; idx < vctEntity.size(); ++idx) {
RenderEntity &entity = vctEntity[idx];
prepareUnitForRender(entity);
renderUnit(entity,meshCallbackTeamColor,renderFps, worldFrameCount);
}
}
void Renderer::renderUnit(RenderEntity &entity,MeshCallbackTeamColor *meshCallbackTeamColor,const int renderFps, const int worldFrameCount) {
Unit *unit = entity.unit;
if(unit != NULL) {
renderUnit(unit,meshCallbackTeamColor, entity.teamTexture, worldFrameCount);
entity.setState(resRendered);
}
}
void Renderer::renderUnit(Unit *unit,MeshCallbackTeamColor *meshCallbackTeamColor, const Texture2D *teamTexture, const int worldFrameCount) {
if(unit != NULL) {
if(meshCallbackTeamColor != NULL) {
meshCallbackTeamColor->setTeamTexture(teamTexture);
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//translate
Vec3f currVec= unit->getCurrVectorFlat();
glTranslatef(currVec.x, currVec.y, currVec.z);
//rotate
glRotatef(unit->getRotation(), 0.f, 1.f, 0.f);
glRotatef(unit->getVerticalRotation(), 1.f, 0.f, 0.f);
//dead alpha
float alpha= 1.0f;
const SkillType *st= unit->getCurrSkill();
if(st->getClass()==scDie && static_cast<const DieSkillType*>(st)->getFade()){
alpha= 1.0f-unit->getAnimProgress();
glDisable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr());
}
else{
glEnable(GL_COLOR_MATERIAL);
}
//render
const Model *model= unit->getCurrentModel();
//model->updateInterpolationData(unit->getAnimProgress(), unit->isAlive());
modelRenderer->render(model);
unit->setLastRenderFrame(worldFrameCount);
triangleCount+= model->getTriangleCount();
pointCount+= model->getVertexCount();
glPopMatrix();
unit->setVisible(true);
if(allowRenderUnitTitles == true) {
// Add to the pending render unit title list
renderUnitTitleList.push_back(std::pair<Unit *,Vec3f>(unit,computeScreenPosition(unit->getCurrVectorFlat())) );
}
}
}
void Renderer::prepareUnitForRender(RenderEntity &entity) {
if(entity.unit != NULL) {
const Model *model= entity.unit->getCurrentModel();
model->updateInterpolationData(entity.unit->getAnimProgress(), entity.unit->isAlive());
}
entity.setState(resInterpolated);
}
void Renderer::renderSelectionEffects(){
const World *world= game->getWorld();
@ -2189,28 +2144,30 @@ void Renderer::renderMinimap(){
glDisable(GL_TEXTURE_2D);
//draw units
if(useQuadCache == true) {
VisibleQuadContainerCache &qCache = getQuadCache();
if(qCache.visibleUnitList.size() > 0) {
glBegin(GL_QUADS);
for(int visibleUnitIndex = 0; visibleUnitIndex < qCache.visibleUnitList.size(); ++visibleUnitIndex) {
Unit *unit = qCache.visibleUnitList[visibleUnitIndex];
for(int visibleIndex = 0;
visibleIndex < qCache.visibleUnitList.size(); ++visibleIndex) {
Unit *unit = qCache.visibleUnitList[visibleIndex];
Vec2i pos= unit->getPos() / Map::cellScale;
int size= unit->getType()->getSize();
Vec3f color= unit->getFaction()->getTexture()->getPixmap()->getPixel3f(0, 0);
glColor3fv(color.ptr());
glBegin(GL_QUADS);
glVertex2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y));
glVertex2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y));
glVertex2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y));
glVertex2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y));
}
glEnd();
}
/*
}
}
else {
glBegin(GL_QUADS);
for(int i=0; i<world->getFactionCount(); ++i){
for(int j=0; j<world->getFaction(i)->getUnitCount(); ++j){
@ -2228,7 +2185,7 @@ void Renderer::renderMinimap(){
}
}
glEnd();
*/
}
//draw camera
float wRatio= static_cast<float>(metrics.getMinimapW()) / world->getMap()->getW();
@ -2241,31 +2198,35 @@ void Renderer::renderMinimap(){
glEnable(GL_BLEND);
int x1 = 0;
int y1 = 0;
#ifdef USE_STREFLOP
x1 = mx + x + static_cast<int>(20*streflop::sin(ang-pi/5));
y1 = my + mh - (y-static_cast<int>(20*streflop::cos(ang-pi/5)));
#else
x1 = mx + x + static_cast<int>(20*sin(ang-pi/5));
y1 = my + mh - (y-static_cast<int>(20*cos(ang-pi/5)));
#endif
int x2 = 0;
int y2 = 0;
#ifdef USE_STREFLOP
x2 = mx + x + static_cast<int>(20*streflop::sin(ang+pi/5));
y2 = my + mh - (y-static_cast<int>(20*streflop::cos(ang+pi/5)));
#else
x2 = mx + x + static_cast<int>(20*sin(ang+pi/5));
y2 = my + mh - (y-static_cast<int>(20*cos(ang+pi/5)));
#endif
glColor4f(1.f, 1.f, 1.f, 1.f);
glBegin(GL_TRIANGLES);
glVertex2i(mx+x, my+mh-y);
glColor4f(1.f, 1.f, 1.f, 0.0f);
glVertex2i(x1,y1);
glColor4f(1.f, 1.f, 1.f, 0.0f);
glVertex2i(x2,y2);
glColor4f(1.f, 1.f, 1.f, 0.0f);
#ifdef USE_STREFLOP
glVertex2i(
mx + x + static_cast<int>(20*streflop::sin(ang-pi/5)),
my + mh - (y-static_cast<int>(20*streflop::cos(ang-pi/5))));
#else
glVertex2i(
mx + x + static_cast<int>(20*sin(ang-pi/5)),
my + mh - (y-static_cast<int>(20*cos(ang-pi/5))));
#endif
glColor4f(1.f, 1.f, 1.f, 0.0f);
#ifdef USE_STREFLOP
glVertex2i(
mx + x + static_cast<int>(20*streflop::sin(ang+pi/5)),
my + mh - (y-static_cast<int>(20*streflop::cos(ang+pi/5))));
#else
glVertex2i(
mx + x + static_cast<int>(20*sin(ang+pi/5)),
my + mh - (y-static_cast<int>(20*cos(ang+pi/5))));
#endif
glEnd();
glPopAttrib();
@ -2439,15 +2400,15 @@ void Renderer::renderMenuBackground(const MenuBackground *menuBackground){
GLuint waterHandle= static_cast<Texture2DGl*>(menuBackground->getWaterTexture())->getHandle();
glBindTexture(GL_TEXTURE_2D, waterHandle);
for(int i=1; i < waterTesselation; ++i) {
glBegin(GL_TRIANGLE_STRIP);
for(int j=1; j<waterTesselation; ++j) {
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2i(1, 2 % j);
glVertex3f(-waterSize+i*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize);
glTexCoord2i(0, 2 % j);
glVertex3f(-waterSize+(i+1)*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize);
}
glEnd();
}
}
glDisable(GL_BLEND);
//raindrops
@ -2568,7 +2529,8 @@ Vec3f Renderer::computeScreenPosition(const Vec3f &worldPos) {
return screenPos;
}
void Renderer::computeSelected(Selection::UnitContainer &units, const Vec2i &posDown, const Vec2i &posUp){
void Renderer::computeSelected( Selection::UnitContainer &units,
const Vec2i &posDown, const Vec2i &posUp) {
//declarations
GLuint selectBuffer[Gui::maxSelBuff];
@ -2593,30 +2555,42 @@ void Renderer::computeSelected(Selection::UnitContainer &units, const Vec2i &pos
gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane);
loadGameCameraMatrix();
//render units
//render units to find which ones should be selected
renderUnitsFast();
//pop matrices
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//select units
const World *world= game->getWorld();
//select units by checking the selected buffer
int selCount= glRenderMode(GL_RENDER);
if(selCount > 0) {
const World *world= game->getWorld();
for(int i=1; i <= selCount; ++i) {
int factionIndex= selectBuffer[i*5-2];
int unitIndex= selectBuffer[i*5-1];
//int unitIndex= selectBuffer[i*5-1];
int unitId= selectBuffer[i*5-1];
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIndex = %d, unitId = %d, selCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIndex,unitId,selCount);
//if( factionIndex >= 0 && factionIndex < world->getFactionCount() &&
// unitIndex >= 0 && unitIndex < world->getFaction(factionIndex)->getUnitCount()) {
// Unit *unit= world->getFaction(factionIndex)->getUnit(unitIndex);
if( factionIndex >= 0 && factionIndex < world->getFactionCount() &&
unitIndex >= 0 && unitIndex < world->getFaction(factionIndex)->getUnitCount()) {
unitId >= 0) {
Unit *unit= world->getFaction(factionIndex)->getUnit(unitIndex);
if(unit->isAlive()) {
const Faction *faction= world->getFaction(factionIndex);
if(faction != NULL) {
Unit *unit = faction->findUnit(unitId);
if(unit != NULL && unit->isAlive()) {
units.push_back(unit);
}
}
}
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] units.size() = %d, selCount = %d\n",__FILE__,__FUNCTION__,__LINE__,units.size(),selCount);
}
}
// ==================== shadows ====================
@ -2627,7 +2601,6 @@ void Renderer::renderShadowsToTexture(const int renderFps){
shadowMapFrame= (shadowMapFrame + 1) % (shadowFrameSkip + 1);
if(shadowMapFrame == 0){
assertGl();
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT | GL_POLYGON_BIT);
@ -2979,14 +2952,14 @@ void Renderer::renderUnitsFast(){
bool modelRenderStarted = false;
bool modelRenderFactionStarted = false;
if(useQuadCache == true) {
int lastFactionIndex = -1;
VisibleQuadContainerCache &qCache = getQuadCache();
for(int visibleUnitIndex = 0; visibleUnitIndex < qCache.visibleUnitList.size(); ++visibleUnitIndex) {
Unit *unit = qCache.visibleUnitList[visibleUnitIndex];
if(qCache.visibleQuadUnitList.size() > 0) {
for(int visibleUnitIndex = 0;
visibleUnitIndex < qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
if(lastFactionIndex != unit->getFactionIndex()) {
modelRenderFactionStarted = false;
}
if(modelRenderStarted == false) {
modelRenderStarted = true;
glPushAttrib(GL_ENABLE_BIT);
@ -2997,11 +2970,20 @@ void Renderer::renderUnitsFast(){
glInitNames();
}
if(modelRenderFactionStarted == false) {
if(lastFactionIndex != unit->getFactionIndex()) {
if(lastFactionIndex != -1) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] calling glPopName() for lastFactionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,lastFactionIndex);
glPopName();
}
modelRenderFactionStarted = true;
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] calling glPushName() for lastFactionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getFactionIndex());
// Used for selection lookup in computeSelected
glPushName(unit->getFactionIndex());
}
glPushName(visibleUnitIndex);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] calling glPushName() for unit->getId() = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getId());
// Used for selection lookup in computeSelected
glPushName(unit->getId());
glMatrixMode(GL_MODELVIEW);
@ -3021,22 +3003,24 @@ void Renderer::renderUnitsFast(){
modelRenderer->render(model);
glPopMatrix();
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] calling glPopName() for unit->getId() = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getId());
glPopName();
if((lastFactionIndex != -1 && lastFactionIndex != unit->getFactionIndex()) ||
(visibleUnitIndex == qCache.visibleUnitList.size() - 1)) {
glPopName();
}
lastFactionIndex = unit->getFactionIndex();
}
if(modelRenderFactionStarted == true) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] calling glPopName() for lastFactionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,lastFactionIndex);
glPopName();
}
if(modelRenderStarted == true) {
modelRenderer->end();
glPopAttrib();
}
/*
}
}
else {
bool modelRenderStarted = false;
bool modelRenderFactionStarted = false;
for(int i=0; i<world->getFactionCount(); ++i){
@ -3088,21 +3072,11 @@ void Renderer::renderUnitsFast(){
modelRenderer->end();
glPopAttrib();
}
*/
}
assertGl();
}
void Renderer::prepareUnitFastForRender(RenderEntity &entity) {
if(entity.unit != NULL) {
const Model *model= entity.unit->getCurrentModel();
if(model != NULL) {
model->updateInterpolationVertices(entity.unit->getAnimProgress(), entity.unit->isAlive());
}
}
entity.setState(resInterpolated);
}
//render objects for selection purposes
void Renderer::renderObjectsFast() {
const World *world= game->getWorld();
@ -3110,11 +3084,13 @@ void Renderer::renderObjectsFast() {
assertGl();
int thisTeamIndex= world->getThisTeamIndex();
bool modelRenderStarted = false;
if(useQuadCache == true) {
VisibleQuadContainerCache &qCache = getQuadCache();
for(int visibleIndex = 0; visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) {
if(qCache.visibleObjectList.size() > 0) {
for(int visibleIndex = 0;
visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) {
Object *o = qCache.visibleObjectList[visibleIndex];
const Model *objModel= o->getModel();
@ -3156,12 +3132,13 @@ void Renderer::renderObjectsFast() {
modelRenderer->end();
glPopAttrib();
}
/*
}
}
else {
int thisTeamIndex= world->getThisTeamIndex();
bool modelRenderStarted = false;
PosQuadIterator pqi(map, visibleQuad, Map::cellScale);
PosQuadIterator pqi(visibleQuad, Map::cellScale);
while(pqi.next()) {
const Vec2i &pos= pqi.getPos();
if(map->isInside(pos)){
@ -3217,29 +3194,11 @@ void Renderer::renderObjectsFast() {
modelRenderer->end();
glPopAttrib();
}
*/
}
assertGl();
}
void Renderer::renderObjectFastList(std::vector<RenderEntity> &vctEntity) {
for(int idx=0; idx < vctEntity.size(); ++idx) {
RenderEntity &entity = vctEntity[idx];
const Model *objModel= entity.o->getModel();
Vec3f v= entity.o->getPos();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(v.x, v.y, v.z);
glRotatef(entity.o->getRotation(), 0.f, 1.f, 0.f);
modelRenderer->render(objModel);
glPopMatrix();
}
}
// ==================== gl caps ====================
void Renderer::checkGlCaps() {
@ -3569,7 +3528,8 @@ void Renderer::renderSelectionCircle(Vec3f v, int size, float radius){
glPopMatrix();
}
void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &color, float width){
void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2,
const Vec3f &color, float width) {
const int tesselation= 3;
const float arrowEndSize= 0.4f;
const float maxlen= 25;
@ -3592,7 +3552,6 @@ void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &co
Vec3f pos1Right= pos1 - normal*(width+0.05f);
//arrow body
glBegin(GL_TRIANGLE_STRIP);
for(int i=0; i<=tesselation; ++i) {
float t= static_cast<float>(i)/tesselation;
Vec3f a= pos1Left.lerp(t, pos2Left);
@ -3600,10 +3559,12 @@ void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &co
Vec4f c= Vec4f(color, t*0.25f*alphaFactor);
glColor4fv(c.ptr());
glBegin(GL_TRIANGLE_STRIP);
glVertex3fv(a.ptr());
glVertex3fv(b.ptr());
}
glEnd();
}
//arrow end
glBegin(GL_TRIANGLES);
@ -3665,22 +3626,27 @@ void Renderer::renderTile(const Vec2i &pos){
glDisable(GL_CULL_FACE);
float h1 = map->getCell(renderPos.x, renderPos.y)->getHeight();
float h2 = map->getCell(renderPos.x, renderPos.y+1)->getHeight();
float h3 = map->getCell(renderPos.x+1, renderPos.y)->getHeight();
float h4 = map->getCell(renderPos.x+1, renderPos.y+1)->getHeight();
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(
static_cast<float>(renderPos.x),
map->getCell(renderPos.x, renderPos.y)->getHeight(),
h1,
static_cast<float>(renderPos.y));
glVertex3f(
static_cast<float>(renderPos.x),
map->getCell(renderPos.x, renderPos.y+1)->getHeight(),
h2,
static_cast<float>(renderPos.y+1));
glVertex3f(
static_cast<float>(renderPos.x+1),
map->getCell(renderPos.x+1, renderPos.y)->getHeight(),
h3,
static_cast<float>(renderPos.y));
glVertex3f(
static_cast<float>(renderPos.x+1),
map->getCell(renderPos.x+1, renderPos.y+1)->getHeight(),
h4,
static_cast<float>(renderPos.y+1));
glEnd();
@ -3783,39 +3749,52 @@ void Renderer::renderUnitTitles(Font2D *font, Vec3f color) {
}
}
VisibleQuadContainerCache & Renderer::getQuadCache(bool updateOnDirtyFrame) {
VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
bool forceNew) {
//forceNew = true;
if(game != NULL && game->getWorld() != NULL) {
const World *world= game->getWorld();
if(updateOnDirtyFrame == true &&
if(forceNew == true ||
(updateOnDirtyFrame == true &&
(world->getFrameCount() != quadCache.cacheFrame ||
visibleQuad != quadCache.lastVisibleQuad)) {
visibleQuad != quadCache.lastVisibleQuad))) {
// Dump cached info
if(visibleQuad != quadCache.lastVisibleQuad) {
quadCache.clearCacheData();
}
else {
//if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) {
//quadCache.clearCacheData();
//}
//else {
quadCache.clearVolatileCacheData();
}
//}
// Unit calculations
for(int i = 0; i < world->getFactionCount(); ++i) {
for(int j = 0; j < world->getFaction(i)->getUnitCount(); ++j) {
Unit *unit= world->getFaction(i)->getUnit(j);
const Faction *faction = world->getFaction(i);
for(int j = 0; j < faction->getUnitCount(); ++j) {
Unit *unit= faction->getUnit(j);
if(world->toRenderUnit(unit, visibleQuad)) {
quadCache.visibleUnitList.push_back(unit);
quadCache.visibleQuadUnitList.push_back(unit);
}
else {
unit->setVisible(false);
quadCache.inVisibleUnitList.push_back(unit);
// Currently don't need this list
//quadCache.inVisibleUnitList.push_back(unit);
}
if(world->toRenderUnit(unit)) {
quadCache.visibleUnitList.push_back(unit);
}
}
}
if(visibleQuad != quadCache.lastVisibleQuad) {
if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) {
// Object calculations
const Map *map= world->getMap();
PosQuadIterator pqi(map, visibleQuad, Map::cellScale);
quadCache.clearNonVolatileCacheData();
PosQuadIterator pqi(visibleQuad, Map::cellScale);
while(pqi.next()) {
const Vec2i &pos= pqi.getPos();
if(map->isInside(pos)) {
@ -3835,18 +3814,18 @@ VisibleQuadContainerCache & Renderer::getQuadCache(bool updateOnDirtyFrame) {
}
}
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
Quad2i scaledQuad = visibleQuad / Map::cellScale;
PosQuadIterator pqis(map, scaledQuad);
PosQuadIterator pqis(scaledQuad);
while(pqis.next()) {
const Vec2i &pos= pqis.getPos();
if(map->isInside(pos)) {
if(mapBounds.isInside(pos)) {
quadCache.visibleScaledCellList.push_back(pos);
}
}
quadCache.lastVisibleQuad = visibleQuad;
}
quadCache.cacheFrame = world->getFrameCount();
quadCache.lastVisibleQuad = visibleQuad;
}
}

View File

@ -74,75 +74,6 @@ class Object;
/// OpenGL renderer, uses the shared library
// ===========================================================
enum RenderEntityState {
resNone,
resInterpolated,
resRendered
};
enum RenderEntityType {
retObject,
retUnit,
retUnitFast
};
class RenderEntity {
protected:
RenderEntityState state;
void CopyAll(const RenderEntity &obj) {
this->type = obj.type;
this->state = obj.state;
this->o = obj.o;
this->mapPos = obj.mapPos;
this->unit = obj.unit;
this->teamTexture = obj.teamTexture;;
}
public:
static bool forceRenderWithIterpolation;
RenderEntity() {
this->type = retObject;
this->o = NULL;
this->unit = NULL;
this->teamTexture = NULL;
setState(resNone);
}
RenderEntity(RenderEntityType type,Object *o, Vec2i mapPos, Unit *unit,const Texture2D *teamTexture=NULL) {
this->type = type;
this->o = o;
this->mapPos = mapPos;
this->unit = unit;
this->teamTexture = teamTexture;
setState(resNone);
}
RenderEntity(const RenderEntity &obj) {
CopyAll(obj);
}
RenderEntity & operator=(const RenderEntity &obj) {
CopyAll(obj);
return *this;
}
bool operator<(const RenderEntity &rhs) const;
bool operator()(const RenderEntity &lhs,const RenderEntity &rhs) const;
RenderEntityType type;
Object *o;
Vec2i mapPos;
Unit *unit;
const Texture2D *teamTexture;
RenderEntityState getState() {
return this->state;
}
void setState(RenderEntityState value) {
this->state = value;
}
};
class VisibleQuadContainerCache {
protected:
@ -150,7 +81,8 @@ protected:
cacheFrame = obj.cacheFrame;
visibleObjectList = obj.visibleObjectList;
visibleUnitList = obj.visibleUnitList;
inVisibleUnitList = obj.inVisibleUnitList;
visibleQuadUnitList = obj.visibleQuadUnitList;
//inVisibleUnitList = obj.inVisibleUnitList;
//visibleCellList = obj.visibleCellList;
visibleScaledCellList = obj.visibleScaledCellList;
lastVisibleQuad = obj.lastVisibleQuad;
@ -169,26 +101,27 @@ public:
CopyAll(obj);
return *this;
}
//bool operator<(const RenderEntity &rhs) const;
//bool operator()(const RenderEntity &lhs,const RenderEntity &rhs) const;
void clearCacheData() {
clearVolatileCacheData();
visibleObjectList.clear();
//visibleCellList.clear();
visibleScaledCellList.clear();
clearNonVolatileCacheData();
}
void clearVolatileCacheData() {
visibleUnitList.clear();
inVisibleUnitList.clear();
visibleQuadUnitList.clear();
//inVisibleUnitList.clear();
}
void clearNonVolatileCacheData() {
visibleObjectList.clear();
visibleScaledCellList.clear();
}
int cacheFrame;
Quad2i lastVisibleQuad;
std::vector<Object *> visibleObjectList;
std::vector<Unit *> visibleQuadUnitList;
std::vector<Unit *> visibleUnitList;
std::vector<Unit *> inVisibleUnitList;
//std::vector<Unit *> inVisibleUnitList;
//std::vector<Vec2i> visibleCellList;
std::vector<Vec2i> visibleScaledCellList;
};
@ -302,6 +235,7 @@ private:
int lastRenderFps;
bool shadowsOffDueToMinRender;
bool useQuadCache;
private:
Renderer();
~Renderer();
@ -381,17 +315,9 @@ public:
//complex rendering
void renderSurface(const int renderFps, const int worldFrameCount);
void renderObjects(const int renderFps, const int worldFrameCount);
void renderObject(RenderEntity &entity,const Vec3f &baseFogColor,const int renderFps, const int worldFrameCount);
void renderObject(Object *o,const Vec2i &mapPos,const Vec3f &baseFogColor,const int worldFrameCount);
void prepareObjectForRender(RenderEntity &entity);
void renderObjectList(std::vector<RenderEntity> &vctEntity,const Vec3f &baseFogColor,const int renderFps, const int worldFrameCount);
void renderWater();
void renderUnits(const int renderFps, const int worldFrameCount);
void prepareUnitForRender(RenderEntity &entity);
void renderUnitList(std::vector<RenderEntity> &vctEntity,MeshCallbackTeamColor *meshCallbackTeamColor,const int renderFps, const int worldFrameCount);
void renderUnit(RenderEntity &entity,MeshCallbackTeamColor *meshCallbackTeamColor,const int renderFps, const int worldFrameCount);
void renderUnit(Unit *unit,MeshCallbackTeamColor *meshCallbackTeamColor, const Texture2D *teamTexture, const int worldFrameCount);
void renderSelectionEffects();
void renderWaterEffects();
@ -442,7 +368,7 @@ public:
void setLastRenderFps(int value) { lastRenderFps = value;}
int getLastRenderFps() const { return lastRenderFps;}
VisibleQuadContainerCache & getQuadCache(bool updateOnDirtyFrame=true);
VisibleQuadContainerCache & getQuadCache(bool updateOnDirtyFrame=true,bool forceNew=false);
private:
//private misc
@ -456,12 +382,7 @@ private:
//selection render
void renderObjectsFast();
void renderObjectFastList(std::vector<RenderEntity> &vctEntity);
void renderUnitsFast();
void renderUnitFastList(std::vector<RenderEntity> &vctEntity);
void renderUnitFast(RenderEntity &entity);
void renderUnitFast(Unit *unit, int x, int y);
void prepareUnitFastForRender(RenderEntity &entity);
//gl requirements
void checkGlCaps();

View File

@ -864,7 +864,8 @@ bool Gui::isSharedCommandClass(CommandClass commandClass){
void Gui::computeSelected(bool doubleClick){
Selection::UnitContainer units;
Renderer::getInstance().computeSelected(units, selectionQuad.getPosDown(), selectionQuad.getPosUp());
Renderer::getInstance().computeSelected(units, selectionQuad.getPosDown(),
selectionQuad.getPosUp());
selectingBuilding= false;
activeCommandType= NULL;

View File

@ -449,21 +449,21 @@ void Faction::setResourceBalance(const ResourceType *rt, int balance){
assert(false);
}
Unit *Faction::findUnit(int id){
Unit *Faction::findUnit(int id) const {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] id = %d\n",__FILE__,__FUNCTION__, __LINE__,id);
UnitMap::iterator it= unitMap.find(id);
UnitMap::const_iterator itFound = unitMap.find(id);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
if(it==unitMap.end()){
if(itFound == unitMap.end()) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
return NULL;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] it->second = %p\n",__FILE__,__FUNCTION__, __LINE__,it->second);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] it->second->id = %d\n",__FILE__,__FUNCTION__, __LINE__,it->second->getId());
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] it->second = %s\n",__FILE__,__FUNCTION__, __LINE__,it->second->toString().c_str());
return it->second;
return itFound->second;
}
void Faction::addUnit(Unit *unit){

View File

@ -130,7 +130,7 @@ public:
bool isAlly(const Faction *faction);
//other
Unit *findUnit(int id);
Unit *findUnit(int id) const;
void addUnit(Unit *unit);
void removeUnit(Unit *unit);
void addStore(const UnitType *unitType);

View File

@ -906,8 +906,7 @@ const Vec2i &PosCircularIterator::getPos(){
// class PosQuadIterator
// =====================================================
PosQuadIterator::PosQuadIterator(const Map *map, const Quad2i &quad, int step){
this->map= map;
PosQuadIterator::PosQuadIterator(const Quad2i &quad, int step){
this->quad= quad;
this->boundingRect= quad.computeBoundingRect();
this->step= step;

View File

@ -275,11 +275,10 @@ class PosQuadIterator{
private:
Quad2i quad;
Rect2i boundingRect;
const Map *map;
Vec2i pos;
int step;
public:
PosQuadIterator(const Map *map, const Quad2i &quad, int step=1);
PosQuadIterator(const Quad2i &quad, int step=1);
bool next();
void skipX();
const Vec2i &getPos();

View File

@ -29,12 +29,15 @@ namespace Glest{ namespace Game{
// class PixmapInfo
// =====================================================
SurfaceInfo::SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld, const Pixmap2D *rd) {
SurfaceInfo::SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld,
const Pixmap2D *rd) {
this->leftDown= ld;
this->leftUp= lu;
this->rightDown= rd;
this->rightUp= ru;
center= NULL;
texture=NULL;
}
SurfaceInfo::SurfaceInfo(const Pixmap2D *center) {
@ -43,6 +46,7 @@ SurfaceInfo::SurfaceInfo(const Pixmap2D *center) {
this->rightDown= NULL;
this->rightUp= NULL;
this->center= center;
texture=NULL;
}
bool SurfaceInfo::operator==(const SurfaceInfo &si) const {

View File

@ -831,7 +831,7 @@ void World::initSplattedTextures(){
for(int i=0; i<map.getSurfaceW()-1; ++i){
for(int j=0; j<map.getSurfaceH()-1; ++j){
Vec2f coord;
const Texture2D *texture;
const Texture2D *texture=NULL;
SurfaceCell *sc00= map.getSurfaceCell(i, j);
SurfaceCell *sc10= map.getSurfaceCell(i+1, j);
SurfaceCell *sc01= map.getSurfaceCell(i, j+1);