我有一個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
並將其翻譯爲新的正方形時,該作品是否仍具有適當的底紋?
解決我遇到的問題的最佳方法是什麼?
嗯。這似乎是一個錯誤。今晚我會改變它,看看會發生什麼 – Nathan 2011-01-12 15:45:18