zoukankan      html  css  js  c++  java
  • 对渲染相关操作封装的类库

    github链接

    开始准备做毕设了,利用周末的时间整理了一下图形学渲染相关的一些基础代码,尤其是opengl相关的,封装完后,如下只需简单几行就可以构建一个opengl框架。

    #include <common/glfwApp.h>
    #include <openglWrappers/DemoMeshes/BlinnPhongMesh.h>
    
    //glfw setup
    auto application = redips::glfw::getInstance(720, 720);
    
    //standard pinhole camera
    redips::PhC phc(60, 1.0f, 1.0f, 10000);
    
    //load a obj and then wrap into a glMesh。
    redips::BlinnPhongMesh mesh(new redips::Triangles("E:/Documents/models/maze_with_dragon.obj"));
    
    void movement(){
    	if (application->keydown(GLFW_KEY_F))
    		application->showFps(false);
    }
    
    //need register a display-callback function to tell glfwApp what to render
    void display(){
    	mesh.uniformFloat3("lightColor", redips::float3(1, 1, 1));
    	mesh.uniformFloat3("lightPos", phc.pos());
    	mesh.uniformFloat3("cameraPos", phc.pos());
    	mesh.uniformMat44f("projection", phc.glProjection().ptr());
    	mesh.uniformMat44f("view", phc.glView().ptr());
    	mesh.uniformMat44f("model", redips::Mat44f::eye().ptr());
    	mesh.draw();
    
    	movement();
    }
    
    void initialize(){
    	//mesh center
    	redips::float3 heart = mesh.model_ptr()->aabb_T().heart();
    	//set up camera
    	phc.lookAt(heart + redips::float3(0, 0, 200), heart, redips::float3(0, 1, 0));
    }
    
    int main(){
    	initialize();
    	application->registerDisplayCallback(display);
    	application->bindCamera(&phc);
    	application->loop();
    	return 0;
    }
    

    简单介绍一下结构

    1.依赖

    需要FreeImage读/写图片,及glfw/glew。github链接里包含了所有代码及依赖的库文件。

    不需要glm,assimp。

    2. 环境搭建

    a. 以VS2013为例,设置redips及GLEW/GLFW的头文件目录,库目录以及dll目录

    X64 release
    
    #include 
    E:DocumentsCGCGLib
    edips
    E:DocumentsCGCGLib
    edipsDependenciesGLEW_GLFW_X64include
    
    #libs
    E:DocumentsCGCGLib
    edipsDependenciesFreeImagex64
    E:DocumentsCGCGLib
    edipsDependenciesGLEW_GLFW_X64libsglew_x64
    E:DocumentsCGCGLib
    edipsDependenciesGLEW_GLFW_X64libsglfw_64_lib-vc2013
    
    FreeImage.lib
    glew32.lib
    opengl32.lib
    glfw3.lib
    
    #dlls
    path=E:DocumentsCGCGLib
    edipsDependenciesFreeImagex64;E:DocumentsCGCGLib
    edipsDependenciesGLEW_GLFW_X64inx64;E:DocumentsCGCGLib
    edipsDependenciesGLEW_GLFW_X64libsglfw_64_lib-vc2013
    

     b. 因为OpenglWrappersDemoMeshes下面提供了BlinnPhongMesh,gBufferMesh,PhongMesh三个mesh,每个mesh都提供了默认的shader文件,所以在Commonconstant.h里面定义了一个宏:_REDIPS_ROOT_PATH_。需要把其改为解压redips的根目录。

    3. 类库

    Cameras里面包括基类Camera以及派生类PhC,GLC,MPC,常用PhC(小孔相机)实现了getRay(uint x,uint y)[for raytracing];  glProjection()[for rasterization]等常用函数。

    Common比较重要。里面包含了

    • constant.h => 包含一些常量、宏、枚举类的定义。
    • fImage.h  => 对FreeImage的封装。可以方便的读、写图片。
    • glfwApp.h   => 对GLFW的封装。仅需一句 auto application = redips::glfw::getInstance(); 就可以创建好一个GLFW环境。
    • rayTracer.h => 实现了一个简单的Ray Tracer。渲染一副图片并保存。
    • utils.h => 实现了一些工具类,如StringUtil类实现了部分对字符串的操作。
    • vec.h  => Vec2/Vec3/Vec4/Mat33/Mat44的常用操作,遵循 column-major。

    Geometry里包含了几何相关的类。

    • geometry.h => 定义了简单常用的数据结构,如BOX,Light,Ray,HitRecord,以及一个工具类GeoUtil,提供如求重心坐标、三角形面积等工具函数
    • kdtree.h => 实现了一个简单的kdtree用于加速raytracing。
    • material.h => 定义了材质类Material以及MtlLib类用来load *.mtl文件。
    • model.h => 定义了模型类的基类Model,暂时只派生出Triangles和Partiles两个类。Model类主要定义了几个接口规范。比如virtual bool intersect(const Ray& ray, HitRecord& record) = 0;用来判断光线是否与模型相交。
    • triangles.h => 定义了Mesh类用来加载obj模型及存储相关信息。Triangles类是Model类的派生类。实现了Model的全部接口。还有 类似Triangles(const float3 &boxdim,float3 center = float3(0.0f,0.0f,0.0f))【快速创建一个正方体mesh。】的函数
    • particles.h => 一堆小球组成的例子系统。暂时还不完善。

    OpenglWrappers里面封装了OpenGL相关的类。

    • glMeshWrapper.h => 用来将数据打包传到显卡,这包括材质中用到的纹理。实现了引用计数避免将同一个模型的数据多次传入显存。将Obj模型里使用相同material的group合并成一组放在一个Vbo里节约了资源。后面会介绍glMeshWrapper的使用。
    • glslShaderWrapper.h => 封装了glsl shader的相关操作。ShaderSource类用来说明shader的来源(from file or existed shader program)用来避免多次创建同一个shader。Shader类主要负责加载shader文件。ShaderManager类会自动加载一个指定文件夹下的所有shader文件,并重载了[]运算符。shaderManager["light"],即可获得light.vs/light.fs定义的shader。
    • glTextureWrapper.h => 封装了Texture的相关操作。
    • glHelper.h => 定义了opengl相关的辅助类:glImageRender用于显示一张2d图片到opengl窗口(可以用来显示raytracing的结果),glScreenCapture用于保存渲染的图片。

     4. glMeshWrapper的使用

    glMeshWrapper只负责生成纹理、将数据绑定到VBO。而其派生类负责和shader交互,渲染等。所以glMeshWrapper的构造函数被定义成了protected不能创建对象。
    其作为基类提供了一些常用操作及接口规范。定义一个glMeshWrapper派生类需要以下工作:

    #pragma once
    #include <openglWrappers/glMeshWrapper.h>
    class LightMesh : public redips::glMeshWrapper{
    public:
    	LightMesh(const redips::Triangles* model, redips::ShaderSource shadersource = redips::ShaderSource(), unsigned int option = 1u) : glMeshWrapper(model, shadersource,option){
    		bindVaoAttribData(0, 1, -1);
    	};
    	LightMesh(const glMeshWrapper& another, redips::ShaderSource shadersource = redips::ShaderSource()) : glMeshWrapper(another,shadersource){
    		bindVaoAttribData(0, 1, -1);
    	}
    	~LightMesh(){};
    };
    

    1. 定义一个普通构造及一个拷贝构造函数,说明应该绑定哪些数据到vao。普通构造函数中的三个参数分别是:三角mesh、mesh使用的ShaderSource、打包mesh的option[传送模型数据时是以mtl为单位还是group为单位打包;是否要自动生成三角面片的法线]。ShaderSource有两个构造函数及一个默认构造,其中一个接受一个GLuint类型的参数[代表一个现有的shaderProgram],另外一个接受const char* 类型的参数[shader文件的路径]。所以可以像下面那样创建LightMesh.

        LightMesh* mesh1 = new LightMesh(new Triangles("obj/file/path"), "shader/path");
        LightMesh* mesh2 = new LightMesh(new Triangles("obj/file/path"), existedShader.Program);
    
        LightMesh* mesh3 = new LightMesh(new Triangles("obj/file/path"));
        mesh3->useShader(existedShader.Program);
        mesh3->useShader("shader/path");

    也可以像mesh3那样后来再指定shader。

    2. 重写glMeshWrapper的draw()函数用于定制化的渲染[比如激活纹理等操作]。LightMesh类没有重写,使用了glMeshWrapper提供的draw()函数。

  • 相关阅读:
    阿里云通过465端口发送邮件绕过25端口
    阿里云子账号Policy授权规则明细
    蓝鲸cmdb平台架构
    库文件缺失问题修复
    centos7.2中启动polkit服务启动失败
    Linux升级GCC
    Ubuntu18.04服务器使用netplan网络构建桥接kvm虚拟机
    常用服务部署脚本(nodejs,pyenv,go,redis,)
    anaconda安装教程(之前安装过python)
    【PHP】array_unique与array_array_flip
  • 原文地址:https://www.cnblogs.com/redips-l/p/8013138.html
Copyright © 2011-2022 走看看