Bonne journée. Je dessine une scène avec des ombres en utilisant la méthode des cartes d'ombre (lorsque nous restituons une scène du point de vue de la lumière pour récupérer le tampon de profondeur, faire de la texture d'ombre et la projeter sur la scène). texture de l'image, tous les autres objets texturés, bien sûr, perdent leur texture. Mais je veux vraiment la scène texturée avec des ombres :) J'ai lu sur la multitexturing, j'ai effectivement essayé de l'appliquer, mais a échoué. Que dois-je faire exactement? (J'ai pris le code de OpenGl superbible) Voici le code de la procédure d'installation principale. J'ai marqué de nouvelles chaînes (pour les multitexturing) avec // < ====Ombres via des shadowmaps et d'autres textures - comment combiner? OpenGL
void SetupRC()
{
ambientShadowAvailable = GL_TRUE;
npotTexturesAvailable = GL_TRUE;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
fprintf(stdout, "Controls:\n");
fprintf(stdout, "\tRight-click for menu\n\n");
fprintf(stdout, "\tx/X\t\tMove +/- in x direction\n");
fprintf(stdout, "\ty/Y\t\tMove +/- in y direction\n");
fprintf(stdout, "\tz/Z\t\tMove +/- in z direction\n\n");
fprintf(stdout, "\tf/F\t\tChange polygon offset factor +/-\n\n");
fprintf(stdout, "\tq\t\tExit demo\n\n");
// Black background
glClearColor(0.32f, 0.44f, 0.85f, 0.5f);
// Hidden surface removal
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPolygonOffset(factor, 0.0f);
// Set up some lighting state that never changes
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHT0);
// Set up some texture state that never changes
glActiveTexture(GL_TEXTURE1); //<=====
glGenTextures(1, &shadowTextureID);
glBindTexture(GL_TEXTURE_2D, shadowTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
// if (ambientShadowAvailable)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB,
0.5f);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
::scene->fog->init();
RegenerateShadowMap();
}
Voici la procédure de génération shadowmap:
void RegenerateShadowMap(void)
{
GLfloat lightToSceneDistance, nearPlane, fieldOfView;
GLfloat lightModelview[16], lightProjection[16];
GLfloat sceneBoundingRadius = 200.0f; // based on objects in scene
// Save the depth precision for where it's useful
lightToSceneDistance = sqrt(lightPos[0] * lightPos[0] +
lightPos[1] * lightPos[1] +
lightPos[2] * lightPos[2]);
nearPlane = lightToSceneDistance - sceneBoundingRadius;
// Keep the scene filling the depth texture
fieldOfView = (GLfloat)m3dRadToDeg(2.0f * atan(sceneBoundingRadius/lightToSceneDistance));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fieldOfView, 1.0f, nearPlane, nearPlane + (2.0f * sceneBoundingRadius));
glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
// Switch to light's point of view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(lightPos[0], lightPos[1], lightPos[2],
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
glViewport(0, 0, shadowWidth, shadowHeight);
// Clear the depth buffer only
glClear(GL_DEPTH_BUFFER_BIT);
// All we care about here is resulting depth values
glShadeModel(GL_FLAT);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_NORMALIZE);
glActiveTexture(GL_TEXTURE0); //<=====
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1); //<=====
glColorMask(0, 0, 0, 0);
// Overcome imprecision
glEnable(GL_POLYGON_OFFSET_FILL);
// Draw objects in the scene except base plane
// which never shadows anything
DrawModels(GL_FALSE);
// Copy depth values into depth texture
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
0, 0, shadowWidth, shadowHeight, 0);
// Restore normal drawing state
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glActiveTexture(GL_TEXTURE0); //<=====
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColorMask(1, 1, 1, 1);
glDisable(GL_POLYGON_OFFSET_FILL);
// Set up texture matrix for shadow map projection,
// which will be rolled into the eye linear
// texture coordinate generation plane equations
M3DMatrix44f tempMatrix;
m3dLoadIdentity44(tempMatrix);
m3dTranslateMatrix44(tempMatrix, 0.5f, 0.5f, 0.5f);
m3dScaleMatrix44(tempMatrix, 0.5f, 0.5f, 0.5f);
m3dMatrixMultiply44(textureMatrix, tempMatrix, lightProjection);
m3dMatrixMultiply44(tempMatrix, textureMatrix, lightModelview);
// transpose to get the s, t, r, and q rows for plane equations
m3dTransposeMatrix44(textureMatrix, tempMatrix);
}
rendu de la scène proc:
void RenderScene(void)
{
// Track camera angle
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (windowWidth > windowHeight)
{
GLdouble ar = (GLdouble)windowWidth/(GLdouble)windowHeight;
glFrustum(-ar * cameraZoom, ar * cameraZoom, -cameraZoom, cameraZoom, 1.0, 1000.0);
}
else
{
GLdouble ar = (GLdouble)windowHeight/(GLdouble)windowWidth;
glFrustum(-cameraZoom, cameraZoom, -ar * cameraZoom, ar * cameraZoom, 1.0, 1000.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2],
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glViewport(0, 0, windowWidth, windowHeight);
// Track light position
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (showShadowMap)
{
// Display shadow map for educational purposes
glActiveTexture(GL_TEXTURE1); //<=====
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
// Show the shadowMap at its actual size relative to window
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(((GLfloat)shadowWidth/(GLfloat)windowWidth)*2.0f-1.0f,
-1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(((GLfloat)shadowWidth/(GLfloat)windowWidth)*2.0f-1.0f,
((GLfloat)shadowHeight/(GLfloat)windowHeight)*2.0f-1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-1.0f,
((GLfloat)shadowHeight/(GLfloat)windowHeight)*2.0f-1.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0f, 1.0f, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
}
else if (noShadows)
{
// Set up some simple lighting
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
// Draw objects in the scene including base plane
DrawModels(GL_TRUE);
}
else
{
if (!ambientShadowAvailable)
{
GLfloat lowAmbient[4] = {0.1f, 0.1f, 0.1f, 1.0f};
GLfloat lowDiffuse[4] = {0.35f, 0.35f, 0.35f, 1.0f};
// Because there is no support for an "ambient"
// shadow compare fail value, we'll have to
// draw an ambient pass first...
glLightfv(GL_LIGHT0, GL_AMBIENT, lowAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lowDiffuse);
// Draw objects in the scene, including base plane
DrawModels(GL_TRUE);
// Enable alpha test so that shadowed fragments are discarded
glAlphaFunc(GL_GREATER, 0.9f);
glEnable(GL_ALPHA_TEST);
}
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
// Set up shadow comparison
glActiveTexture(GL_TEXTURE1); //<=====
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_COMPARE_R_TO_TEXTURE);
// Set up the eye plane for projecting the shadow map on the scene
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
glTexGenfv(GL_S, GL_EYE_PLANE, &textureMatrix[0]);
glTexGenfv(GL_T, GL_EYE_PLANE, &textureMatrix[4]);
glTexGenfv(GL_R, GL_EYE_PLANE, &textureMatrix[8]);
glTexGenfv(GL_Q, GL_EYE_PLANE, &textureMatrix[12]);
// Draw objects in the scene, including base plane
DrawModels(GL_TRUE);
//glPushMatrix();
//glScalef(1, -1, 1);
//DrawModels(GL_TRUE);
//glPopMatrix();
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
}
if (glGetError() != GL_NO_ERROR)
fprintf(stderr, "GL Error!\n");
//glBindTexture
// Flush drawing commands
glutSwapBuffers();
//RegenerateShadowMap();
}
Et une exemple d'objet texturé dessiner:
CTeapot::CTeapot(std::string fn, float s, float iX, float iY, float iZ)
{
this->setCoords(iX, iY, iZ);
this->size = s;
glActiveTexture(GL_TEXTURE0); //<=====
try
{
this->texture = new C2DTexture(fn);
}
catch(ERR::CError err)
{
throw err;
}
glActiveTexture(GL_TEXTURE1); //<=====
}
void CTeapot::draw()
{
glPushMatrix();
glTranslatef(this->coords[0], this->coords[1], this->coords[2]);
if(this->angle[0] != 0.0f)
glRotatef(this->angle[0], 1.0f, 0.0f, 0.0f);
if(this->angle[1] != 0.0f)
glRotatef(this->angle[1], 0.0f, 1.0f, 0.0f);
if(this->angle[2] != 0.0f)
glRotatef(this->angle[2], 0.0f, 0.0f, 1.0f);
glScalef(this->size, this->size, this->size);
glActiveTexture(GL_TEXTURE0); //<=====
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->texture->getGLTexture());
glutSolidTeapot(this->size);
glPopMatrix();
glActiveTexture(GL_TEXTURE1); //<=====
//glEnable(GL_TEXTURE_2D);
}
C2DTexture texture generaton proc:
C2DTexture::C2DTexture(std::string fn)
{
this->filename = fn;
this->imgTexture = auxDIBImageLoad(this->filename.c_str());
if(this->imgTexture == NULL)
throw ERR::CError(ERR::ERR_NOSUCHFILE, ERR::ERR_NOSUCHFILETEXT + this->filename);
// Creating a texture
glGenTextures(1, &this->glTexture);
glBindTexture(GL_TEXTURE_2D, this->glTexture);
// Setting filters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, this->imgTexture->sizeX, this->imgTexture->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, this->imgTexture->data);
}
>> Vous avez essayé d'appliquer la multi-texturation? Cela n'apparaît pas dans votre code. Oui, j'ai essayé, j'ai échoué et je l'ai enlevé :) Je devais savoir ceci: >> vous voulez mapper la texture de profondeur à l'unité de texture 1: la configuration de l'unité de texture pour la projection d'ombre doit être précédée par un glActiveTexture (GL_TEXTURE1) - la BindTexture, le TexGen, et le texturing lié Enable/Disable.Bien sûr, vous devez revenir à l'unité de texture 0 pour le reste Je vais essayer à nouveau en utilisant votre conseil, puis dire si cela a fonctionné :) – Irene
>> Il est plus rapide de dessiner directement à la texture avec le framebuffer_object extension, que pour copier Merci! Je vais essayer – Irene
Et j'ai une autre question: est une unité de texture pour une texture? Ou je peux lier plus de textures comme toujours dans un calque courant? – Irene