2016-06-23 2 views
2

Я пытаюсь использовать OpenGL для рендеринга в существующую область визуализации окна, созданного с помощью Windows API. Я получаю HDC и создаю контекст opengl, используя wglCreateContext и wglMakeCurrent. Затем создаем текстуру, и я ее связываю. хотя я могу очистить буфер до любого цвета, который я выбираю, я не могу его отобразить. В следующем примере кода должно быть ясно, что моя проблема.Рисунок OpenGL для существующего HDC с использованием Texture2D

void draw(HDC dhdc){ 


static unsigned char render_on_device_image_once, odd; 
static GLuint texture_id; 
size_t sz; 

odd = (odd + 1) % 2; 
if(!render_on_device_image_once){ 
     // DO ONCE 
    render_on_device_image_once = 1; 


    GLubyte pixels[] = 
    { 
     0, 0, 0, 255, 255, 255, 
     255, 255, 255, 0, 0, 0, 
    }; 
    glGenTextures(1, &texture_id); 
    glBindTexture(GL_TEXTURE_2D, texture_id); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); 


} 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
if(odd) 
    glClearColor(0.0, 0.0, 0.5, 1.0); 
else 
    glClearColor(0.5, 0.0, 0.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glTranslatef(0, 0, -5); 

glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, texture_id); 

glBegin(GL_QUADS); 
glTexCoord2f(0.0, 0.0); 
glVertex3f(0.0, 0.0, 0.0); 
glTexCoord2f(1.0, 0.0); 
glVertex3f(1.0, 0.0, 0.0); 
glTexCoord2f(1.0, 1.0); 
glVertex3f(1.0, 1.0, 0.0); 
glTexCoord2f(0.0, 1.0); 
glVertex3f(0.0, 1.0, 0.0); 
glEnd(); 

glDisable(GL_TEXTURE_2D); 

SwapBuffers(dhdc);} 

Приведенный выше код, который я взял (и слегка изменен) от this answer делает область окна для изменения между красным и синим, но не оказывает квадрицепсы. У кого-нибудь была аналогичная проблема или я могу определить свою ошибку?

Спасибо.

EDIT:

Чтобы добавить больше информации, я устанавливаю формат пикселя HDC к этому:

static PIXELFORMATDESCRIPTOR window_pixel_format_desc = 
{ 
    sizeof(PIXELFORMATDESCRIPTOR), 
    1, 
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags 
    PFD_TYPE_RGBA,   //The kind of framebuffer. RGBA or palette. 
    8,      //Colordepth of the framebuffer. 
    0, 0, 0, 0, 0, 0, 
    0, 
    0, 
    0, 
    0, 0, 0, 0, 
    32,      //Number of bits for the depthbuffer 
    0,      //Number of bits for the stencilbuffer 
    0,      //Number of Aux buffers in the framebuffer. 
    PFD_MAIN_PLANE, 
    0, 
    0, 0, 0 
}; 
+0

Какая версия OpenGL - ваш контекст? Непосредственный режим рендеринга устарел в современном OpenGL и не существует в основном профиле и OpenGL ES. – Dan

+0

Кроме того, глубина цвета HDC должна быть 24 для RGB (или 32 для RGBA), как показано [здесь] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd318284 (v = vs.85) .aspx). – Dan

+0

Привет, Дэн, спасибо за ваши комментарии. Версия OpenGL, которую я использую, - 4.5.0, а изменение глубины цвета до 24 бит не исправило мою проблему, хотя я вижу, как это правильное значение для этого поля. – vfiskewl

ответ

2

Две вещи.

Во-первых, вы никогда не звоните glViewport. Вам нужно сделать это, чтобы настроить размер поверхности рендеринга.Видовой экран должен быть настроен на использование всего окна, поэтому вам нужно будет использовать функции Win32 для запроса размера клиента в окне.

Во-вторых, это:

glTranslatef(0, 0, -5); 

Почему что? Это нецелесообразно, и это приводит к тому, что компонент Z ваших треугольников станет -5. Который находится вне диапазона [-1, 1] Z, который вы получаете с состоянием по умолчанию OpenGL.

+0

Спасибо, Николь, ваш ответ приблизил меня к решению, но не совсем там. Поэтому я добавил glViewport с размером окна, и я получил окно полностью черным, поэтому я попытался использовать половину ширины и высоты, а то, что у меня было, было черным квадратом на четверть размера окна черным, а остальная часть область сохраняла цветные изображения (синий и красный). Снова ничего не отображается на экране. Я подозреваю, что не выбираю правильный буфер для рисования и очистки. Любые идеи о том, как это исправить? Большое спасибо! – vfiskewl

+0

Игнорируйте мой предыдущий комментарий, я пропустил тот факт, что рисовал черный квадрат размером области рендеринга! – vfiskewl

1

Прежде всего, если ваша цель состоит в том, чтобы «получить пикселей с OpenGL в DC «тогда делать это через Window DC очень проблематично. Для одного вы полностью зависите от управления пикселями окна. Такие вещи, как владение пикселями, видимость окна, обрезка окна и т. Д., Могут негативно повлиять на результат рендеринга.

Еще одна важная вещь, которую следует учитывать, заключается в том, что вы можете установить только пиксельный формат окна только ! Для закадровый рендеринга у вас есть 2 варианта (или 3, в зависимости от того, если хост-система поддерживает EGL и окружающая среда EGL дает вам закадровый рендеринга):

  • создать скрытый/невидимый помощник окно, чтобы служить DC для OpenGL и рендер в объект framebuffer. Это, безусловно, preferrable решения в текущих данных (2016 год)

  • создать пиксельный буфер, чтобы служить DC для OpenGL и визуализации к этому DC

  • создать закадровый EGL контекст. Offscreen EGL может поддерживать прямые внеэкранные поверхности, поэтому не требуется объект framebuffer. Или внеэкранный контекст без основной поверхности, поэтому требуются объекты фреймбуфера.

Из представленных выше опций только метод пиксельный буфер дает вам relaible путь к BitBlt между контроллерами домена. Тем не менее, PBuffers можно так же легко создавать, как невидимое окно, а объекты фреймбуфера дают вам намного больше контроля. Кроме того, в отличие от PBuffers, содержимое объекта объекта фреймбуфера (текстуры или рендеринга) запрещено внезапно «исчезать» (в любой момент могут быть недействительными PBuffers).

Самый надежный способ получить изображения из OpenGL в «нечто», которое может быть использовано при операциях постоянного тока является создание DIBSECTION (CreateDIBSection) и читать данные изображения в него с glReadPixels.

+0

Привет, datenwolf, я уже пробовал вариант номер 2 и не смог. Можете ли вы немного уточнить вариант 1? Что вы подразумеваете под невидимым окном и как его можно привязать к DC? спасибо – vfiskewl

+0

@vfiskewl: По сути, вы выполняете все шаги, необходимые для создания окна и настраиваете его для OpenGL, но не вызывайте 'ShowWindow' на нем, а также не используете стиль' WS_SHOW'. Важный бит использует объект framebuffer как объект рендеринга. Там есть много учебников по объекту framebuffer. – datenwolf

+0

@ datenwolf: Я думаю, что его проблема немного более фундаментальная, чем эта. Он говорит, что рендеринг в окно не работает. Я очень сомневаюсь, что переключение на FBO и блик к фреймбуферу по умолчанию внезапно заставит его работать. Кроме того, есть * ничего вообще * неправильно с визуализацией непосредственно к фреймбуферу по умолчанию для окна. –

Смежные вопросы