0

私はアプリのような3dobjビューアを実装していますが、アプリでオブジェクトをスケーリングすると(OpenGL ES 1.xで)、オブジェクトは明るく(スケールダウン)、暗くなりました(スケールアップすると)。

この「照明の変化」を防ぐ方法はありますか?つまり、全体を通して均一に同じ明るさです。

私は照明法線に何かをしなければならないと思いますか?

私のRenderメソッドは次のとおりです。

void RenderingEngine::Render(const vector<Visual>& visuals, ivec2 screenSize) const
{
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

vector<Visual>::const_iterator visual = visuals.begin();
for (int visualIndex = 0; visual != visuals.end(); ++visual, ++visualIndex) {

    // Set the viewport transform.
    ivec2 size = visual->ViewportSize;
    ivec2 lowerLeft = visual->LowerLeft;
    glViewport(lowerLeft.x, lowerLeft.y, size.x, size.y);

    // Set the light position.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    vec4 lightPosition(0.25, 0.25, 1, 0);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition.Pointer());

    // Set the model-view transform.
    mat4 rotation = visual->Orientation.ToMatrix();
    mat4 translation = visual->Translate;
    mat4 scale;
    scale = scale.Scale(visual->Scale);
    rotation = rotation * scale;
    //mat4 modelview = rotation * m_translation;
    mat4 modelview = rotation * m_translation * translation;

    glLoadMatrixf(modelview.Pointer());

    // Set the projection transform.
    float h = 4.0f * size.y / size.x;
    mat4 projection = mat4::Frustum(-2, 2, -h / 2, h / 2, 5, 50);
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(projection.Pointer());

    // Set the diffuse color.
    vec3 color = visual->Color * 0.75f;
    vec4 diffuse(color.x, color.y, color.z, 1);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.Pointer());

    // Draw the surface.
    int stride = 2 * sizeof(vec3);
    const GLvoid* normalOffset = (const GLvoid*) sizeof(vec3);
    const Drawable& drawable = m_drawables[visualIndex];
    glBindBuffer(GL_ARRAY_BUFFER, drawable.VertexBuffer);
    glVertexPointer(3, GL_FLOAT, stride, 0);
    glNormalPointer(GL_FLOAT, stride, normalOffset);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.IndexBuffer);
    glDrawElements(GL_TRIANGLES, drawable.IndexCount, GL_UNSIGNED_SHORT, 0);
}
}
4

2 に答える 2

0

まず、平行移動行列(または複数の行列)の前に、回転行列とスケール行列を適用します。だから...これの代わりに:

rotation = rotation * scale;
//mat4 modelview = rotation * m_translation;
mat4 modelview = rotation * m_translation * translation;

これを行う:

rotation = rotation * scale;
//mat4 modelview = rotation * m_translation;
mat4 modelview = m_translation * translation * rotation;

次に、なぜ2つの変換行列があるのですか?オブジェクトの頂点をオブジェクト空間からワールド空間に移行するには、1つの行列が必要です。

第三に、なぜ正規行列を作成するのですか?回転後のせん断されたオブジェクトの法線を変更しない限り、変更する理由は実際にはわかりません。頂点に使用するのと同じ回転行列を使用して、オブジェクトの法線を回転させることができます。

于 2013-02-27T22:48:33.857 に答える
0

この解決策は私のために働きます。ですから、私と同じ問題に遭遇した主題の初心者のためにこれを共有します。

使用する:

glEnable(GL_NORMALIZE);

サーフェス法線を常に単位長に正規化します。

于 2013-02-28T08:07:49.793 に答える