美文网首页音视频从入门到放弃
OpenGL --- (二)案例:渲染三角形/绘制正方形并使用键

OpenGL --- (二)案例:渲染三角形/绘制正方形并使用键

作者: 阿木小丸子 | 来源:发表于2020-07-08 17:22 被阅读0次

一、Mac 配置OpenGL环境

可参考 OpenGL Mac环境配置

二、绘制三角形

三角形绘制流程.jpeg

代码如下:

(1) 引入头文件

#include "GLShaderManager.h"
#include "GLTools.h"
#include <GLUT/GLUT.h>

(2)定义工具类对象(着色器管理类、三角形批次类)

GLShaderManager shaderManager;
GLBatch triangleBatch;

(3)入口函数Main(初始化)

int main(int argc,char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");
glutReshapeFunc(changeSize);
glutDisplayFunc(RenderScene);
GLenum status = glewInit();
 if (GLEW_OK != status) {
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
setupRC();
glutMainLoop();
return  0;
}

(4)初始化setupRC

void setupRC()
{
glClearColor(0.98f, 0.40f, 0.7f, 1);
shaderManager.InitializeStockShaders();
GLfloat vVerts[] = {
        -0.5f,0.0f,0.0f,
        0.5f,0.0f,0.0f,
        0.0f,0.5f,0.0f
    };
    triangleBatch.Begin(GL_TRIANGLES, 3);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

(5)消息循环--渲染回调

void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = {1.0,1.00,0.0,0.5f};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
triangleBatch.Draw();
glutSwapBuffers();  
}

(6)消息循环--窗口大小改变

void changeSize(int w,int h)
{
    glViewport(0, 0, w, h);  
}

三、绘制正方形并使用键位控制

正方形.jpeg

代码如下:

(1) 引入头文件

#include "GLShaderManager.h"
#include "GLTools.h"
#include <GLUT/GLUT.h>

(2)定义工具类对象(着色器管理类、三角形批次类)、正方形边长和四个点坐标

GLShaderManager shaderManager;
GLBatch triangleBatch;
// 边长
GLfloat blockSize = 0.1f;
//正方形的4个点坐标
GLfloat vVerts[] = {
        -blockSize,-blockSize,0.0f,
        blockSize,-blockSize,0.0f,
        blockSize,blockSize,0.0f,
        -blockSize,blockSize,0.0f
};

(3)入口函数Main(初始化)

int main(int argc,char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");
glutReshapeFunc(changeSize);
glutDisplayFunc(RenderScene);
//注册特殊函数
glutSpecialFunc(SpecialKeys);
GLenum status = glewInit();
 if (GLEW_OK != status) {
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
setupRC();
glutMainLoop();
return  0;
}

(4)初始化setupRC

void setupRC()
{
glClearColor(0.98f, 0.40f, 0.7f, 1);
shaderManager.InitializeStockShaders();
//修改为GL_TRIANGLE_FAN ,4个顶点
    triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

(5)消息循环--渲染回调

void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = {1.0,1.00,0.0,0.5f};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
triangleBatch.Draw();
glutSwapBuffers();  
}

(6)消息循环--窗口大小改变

void changeSize(int w,int h)
{
    glViewport(0, 0, w, h);  
}

(7)SpecialKeys

第一种方式:改变顶点坐标

void SpecialKeys(int key, int x, int y){
    
    GLfloat stepSize = 0.025f;
    
    GLfloat blockX = vVerts[0];
    GLfloat blockY = vVerts[10];

    
    
    if (key == GLUT_KEY_UP) {
        
        blockY += stepSize;
    }
    
    if (key == GLUT_KEY_DOWN) {
        
        blockY -= stepSize;
    }
    
    if (key == GLUT_KEY_LEFT) {
        blockX -= stepSize;
    }
    
    if (key == GLUT_KEY_RIGHT) {
        blockX += stepSize;
    }

    //触碰到边界(4个边界)的处理
    
    //当正方形移动超过最左边的时候
    if (blockX < -1.0f) {
        blockX = -1.0f;
    }
    
    //当正方形移动到最右边时
    //1.0 - blockSize * 2 = 总边长 - 正方形的边长 = 最左边点的位置
    if (blockX > (1.0 - blockSize * 2)) {
        blockX = 1.0f - blockSize * 2;
    }
    
    //当正方形移动到最下面时
    //-1.0 - blockSize * 2 = Y(负轴边界) - 正方形边长 = 最下面点的位置
    if (blockY < -1.0f + blockSize * 2 ) {
        
        blockY = -1.0f + blockSize * 2;
    }
    
    //当正方形移动到最上面时
    if (blockY > 1.0f) {
        
        blockY = 1.0f;
        
    }

    
    // Recalculate vertex positions
    vVerts[0] = blockX;
    vVerts[1] = blockY - blockSize*2;
    
    vVerts[3] = blockX + blockSize*2;
    vVerts[4] = blockY - blockSize*2;
    
    vVerts[6] = blockX + blockSize*2;
    vVerts[7] = blockY;
    
    vVerts[9] = blockX;
    vVerts[10] = blockY;
    
    triangleBatch.CopyVertexData3f(vVerts);
    
    glutPostRedisplay();
}

第二种方式:改变顶点着色器的矩阵

void RenderScene(void)
{
     //清缓存区
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};

    M3DMatrix44f mFinalTransform,mTransfromMatrix,mRotationMartix;

        //平移
    m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);

        //每次平移时,旋转5度
    static float yRot = 0.0f;
    yRot += 5.0f;
    m3dRotationMatrix44(mRotationMartix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);

        //将旋转和移动的矩阵结果 合并到mFinalTransform (矩阵相乘)
    m3dMatrixMultiply44(mFinalTransform, mTransfromMatrix, mRotationMartix);

        //将矩阵结果 提交给固定着色器(平面着色器)中绘制
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
    triangleBatch.Draw();

        //执行交换缓存区
    glutSwapBuffers();


}

相关文章

网友评论

    本文标题:OpenGL --- (二)案例:渲染三角形/绘制正方形并使用键

    本文链接:https://www.haomeiwen.com/subject/gynccktx.html