0

ここで、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;
}
4

1 に答える 1

0

OpenGL選択モードをシェーダーと一緒に使用しますか?もしそうなら、これはおそらくあなたの問題です:選択モードはおそらくソフトウェア実装へのフォールバックを引き起こします。GPUで選択モードを実行するOpenGL実装がないことを私は知っています。このコードパスはめったに使用されないため、バグが発生している可能性が非常に高くなります。特に、GPUでエミュレートする必要があるシェーダーと一緒に使用する場合。シェーダーJITコンパイラーがバグのあるコードを出力すると、クラッシュします。

何よりも、選択モードは新しいOpenGLバージョンから完全に削除されました。選択モード(エラーが発生しやすく低速)の代わりに、単一チャネルの整数カラーバッファーがアタッチされたフレームバッファーオブジェクトにレンダリングする必要があります。各オブジェクトは、異なる「インデックス」カラーでレンダリングされます。インデックス画像を読み戻すことにより、ピクセル値に基づいて選択を行うことができます。これを実際に選択投影マトリックスと組み合わせて、フラグメントの生成をビューボリュームの小さなサブセットに制限することができます。

于 2012-11-29T20:53:36.767 に答える