不多说了 ,直接上我的源码和测试结果:
1.不使用裁剪平面
// VAO.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <cstdlib>
#include <cassert>
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glew32.lib")
using namespace std;
GLuint vertex_array[2] = {0,0};
void init()
{
GLubyte indices[][4] ={
{0,1,2,3},
{4,7,6,5},
{0,4,5,1},
{3,2,6,7},
{0,3,7,4},
{1,5,6,2}
};
GLfloat vertexs[][3] = {
{-1, -1, -1},
{1, -1, -1},
{1, 1, -1},
{-1, 1, -1},
{-1, -1, 1},
{1, -1, 1},
{1, 1, 1},
{-1, 1, 1},
};
GLfloat color[][3] ={
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{0.5, 0, 0},
{0, 0.5, 0},
{0, 0, 0.5},
{0.5, 0.5, 0.5},
{0.8, 0.8, 0.8}
};
glClearColor(0, 0, 0, 0);
glShadeModel(GL_SMOOTH);
//VAO[0]
glGenVertexArrays(2, vertex_array);
glBindVertexArray(vertex_array[0]);
//顶点数据
GLuint vbo_vertex = 0;
glGenBuffers(1, &vbo_vertex);
assert(vbo_vertex != 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*8, vertexs, GL_STATIC_DRAW);
//Bind VAO and VBO 索引0一定是顶点
//将顶点数据输入到VAO,用来建立VAO和VBO的数据传递,上传数据完成之后可以删除
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); //leave out this sentence
//顶点颜色
GLuint vbo_color = 0;
glGenBuffers(1, &vbo_color);
assert(vbo_color);
glBindBuffer(GL_ARRAY_BUFFER, vbo_color);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*24, color, GL_STATIC_DRAW);
glVertexAttribPointer(4,3,GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
//glColorPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_COLOR_ARRAY); //??????
//assert(glGetError() == GLEW_OK);
//使用VBO来实现顶点缓冲
//GLuint vbo = 0;
//glGenBuffers(1, &vbo);
//assert(vbo != 0);
//glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*8, vertexs, GL_STATIC_DRAW);
//glVertexPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_VERTEX_ARRAY);
//将顶点索引写入显存
GLuint vbo_index = 0;
glGenBuffers(1, &vbo_index);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_index);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*24, indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
assert(glGetError() == GLEW_OK);
//VAO[1]
GLfloat vertex_triangle[][3] =
{
{0, 1, 0},
{-1, -1, 0},
{1, -1, 0}
};
GLfloat color_triangle [][3] =
{
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
GLubyte index_triangle[] = {0, 1, 2};
glBindVertexArray(vertex_array[1]);
GLuint vboID[3] = {0};
glGenBuffers(3,vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, vertex_triangle, GL_STATIC_DRAW);
//glVertexPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboID[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, color_triangle, GL_STATIC_DRAW);
//glColorPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_COLOR_ARRAY);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*3, index_triangle, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
assert(GLEW_OK == glGetError());
GLint max_modelview_stack_count = 0;
GLint max_projection_stack_count = 0;
GLint max_clip_count = 0;
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &max_modelview_stack_count);
glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, &max_projection_stack_count);
glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_count);
cout<<"max_modelview_stack_count="<<max_modelview_stack_count<<endl;
cout<<"max_projection_stack_count"<<max_projection_stack_count<<endl;
cout<<"max_clip_planes="<<max_clip_count<<endl;
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
{
//glBindVertexArray(vertex_array[0]);
//glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
//glBindVertexArray(0);
//通过计算截取一个正方向// oh,yeah
//GLdouble equ0[] = {1,0,0,0.5};
//glClipPlane(GL_CLIP_PLANE0, equ0);
//glEnable(GL_CLIP_PLANE0);
//GLdouble equ1[] = {-1,0,0,0.5};
//glClipPlane(GL_CLIP_PLANE1, equ1);
//glEnable(GL_CLIP_PLANE1);
//GLdouble equ2[] = {0,-1,0,0};
//glClipPlane(GL_CLIP_PLANE2, equ2);
//glEnable(GL_CLIP_PLANE2);
#if 1
glBindVertexArray(vertex_array[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
#else
glBindVertexArray(vertex_array[0]);
glDrawArrays(GL_QUADS, 0, 24);
glBindVertexArray(0);
#endif
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);
}
glPopMatrix();
//Must call flush to update frame buffer
glFlush();
}
int _tmain(int argc, _TCHAR** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(500, 300);
glutInitWindowSize(360, 360);
glutCreateWindow("Vertex Array Object and Vertex Buffer Object");
//创建窗口,建立上下文之后就可以调用glewInit()
//glewInit()在使用glew的接口之前调用,否则会失败
GLenum err = glewInit();
if (err != GLEW_OK)
{
cout<<"glewInit() failed!!!"<<endl;
return EXIT_FAILURE;
}
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
2.使用裁剪平面的效果
// VAO.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <cstdlib>
#include <cassert>
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glew32.lib")
using namespace std;
GLuint vertex_array[2] = {0,0};
void init()
{
GLubyte indices[][4] ={
{0,1,2,3},
{4,7,6,5},
{0,4,5,1},
{3,2,6,7},
{0,3,7,4},
{1,5,6,2}
};
GLfloat vertexs[][3] = {
{-1, -1, -1},
{1, -1, -1},
{1, 1, -1},
{-1, 1, -1},
{-1, -1, 1},
{1, -1, 1},
{1, 1, 1},
{-1, 1, 1},
};
GLfloat color[][3] ={
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{0.5, 0, 0},
{0, 0.5, 0},
{0, 0, 0.5},
{0.5, 0.5, 0.5},
{0.8, 0.8, 0.8}
};
glClearColor(0, 0, 0, 0);
glShadeModel(GL_SMOOTH);
//VAO[0]
glGenVertexArrays(2, vertex_array);
glBindVertexArray(vertex_array[0]);
//顶点数据
GLuint vbo_vertex = 0;
glGenBuffers(1, &vbo_vertex);
assert(vbo_vertex != 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*8, vertexs, GL_STATIC_DRAW);
//Bind VAO and VBO 索引0一定是顶点
//将顶点数据输入到VAO,用来建立VAO和VBO的数据传递,上传数据完成之后可以删除
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); //leave out this sentence
//顶点颜色
GLuint vbo_color = 0;
glGenBuffers(1, &vbo_color);
assert(vbo_color);
glBindBuffer(GL_ARRAY_BUFFER, vbo_color);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*24, color, GL_STATIC_DRAW);
glVertexAttribPointer(4,3,GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
//glColorPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_COLOR_ARRAY); //??????
//assert(glGetError() == GLEW_OK);
//使用VBO来实现顶点缓冲
//GLuint vbo = 0;
//glGenBuffers(1, &vbo);
//assert(vbo != 0);
//glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*8, vertexs, GL_STATIC_DRAW);
//glVertexPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_VERTEX_ARRAY);
//将顶点索引写入显存
GLuint vbo_index = 0;
glGenBuffers(1, &vbo_index);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_index);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*24, indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
assert(glGetError() == GLEW_OK);
//VAO[1]
GLfloat vertex_triangle[][3] =
{
{0, 1, 0},
{-1, -1, 0},
{1, -1, 0}
};
GLfloat color_triangle [][3] =
{
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
GLubyte index_triangle[] = {0, 1, 2};
glBindVertexArray(vertex_array[1]);
GLuint vboID[3] = {0};
glGenBuffers(3,vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, vertex_triangle, GL_STATIC_DRAW);
//glVertexPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboID[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, color_triangle, GL_STATIC_DRAW);
//glColorPointer(3, GL_FLOAT, 0, 0);
//glEnableClientState(GL_COLOR_ARRAY);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*3, index_triangle, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
assert(GLEW_OK == glGetError());
GLint max_modelview_stack_count = 0;
GLint max_projection_stack_count = 0;
GLint max_clip_count = 0;
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &max_modelview_stack_count);
glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, &max_projection_stack_count);
glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_count);
cout<<"max_modelview_stack_count="<<max_modelview_stack_count<<endl;
cout<<"max_projection_stack_count"<<max_projection_stack_count<<endl;
cout<<"max_clip_planes="<<max_clip_count<<endl;
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
{
//glBindVertexArray(vertex_array[0]);
//glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
//glBindVertexArray(0);
//通过计算截取一个正方向// oh,yeah
//GLdouble equ0[] = {1,0,0,0.5};
//glClipPlane(GL_CLIP_PLANE0, equ0);
//glEnable(GL_CLIP_PLANE0);
//GLdouble equ1[] = {-1,0,0,0.5};
//glClipPlane(GL_CLIP_PLANE1, equ1);
//glEnable(GL_CLIP_PLANE1);
//GLdouble equ2[] = {0,-1,0,0};
//glClipPlane(GL_CLIP_PLANE2, equ2);
//glEnable(GL_CLIP_PLANE2);
#if 1
glBindVertexArray(vertex_array[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
#else
glBindVertexArray(vertex_array[0]);
glDrawArrays(GL_QUADS, 0, 24);
glBindVertexArray(0);
#endif
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);
}
glPopMatrix();
//Must call flush to update frame buffer
glFlush();
}
int _tmain(int argc, _TCHAR** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(500, 300);
glutInitWindowSize(360, 360);
glutCreateWindow("Vertex Array Object and Vertex Buffer Object");
//创建窗口,建立上下文之后就可以调用glewInit()
//glewInit()在使用glew的接口之前调用,否则会失败
GLenum err = glewInit();
if (err != GLEW_OK)
{
cout<<"glewInit() failed!!!"<<endl;
return EXIT_FAILURE;
}
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}