Как сэмплировать пиксель из текстуры кадрового буфера в OpenGL?

Я создаю приложение OpenGL для выбора цвета для изображений с ImGUI. Мне удалось загрузить изображение, загрузив изображение в glTexImage2D и используя ImGUI::Image(). Теперь я хотел бы реализовать метод, который может определять цвет пикселя в случае щелчка левой кнопкой мыши.

Вот как я загружаю текстуру, а затем назначаю ее фреймбуферу:

bool LoadTextureFromFile(const char *filename, GLuint *out_texture, int *out_width, int *out_height,ImVec2 mousePosition ) {

    // Reading the image into a GL_TEXTURE_2D
    int image_width = 0;
    int image_height = 0;
    unsigned char *image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
    if (image_data == NULL)
        return false;

    GLuint image_texture;
    glGenTextures(1, &image_texture);
    glBindTexture(GL_TEXTURE_2D, image_texture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    stbi_image_free(image_data);
    glBindTexture(GL_TEXTURE_2D, 0);

    *out_texture = image_texture;
    *out_width = image_width;
    *out_height = image_height;

    // Assigning texture to Frame Buffer
    unsigned int fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image_texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image_texture, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE){
        std::cout<< "Frame buffer is done."<< std::endl;
    }
    return true;
}

К сожалению, приведенный выше код приводит к совершенно пустому экрану. Наверное, я что-то упустил при настройке фреймбуфера.

Вот метод, в котором я хотел бы сэмплировать текстуру буфера кадра, используя координаты мыши:

    void readPixelFromImage(ImVec2 mousePosition) {
        unsigned char pixels[4];
        glReadBuffer(GL_COLOR_ATTACHMENT0);
        glReadPixels(GLint(mousePosition.x), GLint(mousePosition.y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    
        std::cout << "r: " << static_cast<int>(pixels[0]) << '\n';
        std::cout << "g: " << static_cast<int>(pixels[1]) << '\n';
        std::cout << "b: " << static_cast<int>(pixels[2]) << '\n';
        std::cout << "a: " << static_cast<int>(pixels[3]) << '\n' << std::endl;
    }

Любая помощь приветствуется!

остерегайтесь, что координаты мыши относятся к координатам окна, которые отличаются от координат OpenGL ... вам, скорее всего, следует инвертировать позицию y, если ys - это y размер вашего представления, затем используйте ys-mousePosition.y ... Если у вас есть панели и прочее в окне, которое вам нужно чтобы учесть это тоже... Вы также можете использовать выбор текста непосредственно из текстуры... Также важно выбрать glReadPixels во время рендеринга изображения и из того же потока,... поскольку вы, скорее всего, выбираете в каком-то событии возможно, ваше изображение пусто в то время.

Spektre 21.12.2020 10:17

см. OpenGL 3D-raypicking с высокополигональными сетками есть пример glReadPixel прямого фреймбуфера (без вложений PBO/FBO) для выбора текстуры напрямую, которую вы можете использовать glGetTexImage

Spektre 21.12.2020 10:22
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
2
942
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

В вашем коде действительно чего-то не хватает:

Вы устанавливаете новый буфер кадра, который содержит только один буфер текстуры. Это нормально, поэтому glCheckFramebufferStatus равен GL_FRAMEBUFFER_COMPLETE. Но к вашему фреймбуферу не подключен буфер рендеринга. Если вы хотите, чтобы ваше изображение отображалось на экране, вы должны использовать фреймбуфер по умолчанию. Этот фреймбуфер создается из вашего контекста GL. Однако в документации говорится: буферы кадров по умолчанию не могут изменять свои вложения буфера, [...] https://www.khronos.org/opengl/wiki/Framebuffer . Таким образом, присоединение текстуры или буфера рендеринга к FB по умолчанию, безусловно, невозможно. Однако вы могли бы сгенерировать новый FB, как вы это сделали, отрендерить его и, наконец, отрендерить результат (или преобразовать буферы) в ваш FB по умолчанию. Возможно, хорошей отправной точкой для этой техники является https://learnopengl.com/Advanced-Lighting/Deferred-Shading

Более того, если вы собираетесь просто считывать отрендеренные значения с вашего графического процессора, более эффективно использовать буфер рендеринга вместо текстуры. Вы даже можете иметь несколько буферов рендеринга, прикрепленных к вашему фреймбуферу (как в случае отложенного затенения). Пример: вы можете использовать второй буфер рендеринга для рендеринга идентификатора объекта/экземпляра (таким образом, буфер рендеринга будет одноканальным целым числом), а ваш первый буфер рендеринга будет использоваться для обычного рисования. Читая второй буфер рендеринга с помощью glReadPixels, вы можете напрямую прочитать, какой экземпляр был нарисован, например. положение мыши. Таким образом, вы можете очень эффективно включить выбор мышью.

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