Как использовать более одного состояния openGL в приложении? - PullRequest
0 голосов
/ 07 августа 2020

Я знаю, что openGL - это конечный автомат, но я не знаю, как сохраняется состояние.

У меня есть проект, в котором мне нужно отображать вещи за пределами экрана в памяти на C ++ dll / Dynami c -library и передать окончательное изображение приложению c#, которое также использует состояние openGL для выполнения любых мыслимых действий (визуализируйте все, что приложение хочет, любым способом). Это, очевидно, делает невозможным разделение того, какое состояние openGL используется для рисования вне экрана (в dll / Dynami c -library), и какое состояние openGL используется для рисования в приложении.

Как Мог бы я go создать / использовать отдельное состояние openGL для моего внеэкранного рендерера в c ++? Будет ли c ++ std :: thread использовать / создавать отдельное состояние openGL при использовании в них openGL? одно состояние openGL в одном приложении (и чередование этих состояний) без использования нескольких потоков?

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Если вы хотите передать окончательное изображение рендеринга в другое приложение, вы можете передать его с помощью PBO и указателя на данные пикселей с помощью glMapBuffer.

Это код, в котором я передаю данные пикселей в другое приложение.

glReadBuffer(GL_COLOR_ATTACHMENT0);
writeIndex = (writeIndex + 1) % 2;
readIndex = (readIndex + 1) % 2;
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[writeIndex]);
                    // copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
                    // now read other PBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[readIndex]);
unsigned char* downsampleData = (unsigned char *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
float Time1 = bm.GetTime();
blueOut.RenderOut(downsampleData, FieldNumber); // Pass it to the other application
                
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

вам необходимо написать драйверы для c# приложения, которое будет передавать указатель данных в приложение в реальном времени.

0 голосов
/ 12 августа 2020

Это очень похоже на переключение контекста для ЦП для выполнения расписания потоков.

Допустим, у вас есть два конвейера M и N в одном потоке, и M запускается первым, когда вы хотите переключиться на N, вы можете сохранить M сначала контекст, а затем запустить конвейер N, и в какой-то момент, когда N работает, вы можете сохранить контекст N и восстановить контекст M. Итак, вопрос в том, как явно сохранить контекст OpenGL.

На самом деле OpenGL предоставляет множество методов запроса / получения (или несколько методов, но много параметров), например glGetIntegerv, glGetVertexAttribiv и glGetVertexAttribPointerv ( glGet ), вы можете запросить и сохранить результат где-нибудь и восстановить их в какой-то момент.

Вот простой пример класса-оболочки:

class GLStateSaver {
    GLuint framebuffer;
    GLint activeTexture;
    GLint boundedTextures[MAX_USED_TEXTURES];
    // ... add more fields if you need, like programID, memory object id etc.
public:
    void Save() {
        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
        glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
        // ...
    }
    void Restore() {
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glActiveTexture(activeTexture);
        // ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...