Непонятное поведение шейдера OpenGl в macOSX - PullRequest
1 голос
/ 09 апреля 2020

Я создаю массив вершин, я создаю шейдеры, компилирую и связываю их, но когда я использую Drawarrays, ничего не происходит.

На экране не отображается геометрия, в то время как я должен видеть красный треугольник.
Нет ошибок в командной строке, никаких проблем нет, но треугольник не появится.

#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

using namespace std;

static GLuint compileShader(const string& source,GLuint type);
static int createShader(const string& vertexShader, const string& fragment);

int main(void){

    // I INITIALISE GLFW TO HAVE THE LATEST VERSION OF THE SHADER VERSION
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);


    //I CREATE THE WINDOW
    GLFWwindow* window = glfwCreateWindow(800,600,"Dio suino",NULL,NULL);
    glfwMakeContextCurrent(window);
    glewExperimental= GL_TRUE;

    //I INITIALISE GLEW
    if(glewInit()!=GLEW_OK){
        fprintf(stderr,"ERROR");
        exit(1);
    }

    //I SPECIFY THE VERTEX DATA
    float bufferData[6]={
        0.5,-0.5,
        -0.5,-0.5,
        0.0,0.5
    };

    GLuint bufferId;

    // I CREATE THE BUFFER, BIND IT AND SPECIFY ALL THE INFO NEEDED
    glGenBuffers(1,&bufferId);

    glBindBuffer(GL_ARRAY_BUFFER,bufferId);
    glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);
    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
    glEnableVertexAttribArray(0);


    // I CREATE THE VERTEX AND FRAGMENT SHADERS
    string vs,fs;

    vs = 
    "#version 330 core \n"
    "in vec4 position;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = position;\n"
    "}\n";

    fs =
    "#version 330 core \n"
    "out vec4 color;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    color = vec4(1.0,0.0,0.0,1.0);\n"
    "}\n";

    //I USE THE PROGRAM
    int shaderProgram = createShader(vs,fs);
    glUseProgram(shaderProgram);
    glBindBuffer(GL_ARRAY_BUFFER,0);


    // WINDOW LOOP: CLEAR COLOR, SWAP BUFFER ECC
    while(!glfwWindowShouldClose(window)){


        glClearColor(0,60,80,0);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES,0,3); 

        glfwSwapBuffers(window);

        glfwPollEvents();


    }

    cout<< glGetString(GL_VERSION)<<endl;

    return 0;
}

//CREATES THE SHADER PROGRAM WITH ALL THE SHADERS LINKED
static int createShader(const string& vertexShader, const string& fragment)
{
    GLuint program = glCreateProgram();
    GLuint vs = compileShader(vertexShader,GL_VERTEX_SHADER);
    GLuint fs = compileShader(fragment,GL_FRAGMENT_SHADER);

    glAttachShader(program,vs);
    glAttachShader(program,fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

//COMPILES THE SHADER
static GLuint compileShader(const string& source,GLuint type)
{
    GLuint id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id,1,&src,nullptr);
    glCompileShader(id);

    int debug;
    glGetShaderiv(id,GL_COMPILE_STATUS,&debug);

    if(debug == GL_FALSE){

        int length;
        glGetShaderiv(id,GL_INFO_LOG_LENGTH,&length);
        char message[length];
        glGetShaderInfoLog(id,length,&length,message);
        fprintf(stderr,"Something went wrong in the shader of type %i: %s",type,message);
        glDeleteShader(id);
    }

    return id;
}

Теперь это библиотеки, которые я включил.
Makefile:

CC = clang++
MAIN = main.cpp
LIB = -lglew -lglfw 
FWORK = -framework OpenGl
NAME = -o dio -std=c++11

all:
    ${CC} ${MAIN} ${LIB} ${FWORK} ${NAME}

Что я делаю не так?

1 Ответ

1 голос
/ 09 апреля 2020

Когда вы используете профиль ядра Контекст OpenGL , вам необходимо создать именованный Объект массива вершин , потому что VAO (0) по умолчанию недопустимо. В VAO указывается спецификация массивов вершин.

Вы можете переключиться в контекст профиля совместимости, чтобы решить проблему, если она поддерживается вашим оборудованием и драйвером (вероятно, не в macOSX):

https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object:

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

Но я рекомендую создать объект массива вершин перед спецификацией обобщенных данных массива вершин c. VAO должен быть связан, когда вызываются glVertexAttribPointer и glEnableVertexAttribArray, потому что эта инструкция изменяет вектор состояния VAO:

GLuint bufferId;
glGenBuffers(1,&bufferId);
glBindBuffer(GL_ARRAY_BUFFER,bufferId);
glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);

GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
glEnableVertexAttribArray(0);
...