我正在尝试使用深度测试和alpha混合。我想要做的是在一个更大更透明的小环内放一个不透明的小环。我应该启用深度测试以防止不良几何。所以,如果我启用深度测试,我就无法显示内环。是否有针对此问题的解决方法。谢谢你的帮助。我的代码如下所示:
#include <GLTools.h> // OpenGL toolkit
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
#include <GLShaderManager.h>
#include <math3d.h>
#include <math.h>
#define FREEGLUT_STATIC
#include <GL\glut.h>
GLFrame viewFrame;
GLFrustum viewFrustum;
GLBatch triangleBatch;
GLTriangleBatch torusBatch;
GLTriangleBatch torusBatch2;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLGeometryTransform transformPipeline;
GLShaderManager shaderManager;
// Flags for effects
bool iCull = true;
bool iDepth = true;
GLfloat blockSize = 0.3f;
GLfloat vVerts[] ={-blockSize, -blockSize, 0.0f,
blockSize, -blockSize, 0.0f,
blockSize, blockSize, 0.0f};
void ProcessMenu(int value)
{
switch(value)
{
case 1:
iDepth = !iDepth;
break;
case 2:
iCull = !iCull;
break;
case 3:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
case 4:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
break;
case 5:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
break;
case 6:
glPolygonMode(GL_FRONT, GL_LINE);
break;
}
glutPostRedisplay();
}
void bounceFunction(void)
{
static GLfloat xDir = 1.0f;
static GLfloat yDir = 1.0f;
GLfloat stepSize = 0.0005f;
GLfloat blockX = vVerts[0]; // Upper left X
GLfloat blockY = vVerts[7]; // Upper left Y
blockY += stepSize * yDir;
blockX += stepSize * xDir;
if(blockX < -1.0f) { blockX = -1.0f; xDir *= -1.0f; }
if(blockX > (1.0f - blockSize * 2)) { blockX = 1.0f - blockSize * 2; xDir *= -1.0f; }
if(blockY < -1.0f + blockSize * 2) { blockY = -1.0f + blockSize * 2; yDir *= -1.0f; }
if(blockY > 1.0f) { blockY = 1.0f; yDir *= -1.0f; }
vVerts[0] = blockX;
vVerts[1] = blockY - blockSize*2;
vVerts[3] = blockX + blockSize*2;
vVerts[4] = blockY - blockSize*2;
vVerts[6] = blockX + blockSize*2;
vVerts[7] = blockY;
}
void movementKeys(int key, int x, int y)
{
/*GLfloat stepSize = 0.025f;
GLfloat blockX = vVerts[0];
GLfloat blockY = vVerts[7];
if(key == GLUT_KEY_UP)
blockY += stepSize;
if(key == GLUT_KEY_DOWN)
blockY -= stepSize;
if(key == GLUT_KEY_LEFT)
blockX -= stepSize;
if(key == GLUT_KEY_RIGHT)
blockX += stepSize;
//CollisonDetection
if(blockX < -1.0f) blockX = -1.0f;
if(blockX > (1.0f - blockSize * 2)) blockX = 1.0f - blockSize * 2;;
if(blockY < -1.0f + blockSize * 2) blockY = -1.0f + blockSize * 2;
if(blockY > 1.0f) blockY = 1.0f;
//CollisonDetection end
//Recalculation
vVerts[0] = blockX;
vVerts[1] = blockY - blockSize*2;
vVerts[3] = blockX + blockSize*2;
vVerts[4] = blockY - blockSize*2;
vVerts[6] = blockX + blockSize*2;
vVerts[7] = blockY;
triangleBatch.CopyVertexData3f(vVerts);
glutPostRedisplay();*/
if(key == GLUT_KEY_UP)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_DOWN)
viewFrame.RotateWorld(m3dDegToRad(5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_LEFT)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 0.0f, 1.0f, 0.0f);
if(key == GLUT_KEY_RIGHT)
viewFrame.RotateWorld(m3dDegToRad(5.0), 0.0f, 1.0f, 0.0f);
// Refresh the Window
glutPostRedisplay();
}
void changeSize(int w, int h)
{
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Turn culling on if flag is set
if(iCull)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
// Enable depth testing if flag is set
if(iDepth)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
modelViewMatrix.PushMatrix(viewFrame);
glPolygonOffset(-1.0f, -1.0f);
GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 0.5f};
GLfloat vBlue[] = {0.0f, 0.0f, 1.0f, 0.5f};
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vRed);
torusBatch.Draw();
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vBlue);
torusBatch2.Draw();
glDisable(GL_BLEND);
modelViewMatrix.PopMatrix();
glutSwapBuffers();
}
void SetupRC()
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);//Backgroung color
shaderManager.InitializeStockShaders();
viewFrame.MoveForward(7.0f);
gltMakeTorus(torusBatch, 1.0f, 0.25f, 52, 26);
gltMakeTorus(torusBatch2, 0.95f, 0.1f, 52, 26);
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(1280,720);
glutCreateWindow("Test");
GLenum err = glewInit();
if(err != GLEW_OK)
{
//Error handling
fprintf(stderr, "GLEW error: %s\n", glewGetErrorString(err));
return -1;
}
glutReshapeFunc(changeSize);
glutDisplayFunc(renderScene);
glutSpecialFunc(movementKeys);
// Create the Menu
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Toggle depth test",1);
glutAddMenuEntry("Toggle cull backface",2);
glutAddMenuEntry("Set Fill Mode", 3);
glutAddMenuEntry("Set Line Mode", 4);
glutAddMenuEntry("Set Point Mode", 5);
glutAddMenuEntry("Set Line Mode Back Face Culling", 6);
glutAttachMenu(GLUT_RIGHT_BUTTON);
SetupRC();
glutMainLoop();
return 0;
}
答案 0 :(得分:0)
通常,您可以使用不透明对象启用深度测试,然后在启用OVER混合的情况下对透明对象进行从前到后的渲染。然而,自相交的物体存在需要进一步工作的问题。不幸的是,透明度并不是一个小小的翻转,它的工作原理是&#34; OpenGL中的功能。
以下是近期技术的概述&amp;想法。 https://developer.nvidia.com/content/transparency-or-translucency-rendering