【发布时间】: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;
}
如果不能,你能解释一下这些东西在做什么吗?
- ModelViewMatrix和Projection有什么区别 矩阵?
- LoadIdentity() 有什么作用?
- PushMatrix() 有什么作用?
- PopMatrix() 有什么作用?
- 什么是平截头体 (GLFrustum viewFrustum)?
【问题讨论】: