为什么我的三角形在 Raspberry Pi 上的 OpenGL ES 3 中是白色的

问题描述

我有一个非常简单的 OpenGL ES 程序示例,我试图在 Raspberry Pi 4 上的 RaspiOS 桌面(又名 Raspbian)上运行该程序。

我的目标非常简单 - 在屏幕中央绘制一个红色三角形。但是,三角形显示为白色而不是红色。

我已经搜索并尝试了所有方法,但找不到任何帮助。在这一点上,我非常沮丧,因为这应该是介绍 OpenGL ES 世界的第一个教程,但我已经卡住了,无法继续进行更复杂的示例。

无论如何,这是完整的例子

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include <stdbool.h>

static struct glData {
    GLuint program;
    GLuint vbo;
} glData;

const char vert_shader_source[] = "#version 300 es                         \n"
                                  "precision mediump float;                \n"
                                  "layout (location = 0) in vec3 Position; \n"
                                  "void main()                             \n"
                                  "{                                       \n"
                                  "   gl_Position = vec4(Position,1.0);   \n"
                                  "}                                       \n";

const char frag_shader_source[] = "#version 300 es                             \n"
                                  "precision mediump float;                    \n"
                                  "out vec4 fragColor;                         \n"
                                  "void main()                                 \n"
                                  "{                                           \n"
                                  "  fragColor = vec4(1.0f,0.0f,1.0f); \n"
                                  "}                                           \n";

#define POSITION 0

bool initWindow(int* argc,char** argv)
{
    glutInit(argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE);
    glutCreateWindow("Triangle");
    GLenum glew_status = glewInit();
    if (glew_status != GLEW_OK) {
        fprintf(stderr,"Error: %s\n",glewGetErrorString(glew_status));
        return false;
    }
    return true;
}

static GLuint buildShader(const char* shader_source,GLenum type)
{
    GLuint shader;
    GLint status;

    shader = glCreateShader(type);
    if (shader == 0) {
        return 0;
    }

    glShaderSource(shader,1,&shader_source,NULL);
    glCompileShader(shader);
    glGetShaderiv(shader,GL_COMPILE_STATUS,&status);
    if (status != GL_TRUE) {
        int length;
        char* log;

        fprintf(stderr,"failed to compile shader\n");
        glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&length);
        if (length > 1) {
            log = calloc(length,sizeof(char));
            glGetShaderInfoLog(shader,length,&length,log);
            fprintf(stderr,"%s\n",log);
            free(log);
        }
        return false;
    }

    return true;
}

static GLuint createAndLinkProgram(GLuint v_shader,GLuint f_shader)
{
    GLuint program;
    GLint linked;

    program = glCreateProgram();
    if (program == 0) {
        fprintf(stderr,"failed to create program\n");
        return 0;
    }

    glAttachShader(program,v_shader);
    glAttachShader(program,f_shader);

    glLinkProgram(program);

    glGetProgramiv(program,GL_LINK_STATUS,&linked);

    if (linked != GL_TRUE) {
        int length;
        char* log;

        fprintf(stderr,"failed to link program\n");
        glGetProgramiv(program,sizeof(char));
            glGetProgramInfoLog(program,log);
            free(log);
        }
        glDeleteProgram(program);
        return 0;
    }

    return program;
}

static bool initProgram()
{
    GLuint v_shader,f_shader;

    v_shader = buildShader(vert_shader_source,GL_VERTEX_SHADER);
    if (v_shader == 0) {
        fprintf(stderr,"failed to build vertex shader\n");
        return false;
    }

    f_shader = buildShader(frag_shader_source,GL_FRAGMENT_SHADER);
    if (f_shader == 0) {
        fprintf(stderr,"failed to build fragment shader\n");
        glDeleteShader(v_shader);
        return false;
    }

    glReleaseShaderCompiler(); // should release resources allocated for the compiler

    glData.program = createAndLinkProgram(v_shader,f_shader);
    if (glData.program == 0) {
        fprintf(stderr,"failed to create and link program\n");
        glDeleteShader(v_shader);
        glDeleteShader(f_shader);
        return false;
    }

    glUseProgram(glData.program);

    // this won't actually delete the shaders until the program is closed but it's a good practice
    glDeleteShader(v_shader);
    glDeleteShader(f_shader);

    return true;
}

bool setupOpenGL()
{
    if (!initProgram()) {
        fprintf(stderr,"failed to initialize program\n");
        return false;
    }

    GLfloat vVertices[] = {
        -0.5f,-0.5f,0.5f,};

    glClearColor(0,1);
    glGenBuffers(1,&glData.vbo);
    glBindBuffer(GL_ARRAY_BUFFER,glData.vbo);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vVertices),vVertices,GL_STATIC_DRAW);

    return true;
}

void reshape(int width,int height)
{
    glViewport(0,width,height);
}

void drawTriangle()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glEnableVertexAttribArray(POSITION);
    glBindBuffer(GL_ARRAY_BUFFER,glData.vbo);
    glVertexAttribPointer(POSITION,3,GL_FLOAT,GL_FALSE,0);
    glDrawArrays(GL_TRIANGLES,3);
    glDisableVertexAttribArray(POSITION);
    glutSwapBuffers();
}

int main(int argc,char** argv)
{
    printf("initialize window\n");
    if (!initWindow(&argc,argv)) {
        fprintf(stderr,"failed to initialize window\n");
        return EXIT_FAILURE;
    }

    printf("setup opengl\n");
    if (!setupOpenGL()) {
        fprintf(stderr,"failed to setup opengl\n");
        return EXIT_FAILURE;
    }

    glutDisplayFunc(drawTriangle);
    glutReshapeFunc(reshape);
    glutMainLoop();

    glDeleteProgram(glData.program);
    return EXIT_SUCCESS;
}

在运行之前,您需要:

  1. 运行sudo raspi-config
  2. 转至高级选项 > GL 驱动程序
  3. 启用 GL(假 KMS)
  4. 重启

然后你可以像这样编译和运行它:

gcc triangle.c -Wall -lm -lglut -lGLEW -lGL -o triangle
./triangle

起初我以为可能是驱动程序中的一些错误或其他什么。但后来我找到了 this example 并尝试运行它,它绘制了一些具有多种颜色的图形,这很好。

我会感谢任何帮助。我已经尝试调试这个好几天了。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)