【问题标题】:vertices not being drawn in opengl没有在opengl中绘制的顶点
【发布时间】:2012-04-18 05:47:24
【问题描述】:

我一直无法使用着色器绘制一个简单的顶点指定(类似盒子)的茶壶模型,并带有一些用于平移和旋转的输入。我一遍又一遍地检查了我的 gl 代码和矩阵(-z 上的对象位置、原点处的相机等),但不明白为什么我仍然只是得到一个空白屏幕。为了保持代码简短,我刚刚为我的模型的基本立方体输入了代码(一旦我至少知道我会没事的)。

namespace TeapotViewer{

class TeapotViewer{

private:
    void intitialize();
    void draw();
    void reshape(int h, int w);
    void keyHandle(unsigned char key, int x, int y);
    void initCamera();
    void reset();
    void changeAxis();
    void rotateOnAxis(float rot);
    int createCube(int i);

public:

};

}

#include "TeapotViewer.h"

using namespace glm;

const int S_WIDTH = 800;
const int S_HEIGHT = 600;
const float FOV = 100;
const float P_NEAR = 0.2;
const float P_FAR = 20.0;
const float SPOUT_WIDTH = 0.025;
const float HANDLE_WIDTH = 0.15;
const float ZERO = 0.0;
const int numberOfVertices = 104;
const int noCubeSide = 10;
const int noCubeFace = 4;
const int noLine = 2;

mat4 modelxViewMatrix, projMatrix, viewMatrix, rotationMatrix, translationMatrix;
vec3 rotationAxis;
vec3 teapotPosition  = vec3(0.0, 0.0,-3.0);

const vec3 cameraPosition = vec3(0.0, 0.0, 0.0);
const vec3 cameraDirection = vec3(0.0, 0.0, -1.0);
const vec3 cameraUp = vec3(0.0, 1.0, 0.0);

vec4 vertices[numberOfVertices];
GLuint refVertexArray;
GLuint refVertexBuffer;
GLuint refUniformModelxView;
GLuint refUniformProjection;

const vec4 body[] = {

    vec4(-1.0,-1.0, 1.0, 1.0), vec4(-1.0, 1.0, 1.0, 1.0),
    vec4( 1.0,-1.0, 1.0, 1.0), vec4( 1.0, 1.0, 1.0, 1.0),
    vec4( 1.0,-1.0,-1.0, 1.0), vec4( 1.0, 1.0,-1.0, 1.0),
    vec4(-1.0,-1.0,-1.0, 1.0), vec4(-1.0, 1.0,-1.0, 1.0)
};

const vec3 xAxis = vec3(1.0, 0.0, 0.0);

const vec3 yAxis = vec3(0.0, 1.0, 0.0);

const vec3 zAxis = vec3(0.0, 0.0, 1.0);

// draw callback
void draw(){

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    translationMatrix = translate(mat4(), teapotPosition);

    modelxViewMatrix = viewMatrix*translationMatrix*rotationMatrix;

    glUniformMatrix4fv(refUniformModelxView, 1, &modelxViewMatrix[0][0]);
    glUniformMatrix4fv(refUniformProjection, 1, &projMatrix[0][0]);
    void drawTeapot();

    glutSwapBuffers();
}

void drawTeapot(){

    int bufferIndex = 0;
    // draw cube
    glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeSide);
    bufferIndex += noCubeSide;
    glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeFace);
    bufferIndex += noCubeFace;
    glDrawArrays(GL_TRIANGLE_STRIP, bufferIndex, noCubeFace);
    bufferIndex += noCubeFace;


    // draw the axis of rotation
    if (rotationAxis == xAxis){

        glDrawArrays(GL_LINES, bufferIndex, noLine);
        bufferIndex += noLine;
    }
    if (rotationAxis == yAxis){

        bufferIndex += noLine;
        glDrawArrays(GL_LINES, bufferIndex, noLine);
        bufferIndex += noLine;
    }
    if (rotationAxis == zAxis){

        bufferIndex += noLine*2;
        glDrawArrays(GL_LINES, bufferIndex, noLine);
        bufferIndex += noLine; 

    }  
}

// reset back to the start
void reset(){

    teapotPosition = vec3(0.0, 0.0,-3.0);

    rotationMatrix = mat4();

}

void changeAxis(){

    if(rotationAxis == xAxis)
        rotationAxis = yAxis;
    else
    if(rotationAxis == yAxis)
        rotationAxis = zAxis;
    else
        rotationAxis = xAxis;
}

void rotateOnAxis(float rot){

    rotationMatrix = rotate(rotationMatrix, rot, rotationAxis);
}




// handle keypress
void keyHandle(unsigned char key, int x, int y){

    switch(key){

        case 033:
            exit(EXIT_SUCCESS);
            break;
        case '0':
            reset();
            break;
        case 'a':
            teapotPosition = teapotPosition + vec3(-0.1, 0.0, 0.0);
            break;
        case 'd':
            teapotPosition = teapotPosition + vec3(0.1, 0.0, 0.0);
            break;
        case 'w':
            teapotPosition = teapotPosition + vec3(0.0, 0.1, 0.0);
            break;
        case 's':
            teapotPosition = teapotPosition + vec3(0.0, -0.1, 0.0);
            break;
        case 'q':
            teapotPosition = teapotPosition + vec3(0.0, 0.0, -0.1);
            break;
        case 'e':
            teapotPosition = teapotPosition + vec3(0.0, 0.0, 0.1);
            break;
        case 'j':
            changeAxis();
            break;
        case 'k':
            rotateOnAxis(-5.0);
            break;
        case 'l':
            rotateOnAxis(5.0);
            break;
    }

    glutPostRedisplay();
}


void reshape(int h, int w){

    glViewport(0, 0, h, w);

}

void initCamera(){

    viewMatrix = lookAt(cameraDirection, cameraPosition, cameraUp);
    projMatrix = perspective(FOV, (float)S_WIDTH/(float)S_HEIGHT, P_NEAR, P_FAR);
    reset();
}




int createCube(int i){

    // sides of the cube
    vertices[i++] = body[0];
    vertices[i++] = body[1];
    vertices[i++] = body[2];
    vertices[i++] = body[3];
    vertices[i++] = body[4];
    vertices[i++] = body[5];
    vertices[i++] = body[6];
    vertices[i++] = body[7];
    vertices[i++] = body[0];
    vertices[i++] = body[1];

    // top
    vertices[i++] = body[0];
    vertices[i++] = body[2];
    vertices[i++] = body[4];
    vertices[i++] = body[6];

    //bottom
    vertices[i++] = body[1];
    vertices[i++] = body[3];
    vertices[i++] = body[5];
    vertices[i++] = body[7];

    std::cout << i << '\n';

    return i;

}

int createAxes(int i){

    // X axis
    vertices[i++] = vec4( 2.0, 0.0, 0.0, 1.0);
    vertices[i++] = vec4(-2.0, 0.0, 0.0, 1.0);

    // Y axis
    vertices[i++] = vec4( 0.0, 2.0, 0.0, 1.0);
    vertices[i++] = vec4( 0.0,-2.0, 0.0, 1.0);

    // Z axis
    vertices[i++] = vec4( 0.0, 0.0, 2.0, 1.0);
    vertices[i++] = vec4( 0.0, 0.0,-2.0, 1.0);

    std::cout << i << '\n';

    return i;
}

// Initialize 
void initialize(){

    // generate vertex data
    int i = 0; 
    i = createCube(i);
    i = createAxes(i);

    if(i != numberOfVertices){

        std::cout << "Error creating vertex data: check vertex count\n";
        std::exit(0);
    }

    // set 
    initCamera();

    // load shader and activate shader
    GLuint refVertexShader = Angel::InitShader("Vertex_Shader.glsl", "Fragment_Shader.glsl");
    glUseProgram(refVertexShader);

    // create and activate a new vertex array object (vao)
    glGenVertexArrays(1, &refVertexArray);
    glBindVertexArray(refVertexArray);

    // create and activate a new buffer array object in the vao
    glGenBuffers(1, &refVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, refVertexBuffer);

    // load vertex data into the buffer array
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // load postion pipeline variable
    GLuint refVec4Position = glGetAttribLocation(refVertexShader, "Position");
    glEnableVertexAttribArray(refVec4Position);
    glVertexAttribPointer(refVec4Position, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

    // get pointers for uniform variables in shader program
    refUniformModelxView = glGetUniformLocation(refVertexShader, "ModelxView");
    refUniformProjection = glGetUniformLocation(refVertexShader, "Projection");

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS); 

    glClearColor(0.0, 0.0, 0.0, 1.0);
}

int main(int argc, char* argv[]){

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(S_WIDTH, S_HEIGHT );
    glutCreateWindow("TeapotViewer");

    glewInit();

    initialize();

    glutDisplayFunc(draw);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyHandle);

    glutMainLoop();
    return 0;
}

顶点着色器

#version 150
uniform mat4 ModelxView;
uniform mat4 Projection;
in vec4 Position;


void main()
{
    gl_Position = Projection*ModelxView*Position;
}

片段着色器

     #version 150
out vec4 fColor;

void main()
{
    fColor = vec4(1.0, 1.0, 0.0, 1.0);
}

【问题讨论】:

  • 你试过用固定函数管道渲染它吗?
  • @AndreasBrinck:这将如何帮助他的着色器鳕鱼工作?
  • 你能先确认一下你的渲染循环中 glGetError == 0 吗?
  • 我添加了打印出 glGetError() 的代码,它返回 0,但只返回一次(除非有一个关键事件,在这种情况下调用 glutPostRedisplay(),但屏幕仍然是黑色的)所以由于某种原因,draw() 没有被召回
  • 添加了一个丢失的空闲回调,因此已修复,但仍然是纯屏幕

标签: c++ opengl vertex-shader perspectivecamera


【解决方案1】:

对此不确定,因为我不确定 Angel:: 幕后发生了什么,但从片段着色器输出 fColor 是否正确?我认为在 glsl 150 中它需要特殊变量 gl_FragColor,除非 Angel 做了一些特定的事情来缓解这种情况。

我看了一会儿,但我没有看到任何其他会导致问题的东西。不幸的是,我认为如果你真的陷入困境,你可能不得不开始编写一个更简单的示例(没有函数,只是通过渲染三角形进行初始化的直接概述)。

还要确保每个 draw() 循环至少调用一次 glGetError 以确保它没有丢失任何内容。 Angel 是否会在链接/编译失败时抛出异常?

【讨论】:

  • Angel 命名空间中的所有内容都是加载顶点和片段着色器程序的函数,我从教科书的资源参考中下载了该程序,并将 InitShader.cpp 改编为 .hpp,因为原始标题不会t 编译没有我不想使用的其他源文件。 我真的希望你对 gl_FragColor 的看法是正确的。这很有意义,现在就尝试一下。 我运行我的程序打印 glGetError() 每一帧,它每次都返回 0。
  • 很遗憾没有工作。我查看了 glsl 1.5 规范,gl_fragColor 已被弃用,网络上的其他 1.5 示例以相同的方式使用用户定义的变量输出颜色。
  • 好的,我做了一些我早就应该做的事情。我刚刚添加了 glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices));到draw方法和所有对象转换都按“预期”工作,当然它看起来不像它应该的那样。我要么必须弄清楚 GL_TRIANGLE_STRIP 有什么问题,要么暴力破解它并重写 GL_TRIANGLES 的顶点代码(叹气)。
【解决方案2】:

嗯,这个怎么样:

viewMatrix = lookAt(cameraDirection, cameraPosition, cameraUp);

这和gluLookAt 是同一个lookAt 吗?在该函数中,原型是 (position, lookAtPoint, cameraUp),这与您所拥有的相反。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多