1

我使用 VBO 编写了一个小型 OpengL 测试程序。我在 (0.0, 5.0, 0.0) 中有一个点,相机也在 (0.0, 5.0, 0.0) 中,它看着点 (0.0, 0.0, 0.0)。我的飞机位于 (0.0, 0.0, 0.0) 位置的中心。因此,通常情况下,平面上的所有像素都应该具有相同的值。但事实并非如此。我尝试了几种代码组合,结果相同。

这是现场的图片:

在此处输入图像描述

如您所见,该点似乎位于左侧,但应将其定位为相机。这不合逻辑。

这是我的代码:

#include <iostream>
#include <SDL/SDL.h>
#include <gl/glew.h>

#define OFFSET_BUFFER(offset)   ((char*)NULL + (offset))

static GLfloat position[4] = {0.0f, 5.0f, 0.0f, 1.0f};
static GLfloat diffuse[3] = {0.40f, 0.40f, 0.40f};
static GLfloat specular[3] = {0.80f, 0.80f, 0.80f};
static GLfloat emissive[3] = {0.00f, 0.00f, 0.20f};

const static int WIDTH = 640;
const static int HEIGHT = 480;

struct Vertex
{
    float x, y, z;
    float nx, ny, nz;
};

static Vertex   vertex[24] =
{
    -1.000000f, 0.000000f, 1.000000f,   //V1
    1.000000f, 0.000000f, 1.000000f,    //N1
    1.000000f, 0.000000f, 1.000000f,    //V2
    1.000000f, 0.000000f, 1.000000f,    //N2
    1.000000f, 0.000000f, -1.000000f,   //V3
    1.000000f, 0.000000f, 1.000000f,    //N3
    -1.000000f, 0.000000f, -1.000000f,  //V4
    1.000000f, 0.000000f, 1.000000f     //N4
};

static void     eventListener(SDL_Event *pEvent, bool *pContinue)
{
    while (SDL_PollEvent(pEvent))
    {
        switch(pEvent->type)
        {
        case SDL_QUIT:
            *pContinue = false;
            break;
        case SDL_KEYDOWN:
            switch (pEvent->key.keysym.sym)
            {
            case SDLK_ESCAPE:
                *pContinue = false;
                break;
            }
        }
    }
}

int             main(int ac, char **av)
{
    bool        continuer = true;
    SDL_Event   event;
    GLuint      vboID = 0;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("VBO tests",NULL);
    SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);

    //Initialize projection

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, WIDTH, HEIGHT);
    gluPerspective(60.0, (float)(WIDTH/HEIGHT), 1.0f, 1000.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //Initialize light settings

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissive);
    glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 100);

    //Initialize VBO settings

    glewInit();

    int vertexSize = 4 * sizeof(Vertex);

    if (glIsBuffer(vboID) == GL_TRUE)
        glDeleteBuffers(1, &vboID);
    glGenBuffers(1, &vboID);
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, vertexSize, vertex, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    //Loop

    while (continuer)
    {
        eventListener(&event, &continuer);

        glClearDepth(1.0f);
        glClearColor(0.13f, 0.12f, 0.13f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();    
        gluLookAt(0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);

        //Lock buffer
        glBindBuffer(GL_ARRAY_BUFFER, vboID);

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), OFFSET_BUFFER(0));

        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT, sizeof(Vertex), OFFSET_BUFFER(3 * sizeof(GLfloat)));

        glDrawArrays(GL_QUADS, 0, 24);

        glDisableClientState(GL_NORMAL_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        //Unlock buffer
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glFlush();
        SDL_GL_SwapBuffers();
    }

    SDL_Quit();
    return (0);
}

亮度似乎有效,但渲染不正确。Vertex 结构中的值来自一个从 Blender 导出的简单平面网格文件,所以我认为数据是正确的。有人可以帮助我吗?

4

2 回答 2

0

我注意到提供的源代码存在两个问题:

  • 法线未标准化。
  • 法线指向一个奇怪的位置(1、0、1),它们不应该指向(0、1、0)吗?

法线用于计算与光方向的点积(以及光方程中的其他内容)。如果您的灯光位于 (0, 5, 0) 并且您的法线指向 (1, 0, 1) 这将生成阴影颜色,因为它们使这些顶点像面对位置 (sqrt(2), 0, sqrt(2 )),但您的四边形面向 (0, 1, 0)。

于 2013-05-13T18:50:16.443 回答
0

检查你的几何和法线向量。你的法线向量在哪里看?你有一个非常奇怪的几何和视图设置,而且最好不要使用旧的固定功能管道。

于 2013-05-13T18:08:16.940 回答