c - OpenGL 保存对象供以后绘制

标签 c opengl transparency glut

我正在使用带有透明对象的 openGL 制作一个程序,所以显然我必须最后绘制那些。不幸的是,我在开始这个项目时并没有意识到这个要求,现在重新排序它最后画那些真的很痛苦。

在平移和旋转场景后,我通过调用我的绘图函数来绘制对象。在实际绘制之前可以有多次平移和旋转(例如,首先我绘制地面,然后平移,然后调用房屋的绘图,重复平移和旋转,然后调用墙壁的绘图等)。

所以我的想法是将当前的模型 View 矩阵保存在一个列表中,而不是像往常一样绘制透明对象,然后当我完成不透明的东西时,我遍历我的列表并加载每个矩阵并绘制每个对象(准确地说是一个窗口)。

我这样做是为了保存一个矩阵:

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();在我画的最后。

问题是, window 没有就位,相反,我的场景中出现了奇怪形状的蓝色物体,随机出现和消失。

我做错了什么吗?或者这样的矩阵操作甚至不能像这样使用?那么我还可以使用什么其他方法来执行此操作?

如果您需要,这里有完整的代码:farm.zip矩阵保存位于 components.c 的第 1548 行,管理位于第 142 行。如果不对包含进行一些小改动,它可能无法在 Windows 上运行,这可能应该在 global.h 中完成。

编辑:我只能用C代码和glut库来写这个程序。

编辑 2: 问题是 glGetDoublev 出于某种原因没有返回任何东西,它使 modelMatrix 数组完好无损。虽然我仍然不知道是什么原因导致的,但我可以使用伯尼的想法来解决这个问题。

最佳答案

OpenGL 不是数学库。你不应该用它来做矩阵计算。事实上,那部分已从 OpenGL-3 中完全删除。相反,您应该依赖专门的矩阵数学库。这使您可以轻松地计算每个对象的矩阵,而无需跳过 OpenGL 的 glGet... API(这种滥用从来都不是肉)。要获得良好的替代品,请查看 GLM:http://glm.g-truc.net/

关于c - OpenGL 保存对象供以后绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8372506/

相关文章:

winforms - Windows 窗体中的透明背景?

r - 调整 stat_smooth 线的透明度 (alpha),而不仅仅是置信区间的透明度

c - 将已删除的文件重新附加到目录

c++ - 字符到整数数组

c - 如何实现glMultMatrixf

c++ - 在 OpenGL 中删除部分绘图

将 char 数组的值复制到二维数组

c - 从specman执行perl

java/opengl : loading textures on 64bit VM

cocoa - HUD NSPanel 不太透明