如何在不关心相机的 glew 中创建叠加菜单?

How to create an overlaying menu in glew that doesn't care about camera?

本文关键字:创建 叠加 菜单 glew 不关心 相机      更新时间:2023-10-16

我有一个发光项目。我正在尝试创造一些东西,基本上是一个"生命条",覆盖所有东西。我的问题是我不知道如何绘制它,因为我的相机(定义为"GLFrame cameraFrame;")正在移动和旋转以适应玩家的移动。而且,即使它没有注意到相机,我担心它会与关卡上的其他几何体相交。我怎样才能在glow中做到这一点?

我考虑过用

来避免相交
glPolygonOffset(-1.0f, -1.0f);

但是它不起作用

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

GLBatch bar1;
GLfloat vSquare[6][3] 
bar1.Begin(GL_TRIANGLES, 6);
bar1.CopyVertexData3f(vSquare);
bar1.End();

它画得很完美,除了像所有其他关卡几何图形一样,它遵循相机的视角。我该怎么做呢?

如果你愿意,这里是我的代码中与glow和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: %sn", glewGetErrorString(err));
                return 1;
                }
        SetupRC();
        glutMainLoop();
        return 0;
        }

PT2 所以我就像你说的那样努力让一切正常运转。不幸的是,正如@Ethan所说,我花了一段时间来"清除"变换矩阵。所以我做了一些关于如何做到这一点的研究……我可以做loadiidentity ();在我的一个矩阵上。然而,当运行代码时,它似乎什么都不做。无论如何,这是我的主要渲染代码(称为每个场景),你可以试着写在我评论的区域,它绘制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和投影之间的区别是什么矩阵?
  • loadiidentity()做什么?
  • PushMatrix()做什么?
  • PopMatrix()做什么?
  • 什么是一个Frustum (GLFrustum viewFrustum)做?

在回答你的问题之前,我想强调几件事:

    你的问题和辉光完全没有关系。glow只是一个处理OpenGL函数/扩展加载的库。
  • 你使用OpenGL的方式已经过时了,不再推荐。有一些很好的现代教程,你应该遵循,使用opengl3及以上版本。此外,你正在混合它与着色器(?),这听起来不正确。
现在,回答你的问题。你想要做的是统称为GUI -图形用户界面。它通常是2D的,位于所有内容之上。为了绘制这样的项,您需要:
  • 首先绘制3D场景。一切。
  • 清除变换矩阵
  • 绘制你想要的项目(在本例中是生命条)。