Нарушение прав доступа внутри glfwPollEvents()?

Когда я запускаю свою программу:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

struct ShaderProgramSource
{
    std::string VertexSource;
    std::string FragmentSource;
};

static ShaderProgramSource parseShader(const std::string& filepath)
{
    std::ifstream stream(filepath);

    enum class ShaderType
    {
        NONE = -1, VERTEX = 0, FRAGMENT = 1
    };

    std::string line;
    std::stringstream ss[2];
    ShaderType type = ShaderType::NONE;
    while (getline(stream, line))
    {
        if (line.find("#shader") != std::string::npos)
        {
            if (line.find("vertex") != std::string::npos)
                type = ShaderType::VERTEX;
            else if (line.find("fragment") != std::string::npos)
                type = ShaderType::FRAGMENT;
        }
        else
        {
            ss[(int)type] << line << '\n';
        }
    }

    return { ss[0].str(), ss[1].str() };
}

typedef unsigned int uint;

static uint compileShader(const std::string& source, uint type)
{
    uint id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        //char* message = (char*)alloca(length * sizeof(char));
        char* message = new char[length];
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile the " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment")
            << " shader !" << std::endl;
        std::cout << message << std::endl;
        delete[](message);
        glDeleteShader(id);
        return EXIT_FAILURE;
    }

    return id;
}

static uint CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{
    uint program = glCreateProgram();
    uint vs = compileShader(vertexShader, GL_VERTEX_SHADER);
    uint fs = compileShader(fragmentShader, GL_FRAGMENT_SHADER);

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

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello Triangle", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    auto state = glewInit();
    if (state != GLEW_OK)
    {
        std::cerr << "Error initializing GLEW" << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << glGetString(GL_VERSION) << std::endl;

    float positions[6] = {
        -0.5f, -0.5f,
         0.0f,  0.5f,
         0.5f, -0.5f
    };

    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    ShaderProgramSource source = parseShader("res/shaders/basic.shader");

    std::cout << "VERTEX" << std::endl;
    std::cout << source.VertexSource << std::endl;
    std::cout << "FRAGMENT" << std::endl;
    std::cout << source.FragmentSource << std::endl;

    //uint shader = CreateShader(source.VertexSource, source.VertexSource);
    //glUseProgram(shader);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    //glDeleteProgram(shader);

    glfwTerminate();
    return 0;
}

...все работает хорошо, но через несколько секунд приложение вылетает. он возвращает код выхода -1073741819, и, преобразовав его в шестнадцатеричный формат, я обнаружил, что это код ошибки C0000005: переполнение буфера. Затем я решил отладить это, и отладчик сказал следующее:

"Exception thrown at 0x00007FFD28144921 (igxelpicd64.dll) in App.exe: 0xC0000005: Access violation writing location 0x0000025170620000."
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, вы не используете свой шейдер, как вы закомментировали glCompileShader() и glUseProgram(shader), а в OpenGL нет шейдера по умолчанию. Попробуйте раскомментировать эти две строки и оставить glCompileShader там, где он есть (перед основным циклом), но переместите glUseShader(shader) в цикл рендеринга непосредственно перед вызовом 'glDrawArrays()`.

Также я не вижу, чтобы вы создавали VertexArrayObject, который необходимо создать и связать с помощью glBindVertexArray(GLint: VAO), вместо этого вы используете обычный буфер в качестве VertexArrayBuffer, поэтому ваш код для создания VertexArrayBuffer должен выглядеть так

unsigned int VAO, VBO;

//this is missing in your code
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), &positions GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindVertexArrays(0)

Теперь, когда у вас есть массивы вершин, вы можете визуализировать треугольник, используя следующее

//while loop

glUseProgram(shaderProgram)
glBindVertexArrays(VAO)
glDrawArray(GL_TRIANGLES, 0, 3);

//----------

Это должно решить вашу проблему при условии, что ваши оттенки правильно скомпилированы и вы передаете все в VertexArrayBuffer.

Итак, я реализую то, что вы сказали, и, похоже, это работает. Я просто проверяю кое-что и думаю, что обнаружил причину: если вы используете glfwPollEvent, вам нужно использовать шейдер, иначе он выйдет из строя и выдаст нарушение доступа. Короче говоря, нам нужно использовать шейдер, когда мы что-то рисуем, иначе произойдет сбой.

Lemoine Maxence 17.07.2024 15:14

Другие вопросы по теме