学到了OpenGL中的用户裁剪和前剪切,记录下gl_ClipDistance和gl_CullDiatance的用法。
gl_ClipDiatance:输出的裁剪距离将和图元进行线性插值,插值距离小于0,则图元部分将剪切掉。
gl_CullDiatance:如果图元的所有顶点对于平面都返回了负数的裁减距离值,那么图元需要被裁减。
用OpenGL编程指南中的代码修改测试下:
#include <iostream>
#include "vgl.h"
#include "LoadShaders.h"
#include "vmath.h"
using namespace std;
struct Vertex
{
GLubyte color[4];
GLfloat position[3];
};
Vertex Verts[9] = {
{ { 255,0, 0, 255 }, { 0.6f, 0.9f, 0.0f } },
{ { 0, 255,0, 255 }, { -0.9f, -0.9f, 0.0f } },
{ { 0, 0, 255,255 }, { 0.9f, -0.9f, 0.0f } },
{ { 255,255,255,255 }, { 0.0f, 0.8f, -0.2f } },
{ { 255,255,255,255 }, { -0.4f, 0.0f, -0.2f } },
{ { 255,255,255,255 }, { 0.4f, 0.0f, -0.2f } },
{ { 255,255,255,255 }, { 0.3f, 0.0f, -0.2f } },
{ { 255,255,255,255 }, { -0.4f, -0.8f, -0.2f } },
{ { 255,255,255,255 }, { 0.4f, -0.8f, -0.2f } }
};
GLuint Program = 0;
GLuint vert;
GLuint vbo;
void Init()
{
ShaderInfo si[] = { { GL_VERTEX_SHADER, "Chpater05.vert" },{ GL_FRAGMENT_SHADER, "Chapter05.frag" },{ GL_NONE, NULL } };
Program = LoadShaders(si);
glGenVertexArrays(1, &vert);
glBindVertexArray(vert);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verts), Verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(sizeof(Verts->color)));
glEnableVertexAttribArray(1);
glClearColor(0.2f, 0.1f, 0.3f, 1.0f);
glUseProgram(Program);
glUniform4f(glGetUniformLocation(Program, "Plane"), 0.0, 0.0, 0.0, 0.0);
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vert);
glEnable(GL_CLIP_DISTANCE0);
glDrawArrays(GL_TRIANGLES, 0, 9);
glutSwapBuffers();
glutPostRedisplay();
Sleep(30);
}
int main(int argc, char*argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE |GLUT_STENCIL);
glutInitWindowSize(400, 400);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("Test OpenGL Chapter 04");
if (glewInit())
{
cout << "Unable to Initialize GLEW." << endl;
return 1;
}
Init();
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
顶点着色器:
#version 450 core
layout(location = 0) in vec4 vColor;
layout(location = 1) in vec4 vPos;
uniform vec4 Plane;
out vec4 color;
void main()
{
gl_Position = vPos;
color = vColor;
// gl_ClipDistance[0] = Plane[3] - Plane[0]*vPos.x - Plane[1]*vPos.y - Plane[2]*vPos.z;
// gl_CullDistance[0] = Plane[3] - Plane[0]*vPos.x - Plane[1]*vPos.y - Plane[2]*vPos.z;
}
片元着色器:
#version 450 core
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
正常情况下:
打开gl_CullDistance赋值代码注释,裁剪面设置成:
glUniform4f(glGetUniformLocation(Program, "Plane"), 0.0, 0.0, 1.0, -0.1);
最大的变色三角形消失了,这是因为这个三角形三个顶点的Z值都是0,计算后三个顶点的gl_CullDistance值都小于0
打开gl_ClipDistance的注释,注释掉gl_CullDistance,裁剪面设置成:
glUniform4f(glGetUniformLocation(Program, "Plane"), 0.0, 1.0, 1.0, 0.1);