【问题标题】:Rendering triangle using Vertex Array Object shows nothing (OpenGL)使用顶点数组对象渲染三角形什么都不显示(OpenGL)
【发布时间】:2012-12-27 00:50:23
【问题描述】:

我使用 OpenGL 3.2、GLFW 和 GLEW。我尝试在 OS X (10.8.2) 上使用 VAO 和简单着色器渲染简单三角形,但没有显示,只有白屏。着色器编译正常,GLEW 初始化正常,glGetString(GL_VERSION) 显示 3.2,试图在每一行之后加上 glGetError,它没有报告任何错误。我不知道我做错了什么。代码如下:

#include "include/GL/glew.h"
#include "include/GL/glfw.h"
#include <cstdlib>
#include <iostream>

GLuint program;

char *textFileRead(char *fn) {


    FILE *fp;
    char *content = NULL;

    int count=0;

    if (fn != NULL) {
        fp = fopen(fn,"rt");

        if (fp != NULL) {

      fseek(fp, 0, SEEK_END);
      count = ftell(fp);
      rewind(fp);

            if (count > 0) {
                content = (char *)malloc(sizeof(char) * (count+1));
                count = fread(content,sizeof(char),count,fp);
                content[count] = '\0';
            }
            fclose(fp);
        }
    }
    return content;
}


void checkCompilationStatus(GLuint s) {
    GLint status = 0;

    glGetShaderiv(s, GL_COMPILE_STATUS, &status);
    if (status == 0) {
        int infologLength = 0;
        int charsWritten  = 0;

        glGetShaderiv(s, GL_INFO_LOG_LENGTH, &infologLength);

        if (infologLength > 0)
        {
            GLchar* infoLog = (GLchar *)malloc(infologLength);
            if (infoLog == NULL)
            {
                printf( "ERROR: Could not allocate InfoLog buffer");
                exit(1);
            }
            glGetShaderInfoLog(s, infologLength, &charsWritten, infoLog);
            printf( "Shader InfoLog:\n%s", infoLog );
            free(infoLog);
        }
    }

}


void setShaders() {
    GLuint v, f;
    char *vs = NULL,*fs = NULL;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);

    vs = textFileRead("minimal.vert");
    fs = textFileRead("minimal.frag");

    const char * vv = vs;
    const char * ff = fs;

    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);

    free(vs);free(fs);

    glCompileShader(v);
    checkCompilationStatus(v);
    glCompileShader(f);
    checkCompilationStatus(f);

    program = glCreateProgram();
    glAttachShader(program,v);
    glAttachShader(program,f);

    GLuint error;
    glLinkProgram(program);
    glUseProgram(program);
}


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

    glfwInit();

    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
    glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwOpenWindow(800, 600, 8, 8, 8, 8, 24, 8, GLFW_WINDOW);
    glViewport(0, 0, 800, 600);
    glfwSetWindowTitle("Triangle");

    glewExperimental = GL_TRUE;
    GLenum result = glewInit();
    if (result != GLEW_OK) {
        std::cout << "Error: " << glewGetErrorString(result) << std::endl;
    }

    std::cout << "VENDOR: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "RENDERER: " << glGetString(GL_RENDERER) << std::endl;
    std::cout << "VERSION: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLSL: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    setShaders();

    GLfloat vertices[] = {
        1.0f, 1.0f, 0.f,
        -1.f, -1.f, 0.f,
        1.f, -1.f, 0.f
    };


    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    GLuint vertexbuffer;

    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLuint pos = glGetAttribLocation(program, "position");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glClearColor(1.0, 1.0, 1.0, 1.0);

    while (glfwGetWindowParam(GLFW_OPENED)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers();        
        glfwSleep(0.001);

   }

}

这里是着色器,顶点着色器:

#version 150

in vec3 position;

void main()
{   
      gl_Position = vec4(position, 0);
}

片段着色器:

#version 150

out vec4 out_color;

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

【问题讨论】:

  • 能否尝试禁用深度测试,如果不起作用,请尝试禁用面部剔除?
  • 我添加了 glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glew 初始化后,还是什么都没有
  • 只是想一想,如果你说 gl_Position = vec4(position, 1) 会发生什么? (使用 1 作为 w 分量,而不是 0)
  • 哇!这行得通,非常感谢,你能解释一下为什么 w 参数很重要吗?

标签: c++ opengl glsl glew glfw


【解决方案1】:

顶点着色器中的 w 参数应设置为 1,而不是 0。

gl_Position = vec4(position, 1)

有关更多信息,请参阅this page“光栅化概述”下标题为“标准化坐标”的部分

... 每个顶点位置的 X、Y 和 Z 除以 W 得到归一化的设备坐标...

所以你的坐标被 0 除。除以 0 的数字是未定义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-19
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2017-02-04
    • 1970-01-01
    相关资源
    最近更新 更多