OpenGL-1入门,环境搭建

47 阅读3分钟

OpenGL 介绍

OpenGL 是一种图形应用程序编程接口。适用于Windows,macOS开发。

OpenGL ES则是用于嵌入式设备,比如iOS,Android开发,是OpenGL的一个子集。

开发环境搭建

点击依赖文件,并添加到项目中。

设置依赖的库文件。

企业微信截图_6e8194a9-5bae-473a-9d2e-465a4462b761.png

设置头文件搜索路径,将include文件拖进去。

删除文件AppDelegate.hAppDelegate.m,ViewController.h,ViewController.mmain.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();
}