Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 使用VBO在简单平面上的亮度不正确_Opengl_Sdl_Vbo - Fatal编程技术网

Opengl 使用VBO在简单平面上的亮度不正确

Opengl 使用VBO在简单平面上的亮度不正确,opengl,sdl,vbo,Opengl,Sdl,Vbo,我用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 &

我用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);
}
#包括
#包括
#包括
#定义偏移量缓冲区(偏移量)((字符*)NULL+(偏移量))
静态GLfloat位置[4]={0.0f,5.0f,0.0f,1.0f};
静态GLfloat漫反射[3]={0.40f,0.40f,0.40f};
静态GLfloat镜面反射[3]={0.80f,0.80f,0.80f};
静态GLfloat发射[3]={0.00f,0.00f,0.20f};
常量静态整数宽度=640;
常数静态整数高度=480;
结构顶点
{
浮动x,y,z;
浮动nx,ny,nz;
};
静态顶点[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
};
静态void eventListener(SDL_事件*pEvent,bool*pContinue)
{
while(SDL_PollEvent(pEvent))
{
开关(pEvent->类型)
{
案例SDL_退出:
*pContinue=假;
打破
案例SDL_按键关闭:
开关(pEvent->key.keysym.sym)
{
案例SDLK_逃生:
*pContinue=假;
打破
}
}
}
}
内部主(内部ac,字符**av)
{
bool continuer=true;
SDL_事件;
GLuint vboID=0;
SDL_Init(SDL_Init_视频);
SDL_WM_SetCaption(“VBO测试”,空);
SDL_设置视频模式(宽度、高度、32,SDL_OPENGL);
//初始化投影
glMatrixMode(GL_投影);
glLoadIdentity();
glViewport(0,0,宽度,高度);
透视图(60.0,(浮动)(宽度/高度),1.0华氏度,1000.0华氏度);
glMatrixMode(GLU模型视图);
glLoadIdentity();
//初始化灯光设置
glEnable(德国劳埃德大学照明);
glEnable(GL_LIGHT0);
glEnable(GLU深度试验);
glLightfv(GL_LIGHT0,GL_位置,位置);
GLMATERIALV(GL_前部和后部,GL_漫反射,漫反射);
GLMATERALEV(GL_前部和后部,GL_镜面反射,镜面反射);
GLMATERIALV(GL_前部和后部、GL_发射、发射);
glMateriali(GL_正面和背面,GL_光泽,100);
//初始化VBO设置
glewInit();
int vertexSize=4*sizeof(顶点);
if(glIsBuffer(vboID)=GL_TRUE)
glDeleteBuffers(1和vboID);
glGenBuffers(1,&vboID);
glBindBuffer(GL_数组_BUFFER,vboID);
glBufferData(GLU数组缓冲区、顶点大小、顶点、GLU静态图);
glBindBuffer(GL_数组_BUFFER,0);
//环路
while(continuer)
{
eventListener(&event,&continuer);
glClearDepth(1.0f);
glClearColor(0.13f、0.12f、0.13f、1.0f);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glLoadIdentity();
gluLookAt(0.0f、5.0f、0.0f、0.0f、0.0f、0.0f、1.0f、0.0f、0.0f);
//锁缓冲区
glBindBuffer(GL_数组_BUFFER,vboID);
glEnableClientState(GL_顶点_数组);
glVertexPointer(3,GL_浮点,sizeof(顶点),OFFSET_缓冲区(0));
glEnableClientState(GL_普通_阵列);
glNormalPointer(GL_FLOAT、sizeof(顶点)、OFFSET_缓冲区(3*sizeof(GLfloat));
gldrawArray(GL_四边形,0,24);
glDisableClientState(GL_NORMAL_数组);
glDisableClientState(GL_顶点_数组);
//解锁缓冲区
glBindBuffer(GL_数组_BUFFER,0);
glFlush();
SDL_GL_SwapBuffers();
}
SDL_退出();
返回(0);
}

亮度似乎正常,但渲染不正确。顶点结构中的值来自从Blender导出的简单平面网格文件,因此我认为数据是正确的。有人能帮我吗?

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

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

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

法线用于计算与光方向的点积(光方程中的其他内容之一)。如果灯光位于(0,5,0),法线指向(1,0,1),这将生成一种着色颜色,因为它们使这些顶点像是朝向位置(sqrt(2),0,sqrt(2)),但四边形正朝向(0,1,0)。

“因此,通常情况下,平面上的所有像素都应该具有相同的值。”为什么要这样做?将照明与点光源一起使用;这意味着您将在整个曲面上获得不同的颜色强度。我注意到您在设置灯光位置后设置了
modelview
矩阵。但是,灯光的位置将由
modelview
矩阵修改。不知道这是否重要,但我想我应该提一下。谢谢你的回答。是的,这么说是错误的,对不起。随着灯光强度与平面的接近位置(灯光)相结合,平面的颜色应为白色。我更改了MODEL_视图的位置,没有任何更改。我更新了上面的代码。