OpenGL 介绍
OpenGL 是一种图形应用程序编程接口。适用于Windows,macOS开发。
OpenGL ES则是用于嵌入式设备,比如iOS,Android开发,是OpenGL的一个子集。
开发环境搭建
点击依赖文件,并添加到项目中。
设置依赖的库文件。
设置头文件搜索路径,将include文件拖进去。
删除文件AppDelegate.h
,AppDelegate.m
,ViewController.h
,ViewController.m
,main.m
,添加文件main.cpp
代码如下
#include "GLShaderManager.h"
#include "GLTools.h"
#include <glut/glut.h>
GLBatch triangleBatch;
GLShaderManager shaderManager;
void ChangeSize(int w, int h){
glViewport(0, 0, w, h);
}
void SetupRC()
{
// 设置背景颜色
glClearColor(0.0f,0.0f,1.0f,1.0f);
// 初始化着色管理器
shaderManager.InitializeStockShaders();
// 设置三角形
GLfloat points[] = {
-0.5, 0, 0,
0.5, 0, 0,
0, 0.5, 0
};
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(points);
triangleBatch.End();
}
// 开始渲染
void RenderScene(void)
{
// 清除一个或一组特定的缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// 设置一组浮点数来表示红色
GLfloat vRed[] = {1, 0, 0, 1};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
// 提交着色器
triangleBatch.Draw();
glutSwapBuffers();
}
int main(int argc, char * argv[]){
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("三角形");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
//��SetupRC
SetupRC();
glutMainLoop();
return 1;
}
运行后,出现一个三角形。
坐标系统
其中左下角的坐标为(-1,-1),右上角的坐标为(1,1)。
因此,如果要实现一个左下角的三角形,则修改坐标如下。
GLfloat points[] = {
-1, 1, 0,
-1, -1, 0,
1, -1, 0
};
正方形
triangleBatch.Begin
可以设置不同的形状。
GLfloat points[] = {
-0.5, -0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0,
-0.5, 0.5, 0
};
triangleBatch.Begin(GL_QUADS, 4);
监听键盘
监听键盘,并进行上下左右移动。为了方便,没有直接初始化一个数组,而是定义了一个结构体,保存该人物的中点,偏移位置,边长等信息。
#include "GLShaderManager.h"
#include "GLTools.h"
#include <glut/glut.h>
GLBatch triangleBatch;
GLShaderManager shaderManager;
void ChangeSize(int w, int h){
glViewport(0, 0, w, h);
}
struct people{
// 中点坐标
GLfloat centerx;
GLfloat centery;
// 边长
GLfloat width;
// 偏移位置
GLfloat offsetX;
GLfloat offsetY;
// 每次移动的步长
GLfloat step_size;
}p1;
GLfloat points[12] = {
0.2
};
void SetupRC()
{
// 设置背景颜色
glClearColor(0.0f,0.0f,0.6f,1.0f);
// 初始化着色管理器
shaderManager.InitializeStockShaders();
triangleBatch.Begin(GL_QUADS, 4);
triangleBatch.CopyVertexData3f(points);
triangleBatch.End();
}
void updatePoints(){
points[0] = p1.centerx + p1.offsetX - p1.width/2;
points[1] = p1.centery + p1.offsetY - p1.width/2;
points[3] = p1.centerx + p1.offsetX + p1.width/2;
points[4] = p1.centery + p1.offsetY - p1.width/2;
points[6] = p1.centerx + p1.offsetX + p1.width/2;
points[7] = p1.centery + p1.offsetY + p1.width/2;
points[9] = p1.centerx + p1.offsetX - p1.width/2;
points[10] = p1.centery + p1.offsetY + p1.width/2;
}
// 开始渲染
void RenderScene(void)
{
// 清除一个或一组特定的缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// 设置一组浮点数来表示红色
GLfloat vRed[] = {1, 0, 0, 1};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
// 提交着色器
triangleBatch.Draw();
glutSwapBuffers();
}
// 键盘点击
void keyboardClick(GLint key, GLint x, GLint y){
// x和y对应鼠标在窗口相对于窗口左上角的坐标
// printf("%d (%d, %d)", key, x, y);
if (key == GLUT_KEY_UP){
p1.offsetY += p1.step_size;
}else if(key == GLUT_KEY_DOWN){
p1.offsetY -= p1.step_size;
}else if(key == GLUT_KEY_LEFT){
p1.offsetX -= p1.step_size;
}else if(key == GLUT_KEY_RIGHT){
p1.offsetX += p1.step_size;
}
// 边界检测
if(p1.centerx + p1.offsetX > 1){
p1.offsetX = 1 - p1.centerx;
}else if (p1.centerx + p1.offsetX < 0){
p1.offsetX = 0 - p1.centerx;
}else if(p1.centery + p1.offsetY > 1){
p1.offsetY = 1 - p1.centery;
}else if(p1.centery + p1.offsetY < 0){
p1.offsetY = 0 - p1.centery;
}
updatePoints();
triangleBatch.CopyVertexData3f(points);
glutPostRedisplay();
}
int main(int argc, char * argv[]){
p1.step_size = 10/800.0;
p1.width = 0.2;
updatePoints();
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("三角形");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
// 监听键盘的事件
glutSpecialFunc(keyboardClick);
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
// SetupRC
SetupRC();
glutMainLoop();
return 1;
}
同时显示多个图形
每个图形都有固定的坐标点构成。比如三角形由3个顶点组成,那么如果要显示2个三角形,则初始化6个顶点。
void SetupRC()
{
// 设置背景颜色
glClearColor(0.0f,0.0f,1.0f,1.0f);
// 初始化着色管理器
shaderManager.InitializeStockShaders();
// 这里需要传递18个坐标点,画2个三角形
triangleBatch.Begin(GL_TRIANGLES, 18);
GLfloat points[18] = {
0, -0.1, 0,
-0.5, -0.5, 0,
0.5, -0.5, 0,
0, 0.1, 0,
-0.5, 0.5, 0,
0.5, 0.5, 0,
};
triangleBatch.CopyVertexData3f(points);
triangleBatch.End();
}