2010-02-10 4 views
2

В настоящее время я обрабатываю оболочку для некоторых функций OpenGL. Цель состоит в том, чтобы обернуть контекст, используемый игрой Neverwinter Nights, для применения эффектов пост-обработки шейдеров. Изучив OpenGL (это моя первая попытка использовать его), и много играя с DLL и перенаправлением, у меня есть несколько работающая система.Проблемы с альфа-текстурой в обертке OpenGL

Однако, когда полнофункциональный полноэкранный четырехъядерный процессор активен, все текстурирование и прозрачность, нарисованные игрой, теряются. Это не должно быть возможным, потому что все мои функции вступают в силу после того, как игра полностью завершила собственный рендеринг.

Код не использует renderbuffers или фреймбуферы (оба отказались от компиляции в моей системе каким-либо образом, с или с GLEW или GLee, несмотря на то, что они поддерживаются и могут использоваться другими программами). В конце концов, я соединял этот код для обработки копирования текстуры из буфера и рендеринга полноэкранных четверной:

функция
extern "C" SEND BOOL WINAPI hook_wglSwapLayerBuffers(HDC h, UINT v) 
{ 
if (frameCount > 250) 
{ 
    frameCount++; 
    if (frameCount == 750) frameCount = 0; 

    if (nwshader->thisframe == NULL) 
    { 
     createTextures(); 
    } 

    glBindTexture(GL_TEXTURE_2D, nwshader->thisframe); 
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, nwshader->width, nwshader->height, 0); 

    glClearColor(0.0f, 0.5f, 0.0f, 0.5f); 
    glClear(GL_COLOR_BUFFER_BIT); 


    glEnable(GL_TEXTURE_2D);  
    glDisable(GL_DEPTH_TEST); 
    glBlendFunc(GL_ONE, GL_ZERO); 
    glEnable(GL_BLEND); 

    glMatrixMode(GL_PROJECTION); 
    glPushMatrix(); 
    glLoadIdentity(); 
    glOrtho(0, nwshader->width , nwshader->height , 0, -1, 1); 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glLoadIdentity(); 


    glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 
    glBegin(GL_POLYGON); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex2d(0, 0); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex2d(0, nwshader->height); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex2d(nwshader->width, nwshader->height); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex2d(nwshader->width, 0); 
    glEnd(); 


    glMatrixMode(GL_PROJECTION); 
    glPopMatrix(); 
    glMatrixMode(GL_MODELVIEW); 
    glPopMatrix(); 

    glEnable(GL_DEPTH_TEST); 
    glDisable(GL_TEXTURE_2D); 

    glBindTexture(GL_TEXTURE_2D, 0);  
} else { 
    frameCount++; 
} 

if (h == grabbedDevice) 
{ 
    Log->logline("Swapping buffer on cached device."); 

} 
return wglSwapLayerBuffers(h,v); 
} 

Этого кода почти функционирует совершенно и не имею никакого заметного замедления роста. Однако, когда он активен (я добавил условие frameCount для его включения и выключения каждые ~ 5 секунд), все альфа и текстурирование полностью игнорируются игровым рендерером. Я не отказываюсь от каких-либо смешивания или текстурирования перед этой функцией (единственными вызовами OpenGL являются создание текстуры nwshader-> thisframe). мне удалось поймать несколько скриншотов того, что происходит:

Сломанный A: http://i4.photobucket.com/albums/y145/peachykeen000/outside_brokenA.png
Разбитое B: http://i4.photobucket.com/albums/y145/peachykeen000/outside_brokenB.png
(примечание, в B, дым в спине не нарушена, это правильно прозрачный Так. является HUD)
Разбитое Интерьер:. http://i4.photobucket.com/albums/y145/peachykeen000/transparency_broken.png
Правильный интерьер (для сравнения): http://i4.photobucket.com/albums/y145/peachykeen000/transparency_proper.png

чертеж четырехугольника также ломает меню, превращая все это в черную поверхность с одной белой маль Икс. Я подозреваю, что это проблема с любой глубиной или как игра рисует определенные объекты, или состояние, которое не сбрасывается должным образом. Я использовал GLintercept для вывода полного журнала всех вызовов в фрейме и не видел ничего плохого (вызов wglSwapLayerBuffers всегда последний).

Будучи совершенно новым для работы с OpenGL, я действительно понятия не имею, что происходит (или как его исправить), и ничего, что я пробовал, не помогло. Что мне не хватает?

+0

Попробуйте сузить строку вашего кода, которая вызывает проблему (удалив их по одному). Я уверен, что это будет 'createTextures()', 'glBindTexture' или' glCopyTexImage2D' (но это только предположение). –

+0

createTextures - это вызов одной из моих функций, которая создает необходимую текстуру, если она не существует (используется для текстурирования квадроцикла при его рендеринге). glBindTexture используется, насколько я понимаю, для того, чтобы сказать квадрум использовать эту текстуру для ее текстурирования.Я что, ошибаюсь? И glCopyTexImage2D должен скопировать backbuffer в мою текстуру (я знаю, что это работает, так как я получаю оверлей с неправильно изображенным фреймом). – ssube

ответ

2

Я не совсем понимаю, как ваш код должен интегрироваться с кодом Neverwinter Nights. Однако ...

Похоже, что вы, скорее всего, измените некоторые настройки, которые не ожидал изменить существующий код.

На основании описания проблемы, я бы попробовать удалить следующую строку:

glDisable(GL_TEXTURE_2D); 

Эта строка отключает текстуры, которые, безусловно, звучит как проблема, вы видите.

+0

Мой код не интегрируется, например. Я написал DLL, используя
#pragma комментарий (линкер, «/export:wglSwapLayerBuffes=nwshader.hook_wglSwapLayerBuffers»)
отправить некоторые вызовы функций из стандартной библиотеки DLL OpenGL (переименованного hookgl32.DLL) в моей собственной DLL (nwshader.dll). Neverwinter Nights вызывает OpenGL DLL, которая была заменена моей DLL перенаправления. Затем функции, которые мне нужно обернуть, обрабатываются в моем коде. Я попытаюсь удалить этот звонок. Один из образцов, на которые я смотрел, который сделал аналогичную вещь, использовал glEnable и Disable на GL_TEXTURE_2D по обе стороны от рендеринга своего квадроцикла. – ssube

+0

Не знаю, как я это пропустил (слишком долго смотрел на тот же код, я думаю), но это сработало отлично, спасибо! : D – ssube

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

  • Нет связанных вопросов^_^