#我的思考#
我前一段时间仔细考虑了开题的问题,总结了几个大方向:
由于都涉及到OpenGL的呈现,所以我最近一直在对OpenGL进行细致的学习。
#我的实践#
*OpenGL代码基本结构
OpenGL代码主要由三个部分构成:initialization,display,main函数。示例代码如下:
#include
#include "gl.h"
#include "glut.h"
//#include
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("第一个OpenGL程序");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
**VAO VBO的认识
OpenGL使用VAO保存和渲染顶点缓存对象的相关状态,使用VBO保存对象的数据,借用一位大牛的话,OpenGL实际上是状态机。设置数组内容,读取前3*4个float为position,后3*4个float的内容为color,但是只能显示三角形为白色,无法显示颜色,我的理解是要使用shader才行。示例代码如下:
//#include "stdafx.h"
//#include
#include
#include
//including gl/glu.h
#include
//#include
GLuint vbo_position; GLuint vbo_color; GLuint vbo_triangle; GLuint vao1; GLuint vao2; GLuint programID; static const GLushort vertex_indices[] = { 0, 1, 2 , 0, 3, 1, 1, 2, 3,}; void init(void) { const GLfloat vertex_data[] = { -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,//position 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.8f, 0.7f, 0.3f, 0.0f//color }; // Color for each vertex /*static const GLfloat vertex_colors[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, };*/ // Indices for the triangle strips //vertex_indices[] = { 0, 1, 2 }; //glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色为黑色 //glShadeModel(GL_SMOOTH);//设置为光滑明暗模式 //初始化VBO glGenBuffers(1, &vbo_triangle); glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STREAM_DRAW); /*glGenBuffers(1, &vbo_position); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_position); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glGenBuffers(1, &vbo_color); glBindBuffer(GL_ARRAY_BUFFER, vbo_color); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_colors), vertex_colors, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0)*/; //绑定VAO glGenVertexArrays(1, &vao1); glBindVertexArray(vao1); /*size_t colorDataOffset = sizeof(float) * 3 * 3; glBindBuffer(GL_ARRAY_BUFFER, vbo_color); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_position); glBindVertexArray(0);*/ } void myDisplay(void) { //glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);// 将缓存清除为预先的设置值,即黑色 //glTranslatef(0.8, 0.0, 0.0);//平移函数,暂时可以不用 //glBegin(GL_TRIANGLES);//开始画三角形 //glColor3f(1.0, 0.0, 0.0);//设置第一个顶点为红色 //glVertex2f(-1.0, -1.0);//设置第一个顶点的坐标 //glColor3f(0.0, 1.0, 0.0);//设置第二个顶点为绿色 //glVertex2f(0.0, -1.0);//设置第二个顶点的坐标 //glColor3f(0.0, 0.0, 1.0);//设置第三个顶点为蓝色 //glVertex2f(-0.5, 1.0);//设置第三个顶点的坐标 //glEnd();//三角形结束 //glFlush();//强制OpenGL函数在有限时间内运行 glUseProgram(programID); glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle); //向顶点着色器传递数据 glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0,0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48); //glBindVertexArray(vao1); //glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_SHORT, (GLvoid*)vertex_indices); glDrawArrays(GL_TRIANGLES, 0, 3); glUseProgram(0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glFlush(); } //void myReshape(GLsizei w, GLsizei h) //{ // glViewport(0, 0, w, h);//设置视口 // glMatrixMode(GL_PROJECTION);//指明当前矩阵为GL_PROJECTION // glLoadIdentity();//将当前矩阵置换为单位阵 // if (w <= h) // gluOrtho2D(-1.0, 1.5, -1.5, 1.5*(GLfloat)h / (GLfloat)w);//定义二维正视投影矩阵 // else // gluOrtho2D(-1.0, 1.5*(GLfloat)w / (GLfloat)h, -1.5, 1.5); // glMatrixMode(GL_MODELVIEW);//指明当前矩阵为GL_MODELVIEW //} int main(int argc, char ** argv) { /*初始化*/ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//单缓冲、RGB模式 glutInitWindowSize(400, 400); glutInitWindowPosition(200, 200); glutCreateWindow("四边形");//窗口标题 if (glewInit()){ printf( "Unable to initialize GLEW ... EXITING"); } init(); /*绘制与显示*/ //glutReshapeFunc(myReshape);//窗口大小发生改变时采取的行为 glutDisplayFunc(myDisplay);//显示绘制图形 glutMainLoop();//循环 return(0); }
***着色器的使用
修改的上面的代码,加入了shader的数据结构,加入顶点着色器和片元着色器的操作代码,但是有问题,目前未解决(10.31.2016)。代码如下:
//#include "stdafx.h"
//#include
#include
#include
//including gl/glu.h
#include
//#include
GLuint vbo_position; GLuint vbo_color; GLuint vbo_triangle; GLuint vao1; GLuint vao2; GLuint program; static const GLushort vertex_indices[] = { 0, 1, 2, 0, 3, 1, 1, 2, 3, }; typedef struct { GLenum type; const char* filename; GLuint shader; } ShaderInfo; GLuint LoadShader(ShaderInfo*); void init(void) { const GLfloat vertex_data[] = { -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,//position 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.8f, 0.7f, 0.3f, 0.0f//color }; // Color for each vertex /*static const GLfloat vertex_colors[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, };*/ // Indices for the triangle strips //vertex_indices[] = { 0, 1, 2 }; //glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色为黑色 //glShadeModel(GL_SMOOTH);//设置为光滑明暗模式 //初始化VBO glGenBuffers(1, &vbo_triangle); glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STREAM_DRAW); /*glGenBuffers(1, &vbo_position); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_position); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glGenBuffers(1, &vbo_color); glBindBuffer(GL_ARRAY_BUFFER, vbo_color); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_colors), vertex_colors, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0)*/; //绑定VAO glGenVertexArrays(1, &vao1); glBindVertexArray(vao1); /*size_t colorDataOffset = sizeof(float) * 3 * 3; glBindBuffer(GL_ARRAY_BUFFER, vbo_color); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_position); glBindVertexArray(0);*/ ShaderInfo shaders[] = { { GL_VERTEX_SHADER, "simplest.vert" }, { GL_FRAGMENT_SHADER, "simplest.frag" }, { GL_NONE, NULL } }; program = LoadShader(shaders); glCompileShader(program); glLinkProgram(program); 我们把需要的数据和shader程序中的变量关联在一起,后面会详细讲述 //glVertexAttribPointer(vPosition, 2, GL_FLOAT, // GL_FALSE, 0, BUFFER_OFFSET(0)); //glEnableVertexAttribArray(vPosition); } void myDisplay(void) { //glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);// 将缓存清除为预先的设置值,即黑色 //glTranslatef(0.8, 0.0, 0.0);//平移函数,暂时可以不用 //glBegin(GL_TRIANGLES);//开始画三角形 //glColor3f(1.0, 0.0, 0.0);//设置第一个顶点为红色 //glVertex2f(-1.0, -1.0);//设置第一个顶点的坐标 //glColor3f(0.0, 1.0, 0.0);//设置第二个顶点为绿色 //glVertex2f(0.0, -1.0);//设置第二个顶点的坐标 //glColor3f(0.0, 0.0, 1.0);//设置第三个顶点为蓝色 //glVertex2f(-0.5, 1.0);//设置第三个顶点的坐标 //glEnd();//三角形结束 //glFlush();//强制OpenGL函数在有限时间内运行 //glUseProgram(programID); glUseProgram(program); glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle); //向顶点着色器传递数据 glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48); //glBindVertexArray(vao1); //glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_SHORT, (GLvoid*)vertex_indices); glDrawArrays(GL_TRIANGLES, 0, 3); glUseProgram(0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glFlush(); } //void myReshape(GLsizei w, GLsizei h) //{ // glViewport(0, 0, w, h);//设置视口 // glMatrixMode(GL_PROJECTION);//指明当前矩阵为GL_PROJECTION // glLoadIdentity();//将当前矩阵置换为单位阵 // if (w <= h) // gluOrtho2D(-1.0, 1.5, -1.5, 1.5*(GLfloat)h / (GLfloat)w);//定义二维正视投影矩阵 // else // gluOrtho2D(-1.0, 1.5*(GLfloat)w / (GLfloat)h, -1.5, 1.5); // glMatrixMode(GL_MODELVIEW);//指明当前矩阵为GL_MODELVIEW //} int main(int argc, char ** argv) { /*初始化*/ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//单缓冲、RGB模式 glutInitWindowSize(400, 400); glutInitWindowPosition(200, 200); glutCreateWindow("四边形");//窗口标题 if (glewInit()){ printf("Unable to initialize GLEW ... EXITING"); } init(); /*绘制与显示*/ //glutReshapeFunc(myReshape);//窗口大小发生改变时采取的行为 glutDisplayFunc(myDisplay);//显示绘制图形 glutMainLoop();//循环 return(0); }#version 300 out vec4 outputColor; void main(){ float lerpValue = (gl_FragCoord.y-256.0f)/128.0f; outputColor = mix(vec4(1.0f,0.0f,0.0f,1.0f), vec4(0.0f,0.0f,1.0f,1.0f),lerpValue); }#version 300 layout(location = 0) in vec4 pos; void main() { gl_Position = pos; }