【问题标题】:How to create an overlaying menu in glew that doesn't care about camera?如何在不关心相机的glew中创建覆盖菜单?
【发布时间】:2025-11-27 00:45:01
【问题描述】:

所以我有一个 glew 项目。我正在尝试创造一些基本上是覆盖一切的“生命条”。我的问题是我不知道如何绘制它,因为我的相机(定义为“GLFrame cameraFrame;”)正在移动和旋转以适应玩家的移动。此外,即使它没有注意相机,我也担心它会与关卡上的其他几何图形相交。我怎么能在 glew 中做到这一点?

我考虑过使用

尝试让它不相交
glPolygonOffset(-1.0f, -1.0f);

但它不起作用

目前我将生命条定义为两个三角形。

GLBatch bar1;
GLfloat vSquare[6][3] 

bar1.Begin(GL_TRIANGLES, 6);
bar1.CopyVertexData3f(vSquare);
bar1.End();

它的绘制非常完美,除了像所有其他级别的几何体一样,它遵循相机的视角。我该怎么做?

如果您愿意,这里是我的代码中与 glew 和 opengl 相关的部分

您可能可以向下滚动到底部,这就是多汁的东西所在

//Platform demo code.  Copyright Caleb Kierum.  Do not reproduce without permission
#include <GLTools.h>
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLBatch.h>
#include <GLGeometryTransform.h>
#include <iostream>
#include <climits>
#include <string>
#include <sstream>
#include <time.h>
#include <stdlib.h>

//A functiion that will allow variables to become strings for debugging
#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

#include <math.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
#define PI 3.14159265

//Shader manager thing
GLShaderManager         shaderManager;
GLMatrixStack           modelViewMatrix;
GLMatrixStack           projectionMatrix;
//Camera translation things
GLFrame                         cameraFrame;
//Object translation things
GLFrame             objectFrame;
GLFrustum                       viewFrustum;


GLBatch                         triangleBatch;
GLBatch                         QuadStrip;
GLBatch                         playerBatch;

//2d point structure
struct fPoint {
        float x;
        float y;
};

//Collision status
struct CStatus {
        bool front;
        bool right;
        bool left;
        bool back;
        bool top;
        bool bottom;
};

//Stores a 3d coord
struct Coord {
        float x;
        float y;
        float z;
};

//Stores collision info for all non rotated boxes
struct Box {
        Coord c1;
        Coord c2;
        Coord c3;
        Coord c4;
        Coord c5;
        Coord c6;
        Coord c7;
        Coord c8;
};

//Stores things an entity might need
struct Entity {
        float x;
        float y;
        float z;
        float d;
        float fd;
        CStatus collision;
        Box box;
        Box lbox;
};

//Stores 3d rotation Euler style
struct Rot {
        float x;
        float y;
        float z;
};

//Stores 3 bools
struct Bool3 {
        bool c1;
        bool c2;
        bool c3;
};

//Holds the data for a line
struct Line{
        POINT p2;
        POINT p1;
};

//Stores the color
struct Color {
        GLfloat r;
        GLfloat g;
        GLfloat b;
        GLfloat a;
};

//Allows a box to have structure and data
struct BoxD {
        Box obj;
        int c;
};

//Stores a boud of something
struct Square {
        float left;
        float right;
        float top;
        float down;
};

//Stores the current first platform slot that is empty
int current = 0;
//Maximum ammount of platforms. If more are created it will crash
const int max = 60;


GLGeometryTransform     transformPipeline;
M3DMatrix44f            shadowMatrix;

//Stores all the level geometry and the color for each
GLBatch Level[max];
GLfloat Color[max];
BoxD Collisions[max];

//store things related to the player
Entity player;

GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
GLfloat vOrange[] = { 1.0f, 0.67f, 0.0f, 0.5f };//
GLfloat vYellow[] = { 1.0f, 1.0f, 0.0f, 1.0f };
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
GLfloat vBlue[] = { 0.0f, 0.0f, 1.0f, 1.0f };
GLfloat vIndigo[] = { 0.294f, 0.0f, 0.509f, 1.0f }; //
GLfloat vViolet[] = { 0.560f, 0.0f, 1.0f, 1.0f };//
GLfloat vCol[] = { 0.0f, 0.0f, 0.0f, 0.0f };

//Coordinates of a pyramid debugging
GLfloat vPyramid[12][3] = { -2.0f, 0.0f, -2.0f,
                               2.0f, 0.0f, -2.0f,
                                0.0f, 4.0f, 0.0f,

                                2.0f, 0.0f, -2.0f,
                                2.0f, 0.0f, 2.0f,
                                0.0f, 4.0f, 0.0f,

                                2.0f, 0.0f, 2.0f,
                                -2.0f, 0.0f, 2.0f,
                                0.0f, 4.0f, 0.0f,

                                -2.0f, 0.0f, 2.0f,
                                -2.0f, 0.0f, -2.0f,
                                 0.0f, 4.0f, 0.0f};

float grow = 1.2;
GLfloat Playa[24][3] = { -grow, 4.0f, -grow,
        grow, 4.0f, -grow,
        grow, 4.0f, grow,
        -grow, 4.0f, grow,

        -grow, 0.0f, -grow,
        grow, 0.0f, -grow,
        grow, 0.0f, grow,
        -grow, 0.0f, grow,

        grow, 4.0f, -grow,
        grow, 4.0f, grow,
        grow, 0.0f, grow,
        grow, 0.0f, -grow,

        -grow, 4.0f, -grow,
        -grow, 4.0f, grow,
        -grow, 0.0f, grow,
        -grow, 0.0f, -grow,

        -grow, 4.0f, grow,
        grow, 4.0f, grow,
        grow, 0.0f, grow,
        -grow, 0.0f, grow,

        -grow, 4.0f, -grow,
        grow, 4.0f, -grow,
        grow, 0.0f, -grow,
        -grow, 0.0f, -grow};

//Draws the model with an edge around it
void DrawWireFramedBatch(GLBatch* pBatch, int c)
{
        switch(c)
        {
                case 1:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vRed);
                        break;
                case 2:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vOrange);
                        break;
                case 3:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vYellow);
                        break;
                case 4:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen);
                        break;
                case 5:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlue);
                        break;
                case 6:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vIndigo);
                        break;
                case 7:
                        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vViolet);
                        break;
        }
   // Draw the batch solid green

    pBatch->Draw();

    // Draw black outline
    glPolygonOffset(-1.0f, -1.0f);      // Shift depth values
    glEnable(GL_POLYGON_OFFSET_LINE);

    // Draw lines antialiased
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Draw black wireframe version of geometry
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glLineWidth(2.5f);
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    pBatch->Draw();

    // Put everything back the way we found it
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
        glEnable(GL_MULTISAMPLE);

    }
//This happens on the start initializes open gl tasks
void SetupRC()
        {
        HVel.x = 0.0f;
        HVel.y = 0.0f;
        HVel.z = 0.0f;
        //Resets some necessary values
        player.d = 0.0f;
        player.collision.back = false;
        player.collision.bottom = false;
        player.collision.front = false;
        player.collision.left = false;
        player.collision.right = false;
        player.collision.top = false;
        onfloor = true;

        //cameraFrame.RotateLocal(m3dDegToRad(-90.0f), 0.0f, 1.0f, 0.0f);


        //Setup for level 1
        Level1();

    // Black background
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );

        //Starts the stock shaders
        shaderManager.InitializeStockShaders();

        //Enables depth filtering
        glEnable(GL_DEPTH_TEST);

        //Sets up the transform pipeline
        transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);

        //cameraFrame.MoveForward(-15.0f);

    // For Triangles, we'll make a Pyramid
        triangleBatch.Begin(GL_TRIANGLES, 12);
    triangleBatch.CopyVertexData3f(vPyramid);
    triangleBatch.End();

        playerBatch.Begin(GL_QUADS, 24);
        playerBatch.CopyVertexData3f(Playa);
        playerBatch.End();

        PlayerUpd(player.x, player.y, player.z);

    //That way there is some analytical things
        //Update();
    }
//Holds the field of view
float fov = 60.0f;
//Renders the scene every frame
void RenderScene(void)
        {    
                //Does all of the logic
                Update();
                // Clear the window with current clearing color
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

                modelViewMatrix.PushMatrix();
                M3DMatrix44f mCamera;
                cameraFrame.GetCameraMatrix(mCamera);
                modelViewMatrix.MultMatrix(mCamera);

        M3DMatrix44f mObjectFrame;
        objectFrame.GetMatrix(mObjectFrame);
        modelViewMatrix.MultMatrix(mObjectFrame);

                //Enumerates so that all platforms can be drawn
                for (int i = 0; i < max; i++)
                {
                        DrawWireFramedBatch(&Level[i], Collisions[i].c);
                }

                //Draws the batches
                //DrawWireFramedBatch(&triangleBatch);
                DrawWireFramedBatch(&QuadStrip, 1);

                modelViewMatrix.PopMatrix();
                glutPostRedisplay();

                //DrawWireFramedBatch(&playerBatch);


                // Flush drawing commands
                glutSwapBuffers();
                viewFrustum.SetPerspective(fov, 1.0f, 1.0f, 500.0);
                //Starts the lbox game basically keeping the last frames values
                player.lbox = player.box;
    } //Called to render the scene
//React to the changing screeen size, expecially changing the model view matrix
void ChangeSize(int w, int h)
        {
        //std::cout << SSTR( "GetBigger " << w << " , " << h << std::endl);
        width = w;
        height = h;
        glViewport(0, 0, w, h);
        viewFrustum.SetPerspective(fov, float(w) / float(h), 1.0f, 500.0f);
        projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
        modelViewMatrix.LoadIdentity();
        }
//Starts the glut process
int main(int argc, char* argv[])
        {
        gltSetWorkingDirectory(argv[0]);

        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);
        glutInitWindowSize(1000, 800);
        glutInitWindowPosition(700, 0);

        //Mouse stuff
        SetCursorPos((700 + 8 + ((1000/2) * 1)), (0 + -30 +  ((800/2) * 1)));

        glutCreateWindow("The Playground");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);

        GLenum err = glewInit();
        if (GLEW_OK != err) {
                fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
                return 1;
                }

        SetupRC();

        glutMainLoop();
        return 0;
        }

PT2 所以我试图让事情像你说的那样正常工作。不幸的是,正如@Ethan 所说,我花了很长时间“清除”转换矩阵。所以我做了一些关于如何做到这一点的研究......事实证明我可以做 LoadIdentity();在我的一个矩阵上。然而,在运行代码时,它似乎什么也不做。无论如何,这是我的主要渲染代码(称为每个场景),您可以尝试在我评论说它绘制 hud 以便一切正常的区域中编写代码吗?这是代码

//Shader manager thing
GLShaderManager     shaderManager;
GLMatrixStack       modelViewMatrix;
GLMatrixStack       projectionMatrix;
//Camera translation things
GLFrame             cameraFrame;
//Object translation things
GLFrame             objectFrame;
GLFrustum           viewFrustum;
M3DMatrix44f        shadowMatrix;
GLGeometryTransform transformPipeline;

void RenderScene(void) 
    {    
        //Does all of the logic
        Update();
        // Clear the window with current clearing color
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        //I dont know whats going on in these couple lines
        modelViewMatrix.PushMatrix();
        M3DMatrix44f mCamera;
                    //cameraFrame does all the rotating and moving
        cameraFrame.GetCameraMatrix(mCamera);
        modelViewMatrix.MultMatrix(mCamera);

        M3DMatrix44f mObjectFrame;
        objectFrame.GetMatrix(mObjectFrame);
        modelViewMatrix.MultMatrix(mObjectFrame);



        //Draws all of the platforms stored inside of the array and passes what color they are
        for (int i = 0; i < max; i++)
        {
            DrawWireFramedBatch(&Level[i], Collisions[i].c);
        }
        //Draws all of the dots.
        for (int p = 0; p < maxdots; p++)
        {
            if(Dots[p].active)
            {
                if (Dots[p].type == 1)
                {
                    //std::cout << "HI" << std::endl;
                    DrawWireFramedBatch(&Dotz[p], 8);
                }
            }
        }
        //I have no clue... fov stands for a variable that says fov
        viewFrustum.SetPerspective(fov, 1.0f, 0.0f, 200.0);

        //This is the batch I want to draw without any perspective....
        DrawWireFramedBatch(&bar1, 1); //CODE ON THIS LINE NEEDS NOT TO CARE ABOUT TRANSLATION SO THAT IT IS LIKE A HUD

        modelViewMatrix.PopMatrix();
        //Tells it to donother frame
        glutPostRedisplay();

        // Flush drawing commands
        glutSwapBuffers();

        //Starts the lbox game basically keeping the last frames values
        player.lbox = player.box;

    }

如果不能,你能解释一下这些东西在做什么吗?

    1. ModelViewMatrix和Projection有什么区别 矩阵?
    1. Lo​​adIdentity() 有什么作用?
    1. PushMatrix() 有什么作用?
    1. PopMatrix() 有什么作用?
    1. 什么是平截头体 (GLFrustum viewFrustum)?

【问题讨论】:

    标签: c++ windows opengl glew


    【解决方案1】:

    在回答您的问题之前,我想强调几点:

    • 您的问题与 Glew 完全无关。 Glew 只是一个处理 OpenGL 函数/扩展加载的库。
    • 您使用 OpenGL 的方式已经过时,不再推荐。您应该遵循一些使用 OpenGL 3 及更高版本的优秀现代教程。此外,您正在将它与着色器 (?) 混合,这听起来不正确。

    现在,回答您的问题。您想要做的统称为 GUI - 图形用户界面。它通常是位于一切之上的 2D。为了绘制这些项目,您需要:

    • 首先绘制 3D 场景。一切。
    • 清除变换矩阵
    • 画出你想要的物品(这里是血条)。

    【讨论】:

    • 好的 所以我花了一些时间研究如何清除转换矩阵。我一直在做那个最困难的时候......它似乎没有做任何事情。我在原始帖子中只放了简短的渲染代码,您能告诉我如何正确清除矩阵吗? @Ethan
    • 如果您了解堆栈数据结构,那么函数 glPushMatrix 和 glPopMatrix 的名称几乎是不言自明的。如果要清除,只需弹出所有已推送的内容即可。
    • 我不熟悉 pop 或 push 矩阵 @Ethan 的含义
    • swiftless.com/tutorials/opengl/pop_and_push_matrices.html。这些是基本的东西,谷歌是你的朋友。
    • 或者,使用 loadIdentity 将当前矩阵设置为恒等(无转换)。
    最近更新 更多