2011-01-10 41 views
1

我有一個OBJ &從3DS Max導出的MTL文件,這是一個完整的國際象棋集。在我的最終結果中,我希望能夠選擇一個遊戲塊&,然後選擇一個方塊來移動它。我有綁在一起的問題的要素是:什麼是用着色器繪製3D對象的正確方法?

  • 對象選擇
  • 着色

我有我的目標進口商在兩個方面的工作。

1)將所有東西和相似的材料分組到一個名爲Mesh的結構中,並循環遍歷所有繪製每個幀的model.meshes

2)確定棋盤,每個方塊,&每個遊戲塊,並將相關的頂點,材質等放入一個名爲GroupObject的結構中。他們被放置在model.objects我循環繪製每一幀。

下面是#1和#2中描述的每個選項的截圖。在SS的頂部1/2處,我只是畫出網格,所有陰影看起來都是正確的,但沒有任何可選的。在下半場,我可以選擇一款遊戲或一個正方形,但模型看起來像廢話。

http://img815.imageshack.us/img815/2158/chesst.png

此外,如果我使用着色器與#2的代碼,平移縮放&減慢到爬行。它幾乎完全沒有響應。

以下是調用每個框架繪製對象的方法。前2條註釋行是我嘗試選擇1的地方,並且只畫我的結構Mesh's,它看起來不錯。旋轉&縮放也很流暢,但我無法選擇對象b/c我無法做到Mesh的glPushName。現在,代碼循環遍歷每個model.objects,所以我可以運行glPushName((int)object);,這是挑選/選擇遊戲塊或方塊所必需的。註釋掉部分中,我嘗試和應用着色器通過model.objects循環時,這是非常緩慢(循環model.mesh的時候沒有慢下來)

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

//for (int i = 0; i < model.getNumberOfMeshes(); ++i) 
//{ 
for (int i = 0; i < (int)model.objects.size(); i++) 
{ 
    ModelOBJ::GroupObject *object = model.objects[i]; 

    glPushName((int)object); 

    int faceSize = (int)object->faces.size(); 

    for (int j = 0; j < faceSize; j++) 
    { 

     ModelOBJ::Face *face = object->faces[j]; 
     pMaterial = &model.getMaterial(face->materialId); 


     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)pMaterial->ambient); 
     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)pMaterial->diffuse); 
     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)pMaterial->specular); 
     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * 128.0f); 

     glDisable(GL_TEXTURE_2D); 
     drawFace(*face); 

     //if (pMaterial->bumpMapFilename.empty()) 
     //{ 
      // Per fragment Blinn-Phong code path. 

     // glUseProgram(blinnPhongShader); 

     // // Bind the color map texture. 

     // texture = nullTexture; 

     // if (enableTextures) 
     // { 
     //  iter = modelTextures.find(pMaterial->colorMapFilename); 

     //  if (iter != modelTextures.end()) 
     //   texture = iter->second; 
     // } 

     // glActiveTexture(GL_TEXTURE0); 
     // glEnable(GL_TEXTURE_2D); 
     // glBindTexture(GL_TEXTURE_2D, texture); 

     // // Update shader parameters. 

     // glUniform1i(glGetUniformLocation(
     //  blinnPhongShader, "colorMap"), 0); 
     // glUniform1f(glGetUniformLocation(
     //  blinnPhongShader, "materialAlpha"), pMaterial->alpha); 
     //}   
    } 
    glPopName(); 
} 

glBindTexture(GL_TEXTURE_2D, 0); 
glUseProgram(0); 
glDisable(GL_BLEND); 

這裏是drawFace方法的情況下,它的相關

void GLEngine::drawFace(ModelOBJ::Face &face) 
{ 
if ((int)face.numVertices <= 3) 
    glBegin(GL_TRIANGLES); 
else 
    glBegin(GL_POLYGON); 

for (int v = 0; v < (int)face.numVertices; v++) 
{ 
    if ((int)face.numUVWs > v && face.UVWs != NULL) 
     glTexCoord2f(face.UVWs[v]->x, face.UVWs[v]->y); 

    if ((int)face.numNormals > v && face.normals != NULL) 
     glTexCoord3d(face.normals[v]->x, face.normals[v]->y, face.normals[v]->z); 

    if ((int)face.numVertices > v && face.vertices != NULL) 
     glVertex3f(face.vertices[v]->x, face.vertices[v]->y, face.vertices[v]->z); 
} 
glEnd(); 
} 

,這裏是着色器,我使用

Per-fragment Blinn-Phong shader for a single directional light source. 

[vert] 


varying vec3 normal; 

void main() 
{ 
    normal = normalize(gl_NormalMatrix * gl_Normal); 

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_TexCoord[0] = gl_MultiTexCoord0;  
} 

[frag] 


uniform sampler2D colorMap; 
uniform float materialAlpha; 

varying vec3 normal; 

void main() 
{ 
    vec3 n = normalize(normal); 

    float nDotL = max(0.0, dot(n, gl_LightSource[0].position.xyz)); 
    float nDotH = max(0.0, dot(normal, vec3(gl_LightSource[0].halfVector))); 
    float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess); 

    vec4 ambient = gl_FrontLightProduct[0].ambient; 
    vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL; 
    vec4 specular = gl_FrontLightProduct[0].specular * power; 
    vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular; 

    gl_FragColor = color * texture2D(colorMap, gl_TexCoord[0].st); 
    gl_FragColor.a = materialAlpha; 
} 

你會如何合併所有這些功能整合在一起?我的第一個想法是繪製所有的model.objects沒有任何材料信息,並使其透明。然後運行第二個循環並使用着色器繪製所有完整的材料&。但後來我想,當我開始將遊戲棋子移動到一個新的廣場時,我將如何確保正確的陰影應用於棋子的新位置。當我選擇透明的GroupObject並將其翻譯爲新的正方形時,該作品是否仍具有適當的底紋?

解決我遇到的問題的最佳方法是什麼?

回答

1

,爲什麼要找你的正常的紋理座標GLEngine::drawFace

glTexCoord3d(face.normals[v]->x, face.normals[v]->y, face.normals[v]->z); 

你着色器期望這是一個glNormal3d,你可以在這裏看到:

normal = normalize(gl_NormalMatrix * gl_Normal); 
+0

嗯。這似乎是一個錯誤。今晚我會改變它,看看會發生什麼 – Nathan 2011-01-12 15:45:18

相關問題