Scenery3d.cpp   Scenery3d.cpp 
skipping to change at line 23 skipping to change at line 23
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include <QtGlobal> #include <QtGlobal>
#if !defined(Q_OS_WIN)
//exclude StelOpenGL here on windows because of conflicts with GLFuncs.hpp
otherwise (uses QOpenGLFunctions_1_0 directly)
#include "StelOpenGL.hpp"
#endif
//needs to be included before StelOpenGL on Windows
#include "GLFuncs.hpp" #include "GLFuncs.hpp"
#include "Scenery3d.hpp" #include "Scenery3d.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include "StelModuleMgr.hpp" #include "StelModuleMgr.hpp"
#include "StelMovementMgr.hpp" #include "StelMovementMgr.hpp"
#include "StelTranslator.hpp" #include "StelTranslator.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
skipping to change at line 52 skipping to change at line 46
#include "SolarSystem.hpp" #include "SolarSystem.hpp"
#include "Scenery3dMgr.hpp" #include "Scenery3dMgr.hpp"
#include "AABB.hpp" #include "AABB.hpp"
#include <QKeyEvent> #include <QKeyEvent>
#include <QSettings> #include <QSettings>
#include <stdexcept> #include <stdexcept>
#include <cmath> #include <cmath>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#define GET_GLERROR() \ #define GET_GLERROR() StelOpenGL::checkGLErrors(__FILE__,__LINE__);
{ \
GLenum err = glGetError(); \
if (err != GL_NO_ERROR) { \
qWarning("[line %d] GL Error: %d",__LINE__, err); \
} \
}
//macro for easier uniform setting //macro for easier uniform setting
#define SET_UNIFORM(shd,uni,val) shd->setUniformValue(shaderManager.uniform Location(shd,uni),val) #define SET_UNIFORM(shd,uni,val) shd->setUniformValue(shaderManager.uniform Location(shd,uni),val)
static const float LUNAR_BRIGHTNESS_FACTOR=0.2f; static const float LUNAR_BRIGHTNESS_FACTOR=0.2f;
static const float VENUS_BRIGHTNESS_FACTOR=0.005f; static const float VENUS_BRIGHTNESS_FACTOR=0.005f;
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2
//this is the place where this is initialized //this is the place where this is initialized
GLExtFuncs* glExtFuncs; GLExtFuncs* glExtFuncs;
skipping to change at line 115 skipping to change at line 102
shaderParameters.openglES = false; shaderParameters.openglES = false;
shaderParameters.shadowTransform = false; shaderParameters.shadowTransform = false;
shaderParameters.pixelLighting = false; shaderParameters.pixelLighting = false;
shaderParameters.bump = false; shaderParameters.bump = false;
shaderParameters.shadows = false; shaderParameters.shadows = false;
shaderParameters.shadowFilterQuality = S3DEnum::SFQ_LOW; shaderParameters.shadowFilterQuality = S3DEnum::SFQ_LOW;
shaderParameters.pcss = false; shaderParameters.pcss = false;
shaderParameters.geometryShader = false; shaderParameters.geometryShader = false;
shaderParameters.torchLight = false; shaderParameters.torchLight = false;
shaderParameters.frustumSplits = 0; shaderParameters.frustumSplits = 0;
shaderParameters.hwShadowSamplers = false;
sceneBoundingBox = AABB(Vec3f(0.0f), Vec3f(0.0f)); sceneBoundingBox = AABB(Vec3f(0.0f), Vec3f(0.0f));
debugTextFont.setFamily("Courier"); debugTextFont.setFamily("Courier");
debugTextFont.setPixelSize(16); debugTextFont.setPixelSize(16);
#ifndef NDEBUG #ifndef NDEBUG
qDebug()<<"Scenery3d constructor...done"; qDebug()<<"Scenery3d constructor...done";
#endif #endif
} }
skipping to change at line 256 skipping to change at line 244
else else
heightmapLoad = NULL; heightmapLoad = NULL;
parent->updateProgress(q_("Finalizing load..."),6,0,6); parent->updateProgress(q_("Finalizing load..."),6,0,6);
return true; return true;
} }
void Scenery3d::finalizeLoad() void Scenery3d::finalizeLoad()
{ {
//must ensure the correct GL context is active!
//this is not guaranteed with the new QOpenGLWidget outside of init(
) and draw()!
StelApp::getInstance().ensureGLContextCurrent();
currentScene = loadingScene; currentScene = loadingScene;
//move load data to current one //move load data to current one
objModel = objModelLoad; objModel = objModelLoad;
objModelLoad.clear(); objModelLoad.clear();
groundModel = groundModelLoad; groundModel = groundModelLoad;
groundModelLoad.clear(); groundModelLoad.clear();
//upload GL //upload GL
objModel->uploadBuffersGL(); objModel->uploadBuffersGL();
skipping to change at line 593 skipping to change at line 585
SET_UNIFORM(shader,static_cast<ShaderMgr::UNIFORM>(S haderMgr::UNIFORM_MAT_SHADOW0+i), shadowCPM.at(i)); SET_UNIFORM(shader,static_cast<ShaderMgr::UNIFORM>(S haderMgr::UNIFORM_MAT_SHADOW0+i), shadowCPM.at(i));
} }
//Send squared splits to the shader //Send squared splits to the shader
shader->setUniformValue(loc, splitData.v[0], splitData.v[1], splitData.v[2], splitData.v[3]); shader->setUniformValue(loc, splitData.v[0], splitData.v[1], splitData.v[2], splitData.v[3]);
if(shaderParameters.shadowFilterQuality>S3DEnum::SFQ_HARDWAR E) if(shaderParameters.shadowFilterQuality>S3DEnum::SFQ_HARDWAR E)
{ {
//send size of light ortho for each frustum //send size of light ortho for each frustum
loc = shaderManager.uniformLocation(shader,ShaderMgr ::UNIFORM_VEC_LIGHTORTHOSCALE); loc = shaderManager.uniformLocation(shader,ShaderMgr ::UNIFORM_VEC_LIGHTORTHOSCALE);
shader->setUniformValueArray(loc,shadowFrustumSize.c onstData(),4); shader->setUniformValueArray(loc,shadowFrustumSize.c onstData(),shaderParameters.frustumSplits);
} }
} }
loc = shaderManager.uniformLocation(shader,ShaderMgr::UNIFORM_MAT_CU BEMVP); loc = shaderManager.uniformLocation(shader,ShaderMgr::UNIFORM_MAT_CU BEMVP);
if(loc>=0) if(loc>=0)
{ {
//upload cube mvp matrices //upload cube mvp matrices
shader->setUniformValueArray(loc,cubeMVP,6); shader->setUniformValueArray(loc,cubeMVP,6);
} }
} }
skipping to change at line 801 skipping to change at line 793
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
backfaceCullState = false; backfaceCullState = false;
} }
else if(!backfaceCullState && pMaterial->backfacecul l) else if(!backfaceCullState && pMaterial->backfacecul l)
{ {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
backfaceCullState = true; backfaceCullState = true;
} }
} }
GET_GLERROR()
glDrawElements(GL_TRIANGLES, pStelModel->triangleCount * 3, indexDataType, reinterpret_cast<const void*>(pStelModel->startIndex * index DataTypeSize)); glDrawElements(GL_TRIANGLES, pStelModel->triangleCount * 3, indexDataType, reinterpret_cast<const void*>(pStelModel->startIndex * index DataTypeSize));
drawnTriangles+=pStelModel->triangleCount; drawnTriangles+=pStelModel->triangleCount;
} }
if(!backfaceCullState) if(!backfaceCullState)
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
if(curShader) if(curShader)
curShader->release(); curShader->release();
skipping to change at line 1125 skipping to change at line 1118
//Draw the scene //Draw the scene
if(!drawArrays(false)) if(!drawArrays(false))
{ {
success = false; success = false;
break; break;
} }
} }
} }
//Unbind //Unbind
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
//reset viewport (see StelPainter::setProjector) //reset viewport (see StelPainter::setProjector)
const Vec4i& vp = altAzProjector->getViewport(); const Vec4i& vp = altAzProjector->getViewport();
glViewport(vp[0], vp[1], vp[2], vp[3]); glViewport(vp[0], vp[1], vp[2], vp[3]);
//Move polygons back to normal position //Move polygons back to normal position
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.0f,0.0f); glPolygonOffset(0.0f,0.0f);
//Reset //Reset
skipping to change at line 1571 skipping to change at line 1564
{ {
//In this mode, only the "perspective" shadow mode can be us ed (otherwise it would need up to 6*4 shadowmaps at once) //In this mode, only the "perspective" shadow mode can be us ed (otherwise it would need up to 6*4 shadowmaps at once)
renderIntoCubemapGeometryShader(); renderIntoCubemapGeometryShader();
} }
else else
{ {
renderIntoCubemapSixPasses(); renderIntoCubemapSixPasses();
} }
//cubemap fbo must be released //cubemap fbo must be released
glBindFramebuffer(GL_FRAMEBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,defaultFBO);
//reset GL state //reset GL state
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
//reset viewport (see StelPainter::setProjector) //reset viewport (see StelPainter::setProjector)
const Vec4i& vp = altAzProjector->getViewport(); const Vec4i& vp = altAzProjector->getViewport();
glViewport(vp[0], vp[1], vp[2], vp[3]); glViewport(vp[0], vp[1], vp[2], vp[3]);
skipping to change at line 2046 skipping to change at line 2039
else else
{ {
//assume everything is available on Desktop GL for now (shou ld be ok on GL>2.0 as Stellarium base requires) //assume everything is available on Desktop GL for now (shou ld be ok on GL>2.0 as Stellarium base requires)
supportsShadows = true; supportsShadows = true;
supportsShadowFiltering = true; supportsShadowFiltering = true;
} }
} }
void Scenery3d::init() void Scenery3d::init()
{ {
initializeOpenGLFunctions();
OBJ::setupGL(); OBJ::setupGL();
QOpenGLContext* ctx = QOpenGLContext::currentContext(); QOpenGLContext* ctx = QOpenGLContext::currentContext();
Q_ASSERT(ctx);
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2
//initialize additional functions needed and not provided through St elOpenGL //initialize additional functions needed and not provided through St elOpenGL
glExtFuncs = new GLExtFuncs(); glExtFuncs = new GLExtFuncs();
glExtFuncs->init(ctx); glExtFuncs->init(ctx);
#endif #endif
//save opengl ES state //save opengl ES state
shaderParameters.openglES = ctx->isOpenGLES(); shaderParameters.openglES = ctx->isOpenGLES();
skipping to change at line 2361 skipping to change at line 2356
qWarning() << "[Scenery3D] glCheckFramebuffe rStatus failed, probably can't use cube map"; qWarning() << "[Scenery3D] glCheckFramebuffe rStatus failed, probably can't use cube map";
ret = false; ret = false;
break; break;
} }
else else
ret = true; ret = true;
} }
} }
//unbind last framebuffer //unbind last framebuffer
glBindFramebuffer(GL_FRAMEBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,defaultFBO);
//initialize cube rotations... found by trial and error :) //initialize cube rotations... found by trial and error :)
QMatrix4x4 stackBase; QMatrix4x4 stackBase;
//all angles were found using some experimenting :) //all angles were found using some experimenting :)
//this is the EAST face (y=1) //this is the EAST face (y=1)
stackBase.rotate(90.0f,-1.0f,0.0f,0.0f); stackBase.rotate(90.0f,-1.0f,0.0f,0.0f);
if(cubemappingMode >= S3DEnum::CM_CUBEMAP) if(cubemappingMode >= S3DEnum::CM_CUBEMAP)
{ {
skipping to change at line 2624 skipping to change at line 2619
#else #else
GLenum depthPcss = GL_DEPTH_COMPONENT; GLenum depthPcss = GL_DEPTH_COMPONENT;
GLenum depthNormal = GL_DEPTH_COMPONENT; GLenum depthNormal = GL_DEPTH_COMPONENT;
#endif #endif
//pcss is only enabled if filtering is also enabled //pcss is only enabled if filtering is also enabled
bool pcssEnabled = shaderParameters.pcss && (shaderP arameters.shadowFilterQuality == S3DEnum::SFQ_LOW || shaderParameters.shado wFilterQuality == S3DEnum::SFQ_HIGH); bool pcssEnabled = shaderParameters.pcss && (shaderP arameters.shadowFilterQuality == S3DEnum::SFQ_LOW || shaderParameters.shado wFilterQuality == S3DEnum::SFQ_HIGH);
//for OpenGL ES2, type has to be UNSIGNED_SHORT or U NSIGNED_INT for depth textures, desktop does probably not care //for OpenGL ES2, type has to be UNSIGNED_SHORT or U NSIGNED_INT for depth textures, desktop does probably not care
glTexImage2D(GL_TEXTURE_2D, 0, (pcssEnabled ? depthP css : depthNormal), shadowmapSize, shadowmapSize, 0, GL_DEPTH_COMPONENT, GL _UNSIGNED_SHORT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, (pcssEnabled ? depthP css : depthNormal), shadowmapSize, shadowmapSize, 0, GL_DEPTH_COMPONENT, GL _UNSIGNED_SHORT, NULL);
GLint filter = (shaderParameters.shadowFilterQuality //we use hardware-accelerated depth compare mode, un
== S3DEnum::SFQ_HARDWARE less pcss is used
shaderParameters.hwShadowSamplers = false;
//NOTE: cant use depth compare mode on ES2
if(!pcssEnabled)
{
#ifndef QT_OPENGL_ES_2
if(!isEs)
{
glTexParameteri(GL_TEXTURE_2D, GL_TE
XTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TE
XTURE_COMPARE_FUNC, GL_LEQUAL);
shaderParameters.hwShadowSamplers =
true;
}
#endif
}
//IF we support hw shadow sampling, then we may enab
le linear filtering, otherwise filtering depth values directly would not ma
ke much sense
GLint filter = shaderParameters.hwShadowSamplers &&
(shaderParameters.shadowFilterQuality == S3DEnum::SFQ_HARDWARE
|| shaderParameters.shadowFilterQual ity == S3DEnum::SFQ_LOW_HARDWARE || shaderParameters.shadowFilterQual ity == S3DEnum::SFQ_LOW_HARDWARE
|| shaderParameters.shadowFilterQual ity == S3DEnum::SFQ_HIGH_HARDWARE) ? GL_LINEAR : GL_NEAREST; || shaderParameters.shadowFilterQual ity == S3DEnum::SFQ_HIGH_HARDWARE) ? GL_LINEAR : GL_NEAREST;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , filter);
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2
if(!isEs) if(!isEs)
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BA SE_LEVEL,0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BA SE_LEVEL,0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MA X_LEVEL,0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MA X_LEVEL,0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WR AP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WR AP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WR AP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WR AP_T, GL_CLAMP_TO_BORDER);
const float ones[] = {1.0f, 1.0f, 1.0f, 1.0f }; const float ones[] = {1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_B ORDER_COLOR, ones); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_B ORDER_COLOR, ones);
} }
#endif #endif
//we use hardware-accelerated depth compare mode, un
less pcss is used
//NOTE: cant use depth compare mode on ES2
if(!pcssEnabled)
{
#ifndef QT_OPENGL_ES_2
if(!isEs)
{
glTexParameteri(GL_TEXTURE_2D, GL_TE
XTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TE
XTURE_COMPARE_FUNC, GL_LEQUAL);
}
#endif
}
//Attach the depthmap to the Buffer //Attach the depthmap to the Buffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTA CHMENT, GL_TEXTURE_2D, shadowMapsArray[i], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTA CHMENT, GL_TEXTURE_2D, shadowMapsArray[i], 0);
//NOTE: disabling the drawbuffer should be required //NOTE: disabling the drawbuffer should be required
//but the respective functions are not available on GLES2? //but the respective functions are not available on GLES2?
//On ANGLE, it seems to work without this settings ( framebuffer is complete, etc.) //On ANGLE, it seems to work without this settings ( framebuffer is complete, etc.)
//but I don't know if it will work on other ES platf orms? //but I don't know if it will work on other ES platf orms?
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2
if(!isEs) if(!isEs)
skipping to change at line 2680 skipping to change at line 2679
qWarning() << "[Scenery3D] glCheckFramebuffe rStatus failed, can't use FBO"; qWarning() << "[Scenery3D] glCheckFramebuffe rStatus failed, can't use FBO";
break; break;
} }
else if (i==shaderParameters.frustumSplits-1) else if (i==shaderParameters.frustumSplits-1)
{ {
valid = true; valid = true;
} }
} }
//Done. Unbind and switch to normal texture unit 0 //Done. Unbind and switch to normal texture unit 0
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
qDebug()<<"[Scenery3D] shadowmapping initialized"; qDebug()<<"[Scenery3D] shadowmapping initialized";
} }
else else
{ {
qWarning()<<"[Scenery3D] shadowmapping not supported or disa bled"; qWarning()<<"[Scenery3D] shadowmapping not supported or disa bled";
} }
if(!valid) if(!valid)
skipping to change at line 2704 skipping to change at line 2703
} }
return valid; return valid;
} }
void Scenery3d::draw(StelCore* core) void Scenery3d::draw(StelCore* core)
{ {
//cant draw if no models //cant draw if no models
if(!objModel || !objModel->hasStelModels()) if(!objModel || !objModel->hasStelModels())
return; return;
//find out the default FBO
defaultFBO = StelApp::getInstance().getDefaultFBO();
//reset render statistic //reset render statistic
drawnTriangles = drawnModels = materialSwitches = shaderSwitches = 0 ; drawnTriangles = drawnModels = materialSwitches = shaderSwitches = 0 ;
requiresCubemap = core->getCurrentProjectionType() != StelCore::Proj ectionPerspective; requiresCubemap = core->getCurrentProjectionType() != StelCore::Proj ectionPerspective;
//update projector from core //update projector from core
altAzProjector = core->getProjection(StelCore::FrameAltAz, StelCore: :RefractionOff); altAzProjector = core->getProjection(StelCore::FrameAltAz, StelCore: :RefractionOff);
//perform Z-sorting for correct transparency //perform Z-sorting for correct transparency
//this uses the object's centroids for sorting, so the OBJ must be c reated correctly //this uses the object's centroids for sorting, so the OBJ must be c reated correctly
objModel->transparencyDepthSort(-absolutePosition.toVec3f()); objModel->transparencyDepthSort(-absolutePosition.toVec3f());
 End of changes. 17 change blocks. 
37 lines changed or deleted 42 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/