ここで、openglの選択とシェーダーに少し問題がありました。
フォン照明にはシェーダーを使用しています。シェーダーは問題なく機能します。しかし、openglピッキングをシェーダーと組み合わせて使用すると、アプリがクラッシュします。この組み合わせは、5台を超えるコンピューター(Geforce gtx 460 SE、Ati Mobility Radeon HD 5850、Intel Graphic 4000など)で正常に機能します。しかし、いくつかのあいまいな理由で、これらのエラーでクラッシュします。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000cde9cc3, pid=2888, tid=3940
#
# JRE version: 7.0_07-b10
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.3-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [ig4icd64.dll+0x6d9cc3] ShCompile+0x17b3b3
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Projet2\Exe\hs_err_pid2888.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
コンパイルが機能していないようです。動作中のコンピューターでは、コンパイルエラーは発生しません(glGetShaderInfoLogを使用)。
同じことがAMDRadeonHD 6970Mでも発生しますが、エラーはatixxxx.dllに関連しています。
これが私たちのopenglの選択です:
GLint viewport[4];
glSelectBuffer(BUFSIZE,selectBuf);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(x,viewport[3]-y, 5,5,viewport);
FacadeModele::obtenirInstance()->obtenirVue()->obtenirProjection()->appliquer();
glMatrixMode(GL_MODELVIEW);
glInitNames();
glLoadIdentity();
FacadeModele::obtenirInstance()->obtenirVue()->obtenirCamera().positionner();
arbre->afficher();
int hits;
// restorer la matrice originale
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
// retourner au mode de rendering normal
hits = glRenderMode(GL_RENDER);
if (hits > 0)
processHits(hits,selectBuf);
頂点シェーダー:
varying vec3 normal, lightDir1, lightDir2, lightDir3, eyeVec;
void main()
{
// calculer la normale qui sera interpolée pour le nuanceur de fragment
normal = gl_NormalMatrix * gl_Normal;
// calculer la position du sommet dans l'espace de la caméra ("eye-coordinate position")
vec3 ecPosition = vec3( gl_ModelViewMatrix * gl_Vertex );
// vecteur de la direction de la lumière
lightDir1 = vec3( gl_LightSource[0].position.xyz - ecPosition );
lightDir2 = vec3( gl_LightSource[1].position.xyz - ecPosition );
lightDir3 = vec3( gl_LightSource[2].position.xyz - ecPosition );
eyeVec = -ecPosition; // vecteur qui pointe vers le (0,0,0), c'est-à-dire vers l'oeil
gl_FrontColor = gl_Color;
// transformation standard du sommet (ModelView et Projection)
gl_Position = ftransform();
}
フラグメントシェーダー:
varying vec3 normal, lightDir1, lightDir2, lightDir3, eyeVec;
float maxCutoff = 0.9;
void main(void)
{
vec4 couleur = ( ( gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient ) +
( gl_LightSource[0].ambient * gl_FrontMaterial.ambient ) +
( gl_LightSource[1].ambient * gl_FrontMaterial.ambient )
);
// vecteur normal
vec3 N = normalize( normal );
// direction de la lumière
vec3 L = normalize( lightDir1 );
// produit scalaire pour le calcul de la réflexion diffuse
float NdotL = dot( N, L );
vec3 D = normalize(gl_LightSource[0].spotDirection);
float LdotD = dot(-L,D);
float attenuation = (LdotD - maxCutoff)/(gl_LightSource[0].spotCosCutoff-maxCutoff) ;
// calcul de l'éclairage seulement si le produit scalaire est positif
if ( NdotL > 0.0 )
{
// calcul de la composante diffuse
if(attenuation > 0.0)
couleur += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * NdotL*attenuation;
// calcul de la composante spéculaire
vec3 E = normalize( eyeVec );
vec3 R = -reflect( L, N ); // réflexion de L par rapport à N
// produit scalaire pour la réflexion spéculaire
float NdotHV = max( dot( R, E ), 0.0 );
couleur += gl_LightSource[0].specular * gl_FrontMaterial.specular * pow( NdotHV, gl_FrontMaterial.shininess )*attenuation;
}
// vecteur normal
vec3 N2 = normalize( normal );
// direction de la lumière
vec3 L2 = normalize( lightDir2 );
// produit scalaire pour le calcul de la réflexion diffuse
float NdotL2 = dot( N2, L2 );
vec3 D2 = normalize(gl_LightSource[1].spotDirection);
float LdotD2 = dot(-L2,D2);
float attenuation2 = (LdotD2 - maxCutoff)/(gl_LightSource[1].spotCosCutoff-maxCutoff) ;
// calcul de l'éclairage seulement si le produit scalaire est positif
if ( NdotL2 > 0.0 )
{
// calcul de la composante diffuse
if(attenuation2 > 0.0)
couleur += gl_LightSource[1].diffuse * gl_FrontMaterial.diffuse * NdotL2*attenuation2;
// calcul de la composante spéculaire
vec3 E2 = normalize( eyeVec );
vec3 R2 = -reflect( L2, N2 ); // réflexion de L par rapport à N
// produit scalaire pour la réflexion spéculaire
float NdotHV2 = max( dot( R2, E2 ), 0.0 );
}
// vecteur normal
vec3 N3 = normalize( normal );
// direction de la lumière
vec3 L3 = normalize( lightDir3 );
// produit scalaire pour le calcul de la réflexion diffuse
float NdotL3 = dot( N3, L3 );
vec3 D3 = normalize(gl_LightSource[2].spotDirection);
float LdotD3 = dot(-L3,D3);
float attenuation3 = (LdotD3 - maxCutoff)/(gl_LightSource[2].spotCosCutoff-maxCutoff) ;
// calcul de l'éclairage seulement si le produit scalaire est positif
if ( NdotL3 > 0.0 )
{
// calcul de la composante diffuse
if(attenuation3 > 0.0)
couleur += gl_LightSource[2].diffuse * gl_FrontMaterial.diffuse * NdotL3*attenuation3;
// calcul de la composante spéculaire
vec3 E3 = normalize( eyeVec );
vec3 R3 = -reflect( L3, N3 ); // réflexion de L par rapport à N
// produit scalaire pour la réflexion spéculaire
float NdotHV3 = max( dot( R3, E3 ), 0.0 );
}
couleur *= gl_Color;
gl_FragColor = couleur;
}