Я делаю программу, использующую openGL с прозрачными объектами в ней, так что, очевидно, я должен нарисовать их последними. К сожалению, я не знал об этом требовании, когда начинал этот проект, и теперь было бы очень больно менять его порядок, наконец, рисуя их.
Я рисую объекты, вызывая свои функции рисования после перевода и поворота сцены. Перед фактическим рисунком может быть несколько переводов и поворотов (например, сначала я рисую землю, затем переводю, затем вызываю чертеж дома, который многократно переводит и вращает, затем вызывает рисунок стен и т. Д.).
Таким образом, моя идея состояла в том, чтобы сохранить текущие матрицы вида модели в списке вместо рисования прозрачных объектов, как обычно, а затем, когда я закончу с непрозрачным материалом, я перебираю свой список и загружаю каждую матрицу и рисую каждый объект (окно, если быть точным).
Я делаю это для сохранения матрицы:
GLdouble * modelMatrix = (GLdouble *)malloc(16 * sizeof(GLdouble));
glGetDoublev(GL_MODELVIEW, modelMatrix);
addWindow(modelMatrix); // save it for later painting
И это часть "прозрачного управления вещами":
/***************************************************************************
*** TRANSPARENT STUFF MANAGEMENT ******************************************
**************************************************************************/
typedef struct wndLst {
GLdouble * modelMatrix;
struct wndLst * next;
} windowList;
windowList * windows = NULL;
windowList * pWindow;
void addWindow(GLdouble * windowModelMatrix) {
pWindow = (windowList *)malloc(sizeof(windowList));
pWindow->modelMatrix = windowModelMatrix;
pWindow->next = windows;
windows = pWindow;
}
void clearWindows() {
while(windows != NULL) {
pWindow = windows->next;
free(windows->modelMatrix);
free(windows);
windows = pWindow;
}
}
void paintWindows() {
glPushMatrix(); // I've tried putting this and the pop inside the loop, but it didn't help either
pWindow = windows;
while(pWindow != NULL) {
glLoadMatrixd(pWindow->modelMatrix);
Size s;
s.height = 69;
s.width = 49;
s.length = 0.1;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
glColor4f(COLOR_GLASS, windowAlpha);
drawCuboid(s);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
pWindow = pWindow->next;
}
glPopMatrix();
}
/* INTERFACE
* paint all the components, that are not yet painted,
* then clean up.
*/
void flushComponents() {
paintWindows();
clearWindows();
}
/**************************************************************************/
Я вызываю flushComponents (); в самом конце моих рисунков.
Проблема в том, что окна не встают на свои места, вместо этого в моей сцене случайно появляются и исчезают синие объекты странной формы.
Я что-то не так делаю? Или такие матричные манипуляции не могут быть использованы даже так Тогда какой другой метод я мог бы использовать для этого?
Вот полный код, если он вам нужен: farm.zip Сохранение матрицы в компонентах.c строка 1548, управление в строке 142. Оно может не работать в Windows без незначительного взлома с помощью include, что, вероятно, должно быть сделано в global.h.
Редактировать: Я могу использовать только код C и библиотеку переизбытка для написания этой программы.
Редактировать 2: Проблема в том, что glGetDoublev по какой-то причине ничего не возвращает, оставляет массив modelMatrix нетронутым. Хотя я до сих пор не знаю, чем это вызвано, я мог бы обойти эту проблему, используя идею Берни.