mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 11:26:11 +00:00
First partially working version of shadow mapping.
We still have to add world matrix in the first rendering pass. this version should work only with centered models.
This commit is contained in:
parent
fb23a9352d
commit
7fa41bd3ef
@ -1,15 +1,11 @@
|
||||
include (../../shared.pri)
|
||||
|
||||
|
||||
QT += opengl
|
||||
|
||||
HEADERS = decorate_shadow.h \
|
||||
shadow_mapping.h
|
||||
|
||||
SOURCES = decorate_shadow.cpp \
|
||||
shadow_mapping.cpp \
|
||||
../../meshlab/filterparameter.cpp \
|
||||
$$GLEWCODE
|
||||
|
||||
TARGET = decorate_shadow
|
||||
|
||||
QT += opengl
|
||||
HEADERS = decorate_shadow.h \
|
||||
shadow_mapping.h
|
||||
SOURCES = decorate_shadow.cpp \
|
||||
shadow_mapping.cpp \
|
||||
../../meshlab/filterparameter.cpp \
|
||||
$$GLEWCODE \
|
||||
../../../../vcglib/wrap/gui/trackball.cpp \
|
||||
../../../../vcglib/wrap/gui/trackmode.cpp
|
||||
TARGET = decorate_shadow
|
||||
|
||||
@ -1,10 +1,23 @@
|
||||
uniform sampler2D shadowMap;
|
||||
uniform float width;
|
||||
varying vec3 normalVec;
|
||||
varying float lightDepth; //current frag distance from light
|
||||
varying vec3 viewVec;
|
||||
varying vec3 lightVec;
|
||||
uniform mat4 mvpl;
|
||||
uniform sampler2DShadow shadowMap;
|
||||
varying vec4 pPos;
|
||||
|
||||
void main(){
|
||||
vec4 shadowCoord = mvpl * pPos;
|
||||
//shadow2DProj fa automaticamente la divisione prospettica..al momento siamo in ortografica e nn serve
|
||||
shadowCoord.xyz = shadowCoord.xyz * 0.5 + 0.5;
|
||||
float sh = shadow2D(shadowMap, shadowCoord.xyz).x;
|
||||
if (sh > 0.95)
|
||||
discard;
|
||||
//else
|
||||
gl_FragColor = vec4(vec3(0.0), 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
uniform mat4 mvpl;
|
||||
|
||||
|
||||
const float w = 0.5;
|
||||
@ -61,4 +74,5 @@ void main(void)
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1,89 +1,10 @@
|
||||
//uniform float far;
|
||||
//uniform float near;
|
||||
uniform float width;
|
||||
uniform vec3 meshCenter;
|
||||
|
||||
//uniform mat4 modelViewMX;
|
||||
//uniform mat4 prjMX;
|
||||
|
||||
|
||||
varying vec3 normalVec;
|
||||
varying float lightDepth;
|
||||
varying vec3 viewVec;
|
||||
varying vec3 lightVec;
|
||||
//uniform mat4 mvpl;
|
||||
varying vec4 pPos;
|
||||
void main(void)
|
||||
{
|
||||
|
||||
vec4 pPos = gl_Vertex;
|
||||
pPos = gl_Vertex;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * pPos;
|
||||
//gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
vec4 lightPosition = gl_ModelViewMatrix * gl_LightSource[0].position;
|
||||
// lighting is performed in eye space
|
||||
vec4 ePos = gl_ModelViewMatrix * gl_Vertex;
|
||||
vec4 eLight = gl_ModelViewMatrix * lightPosition; //lightPosition;
|
||||
|
||||
normalVec = gl_NormalMatrix * gl_Normal;
|
||||
//lightVec = eLight.xyz - ePos.xyz;
|
||||
viewVec = - ePos.xyz;
|
||||
lightVec = eLight.xyz - ePos.xyz;
|
||||
|
||||
//Reproduce GL_LookAt behaviour
|
||||
//create ortonormal basis for lightspace
|
||||
vec3 newZ = normalize(lightPosition.xyz);
|
||||
vec3 newX = normalize(cross(newZ, vec3(0.0, 0.80001, 0.0)));
|
||||
vec3 newY = normalize(cross(newX, newZ));
|
||||
|
||||
|
||||
mat4 toLightSpaceRot = mat4(
|
||||
newX.x, newY.x, newZ.x, 0.0,
|
||||
newX.y, newY.y, newZ.y, 0.0,
|
||||
newX.z, newY.z, newZ.z, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
|
||||
|
||||
|
||||
//Perform parallel Ortographic projection
|
||||
float nearP = - (width / 2.0);//meshCenter.z - (width / 2.0); //distance of Front clipping plane from VRP measured along VPN (a.k.a. lightDir)
|
||||
float farP = (width / 2.0);//meshCenter.z + (width / 2.0);//distance of Back clipping plane from VRP measured along VPN (a.k.a. lightDir)
|
||||
float leftP = meshCenter.x - width/2.0;
|
||||
float rightP = meshCenter.x + width/2.0;
|
||||
float bottomP = meshCenter.y - width/2.0;
|
||||
float topP = meshCenter.y + width/2.0;
|
||||
|
||||
|
||||
mat4 parallelViewProject = mat4(
|
||||
2.0/(rightP-leftP), 0.0, 0.0, 0.0,
|
||||
0.0, 2.0/(topP-bottomP), 0.0, 0.0,
|
||||
0.0, 0.0, 2.0/(farP - nearP), 0.0,
|
||||
-(rightP + leftP)/(rightP - leftP), -(topP + bottomP)/(topP-bottomP), -(farP + nearP)/(farP - nearP), 1.0
|
||||
);
|
||||
|
||||
vec4 lightPos = parallelViewProject
|
||||
* toLightSpaceRot
|
||||
* gl_Vertex;
|
||||
|
||||
|
||||
// glTexGen basically do:
|
||||
// T = S * Pp * Vp * M * vertex
|
||||
//
|
||||
// vertex from local to world space (M)
|
||||
// then to Light (projector) space (Vp)
|
||||
// then projected (Pp)
|
||||
// and at this point adjust to get texcoord from [-1, 1] to [0, 1] range (S)
|
||||
mat4 texAdjTrSc = mat4(
|
||||
0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.5, 0.5, 0.5, 1.0
|
||||
);
|
||||
//vec4 prova = texAdjTrSc * lightPos;
|
||||
lightDepth = lightPos.z;
|
||||
|
||||
gl_TexCoord[0] = texAdjTrSc * lightPos;
|
||||
|
||||
// we also need world space light vector
|
||||
//lightVecDist = (lightDirection.xyz - gl_Vertex.xyz) * (1.0 / zFar);
|
||||
|
||||
//gl_Position = gl_ModelViewProjectionMatrix * pPos;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
@ -42,6 +42,7 @@ ShadowMapping::~ShadowMapping(){}
|
||||
|
||||
bool ShadowMapping::Init()
|
||||
{
|
||||
this->_texSize = 512;
|
||||
compileLinkSM();
|
||||
return true;
|
||||
}
|
||||
@ -54,43 +55,85 @@ void ShadowMapping::RunShader(MeshModel& m, GLArea* gla){
|
||||
GLfloat g_mModelView[16];
|
||||
GLfloat g_mProjection[16];
|
||||
|
||||
this->_texSize = bb.Diag();
|
||||
(this->_texSize % 2) == 0 ? this->_texSize = this->_texSize + 2 : this->_texSize++;
|
||||
|
||||
glUseProgram(this->_depthShaderProgram);
|
||||
this->_diag = bb.Diag();
|
||||
/*glUseProgram(this->_depthShaderProgram);
|
||||
GLint uLocWidth = glGetUniformLocation(this->_depthShaderProgram, "width");
|
||||
GLint uLocMeshCenter = glGetUniformLocation(this->_depthShaderProgram, "meshCenter");
|
||||
|
||||
glUniform1f(uLocWidth, this->_texSize);
|
||||
glUniform3f(uLocMeshCenter, center[0], center[1], center[2]);
|
||||
*/
|
||||
|
||||
this->Setup();
|
||||
this->Bind(m);
|
||||
m.Render(vcg::GLW::DMFlat, vcg::GLW::CMPerFace, vcg::GLW::TMPerWedge);
|
||||
this->GetQImage();
|
||||
this->Unbind();
|
||||
//vcg::Matrix44f mv, pr;
|
||||
|
||||
glUseProgram(0);
|
||||
GLfloat lP[4];
|
||||
glGetLightfv(GL_LIGHT0, GL_POSITION, lP);
|
||||
vcg::Point3f light = -vcg::Point3f(lP[0],lP[1],lP[2]);
|
||||
|
||||
vcg::Matrix44f tm = gla->trackball.Matrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(-(this->_diag/2),
|
||||
this->_diag/2,
|
||||
-(this->_diag/2),
|
||||
this->_diag/2,
|
||||
-(this->_diag/2),
|
||||
this->_diag/2);
|
||||
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, g_mProjection);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
vcg::Point3f u, v;
|
||||
//mi seleziona automaticamente un upvector che mi eviti casi degeneri...nel caso vada bene 010 sceglie quello
|
||||
vcg::GetUV(light, u, v, vcg::Point3f(0,-1,0));
|
||||
glLoadIdentity();
|
||||
gluLookAt(0, 0, 0, light[0], light[1], light[2], v[0], v[1], v[2]);
|
||||
|
||||
//glMultMatrixf(tm.transpose().V());
|
||||
//glMultMatrixf(m.cm.Tr.transpose().V());
|
||||
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, g_mModelView);
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(4.0, 4.0);
|
||||
this->Setup();
|
||||
this->Bind();
|
||||
m.Render(vcg::GLW::DMSmooth, vcg::GLW::CMNone, vcg::GLW::TMNone);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
this->GetQImage();
|
||||
this->Unbind();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
// glUseProgram(0);
|
||||
|
||||
|
||||
GLint depthFuncOld;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &depthFuncOld);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
vcg::Matrix44f mvpl = (vcg::Matrix44f(g_mProjection).transpose() * vcg::Matrix44f(g_mModelView).transpose()).transpose();
|
||||
glUseProgram(this->_objectShaderProgram);
|
||||
uLocWidth = glGetUniformLocation(this->_objectShaderProgram, "width");
|
||||
uLocMeshCenter = glGetUniformLocation(this->_objectShaderProgram, "meshCenter");
|
||||
|
||||
glUniform1f(uLocWidth, gla->size().width());
|
||||
glUniform3f(uLocMeshCenter, center[0], center[1], center[2]);
|
||||
GLuint matrixLoc = glGetUniformLocation(this->_objectShaderProgram, "mvpl");
|
||||
glUniformMatrix4fv(matrixLoc, 1, 0, mvpl.V());
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
GLuint loc = glGetUniformLocation(this->_objectShaderProgram, "shadowMap");
|
||||
glUniform1i(loc, 1);
|
||||
glUniform1i(loc, 0);
|
||||
|
||||
m.Render(vcg::GLW::DMSmooth, vcg::GLW::CMPerVert, vcg::GLW::TMPerWedge);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthFunc((GLenum)depthFuncOld);
|
||||
glUseProgram(0);
|
||||
|
||||
//glEnable (GL_BLEND);
|
||||
//glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
int error = glGetError();
|
||||
@ -106,15 +149,12 @@ bool ShadowMapping::Setup()
|
||||
if (_initOk)
|
||||
return true;
|
||||
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
|
||||
// depth buffer
|
||||
glGenRenderbuffersEXT(1, &(this->_depth));
|
||||
/*glGenRenderbuffersEXT(1, &(this->_depth));
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this->_depth);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->_texSize, this->_texSize);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, this->_depth);
|
||||
|
||||
*/
|
||||
// color buffer
|
||||
glGenTextures(1, &this->_shadowMap);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
@ -124,11 +164,19 @@ bool ShadowMapping::Setup()
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
//glGenerateMipmapEXT(GL_TEXTURE_2D);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_texSize, this->_texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->_shadowMap, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, this->_texSize, this->_texSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, this->_shadowMap, 0);
|
||||
//cosi specifichi che il colore non importa, che il fbo non ha niente sull'attachment colore
|
||||
GLenum drawBuffers[] = {GL_NONE};
|
||||
glDrawBuffersARB(1, drawBuffers);
|
||||
|
||||
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
_initOk = (err == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
@ -136,7 +184,7 @@ bool ShadowMapping::Setup()
|
||||
return _initOk;
|
||||
}
|
||||
|
||||
void ShadowMapping::Bind(MeshModel &m)
|
||||
void ShadowMapping::Bind()
|
||||
{
|
||||
assert(_initOk);
|
||||
|
||||
@ -144,7 +192,7 @@ void ShadowMapping::Bind(MeshModel &m)
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0, 0, this->_texSize, this->_texSize);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void ShadowMapping::Unbind()
|
||||
@ -164,6 +212,29 @@ void ShadowMapping::GetQImage()
|
||||
|
||||
QImage img(this->_texSize, this->_texSize, QImage::Format_RGB32);
|
||||
|
||||
float *tempFBuf = new float[this->_texSize * this->_texSize *1 ];
|
||||
float *tempFBufPtr = tempFBuf;
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, tempFBufPtr);
|
||||
for (int i = 0; i < this->_texSize; ++i) {
|
||||
QRgb *scanLine = (QRgb*)img.scanLine(i);
|
||||
for (int j = 0; j < this->_texSize; ++j) {
|
||||
const unsigned char val = (unsigned char) (tempFBufPtr[0] * 255.0f);
|
||||
scanLine[j] = qRgb(val, val, val);
|
||||
tempFBufPtr ++;
|
||||
}
|
||||
}
|
||||
delete[] tempFBuf;
|
||||
img.mirrored().save("./_shadowMapTXT.png", "PNG");
|
||||
}
|
||||
|
||||
/* void ShadowMapping::GetQImage()
|
||||
{
|
||||
if (!_initOk)
|
||||
return;
|
||||
|
||||
QImage img(this->_texSize, this->_texSize, QImage::Format_RGB32);
|
||||
|
||||
unsigned char *tempBuf = new unsigned char[this->_texSize * this->_texSize * 3];
|
||||
unsigned char *tempBufPtr = tempBuf;
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
@ -178,6 +249,7 @@ void ShadowMapping::GetQImage()
|
||||
delete[] tempBuf;
|
||||
img.mirrored().save("./_shadowMapTXT.png", "PNG");
|
||||
}
|
||||
*/
|
||||
|
||||
bool ShadowMapping::compileLinkSM(){
|
||||
GLenum err = glewInit();
|
||||
|
||||
@ -49,14 +49,14 @@ private:
|
||||
bool compileLinkSM();
|
||||
//bool ClearBuffers();
|
||||
bool Setup();
|
||||
void Bind(MeshModel&);
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void GetQImage();
|
||||
void printShaderInfoLog(GLuint);
|
||||
void printProgramInfoLog(GLuint);
|
||||
|
||||
bool _initOk;
|
||||
int _texSize;
|
||||
int _texSize, _diag;
|
||||
GLuint _shadowMap, _depth;
|
||||
GLuint _fbo;
|
||||
GLuint _depthShaderProgram, _objectShaderProgram;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user