当前位置: 首页 > 科技观察

在开发板上使用OpenGL相关API绘制基本图形流程

时间:2023-03-16 20:18:49 科技观察

了解更多开源内容请访问:51CTO开源基础软件社区https://ost.51cto.comDAYU200是一款支持OpenHarmony的丰富设备,其硬件支持GPU,OpenHarmony的图形框架也开启了GPU相关功能。DAYU200的GPU型号为Mali-G52,支持OpenGLES1.1/2.0/3.2、OpenCL2.0、Vulkan1.1。本文分享于DAYU200,以OpenHarmony为平台,如何搭建OpenGL开发环境,使用最简单的OpenGLAPI(C/C++语言)绘制基本图形——三角形。本文可在OpenHarmony上使用OpenGLAPI绘制基本图形,参考相关开源项目或文章,在此向相关作者表示感谢。1.OpenHarmony图形栈OpenHarmony图形栈如下图所示。OpenHarmony接口层提供图形的NativeAPI能力,包括:WebGL、NativeDrawing渲染能力、OpenGL指令级渲染能力支持等。OpenHarmony应用开发主要基于JSAPI。通常,人们在不使用C/C++的情况下开发应用程序。了解如何使用OpenHarmony的NativeDrawing能力和OpenGL指令绘制一些简单的图形,对于加深对OpenHarmony图形栈的理解是有意义的。2.搭建开发环境如果使用OpenGLAPI直接绘制基本图形,需要依赖OpenHarmony接口层的相关API。如何方便的使用,主要参考Gitee项目(https://gitee.com/honglianglin/glmark2_2)。1、NativeWindow将native_window_wrapper源码和BUILD.gn加入OpenHarmony编译,生成libnative_window_wrapper.z.so库。OpenGL应用程序会调用动态库创建窗口等。库编译完成后,可以使用hdc_std命令推送到开发板。参考命令如下:hdc_stdshellmount-oremount,rw/hdc_stdfilesendlibnative_window_wrapper.z.so/system/lib相关源码见附件(native_window_wrapper.zip),其中native_window_wrapper.h头文件内容文件如下:#ifndefNATIVE_WINDOW_WRAPPER#defineNATIVE_WINDOW_WRAPPER#includeextern"C"{typedefstruct{void*(*CreateWindowWrapper)();bool(*CreateWindow)(void*wrapper,uint32_twind,uint32_th);void*(*GetNativeWindow)(void*包装器);void(*SetVisibility)(void*wrapper,boolvisible);void(*DestroyWindowWrapper)(void*wrapper);}包装函数;boolGetWrapperFunc(WrapperFunc*funcs);}#endif//NATIVE_WINDOW_WRAPPER2.应用开发为了方便直接使用OpenGLAPI开发程序,环境基于glmark2,删除benchmark相关代码,简化为基于Make的工程(见附件)项目源码:native_window_ohos.zip),方便OpenHarmony平台上的应用开发,快速验证OpenGL相关API。目录结构如下,开发时执行make即可编译。├──include│└──native_window_wrapper.h├──main.cpp├──Makefile└──src├──canvas-generic.cpp├──canvas-generic.h├──canvas.h├──glad├──gl-headers.cpp├──gl-headers.h├──gl-state-egl.cpp├──gl-state-egl.h├──gl-state.h├──gl-visual-config.cpp├──gl-visual-config.h├──include├──libmatrix├──native-state.h├──native-state-ohos.cpp├──native-state-ohos。h├──ohos_wrapper_linker.cpp├──ohos_wrapper_linker.h├──options.cpp├──options.h├──shared-library.cpp└──shared-library.hMakefile内核内容:OHOS_ROOT=/home/algoideas/openharmony/masterCC=$(OHOS_ROOT)/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang--sysroot=$(OHOS_ROOT)/out/a311d/obj/third_party/muslCXX=$(OHOS_ROOT)/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++--sysroot=$(OHOS_ROOT)/out/a311d/obj/third_party/muslAR=$(OHOS_ROOT)/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-arLD=$(OHOS_ROOT)/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-linkARFLAG=-rcsTARGET=native_mainPROJECT_PATH=$(shellpwd)CFLAGS:=-march=armv7-a\-mfloat-abi=softfp\-mtune=generic-armv7-a\-mfpu=neon\-mthumb\--target=arm-linux-ohosmusl\--sysroot=$(OHOS_ROOT)/out/rk3568/obj/third_party/musl#WarningCFLAGS+=-Wno-c++11-narrowing#LibCLIBS=-lm-ldl-lrtCLIBS+=-L$(OHOS_ROOT)/设备/soc/rockchip/hardware/gpu/lib-lmali-bifrost-g52-g2p0-ohosCLIBS+=-L$(OHOS_ROOT)/out/rk3568/packages/phone/system/lib-lhilog-lsurface.z-lutils.zCFLAGS+=-DOHOS_USE_DRM-DOHOS_USE_GLESv2-DOHOS_USE_EGLINCLUDE_DIRS+=\-I$(OHOS_ROOT)/third_party/EGL/api\-I$(OHOS_ROOT)/third_party/openGLES/api\-I$(OHOS_ROOT)/utils/native/base/include\-I$(OHOS_ROOT)/drivers/peripheral/base\-I$(OHOS_ROOT)/foundation/graphic/standard/interfaces/innerkits/common\-I$(OHOS_ROOT)/foundation/graphic/standard/interfaces/innerkits/surface\-I$(OHOS_ROOT)/foundation/graphic/standard/utils/buffer_handle/export\-I$(OHOS_ROOT)/foundation/communication/ipc/interfaces/innerkits/ipc_core/include\-I$(OHOS_ROOT)/foundation/aafwk/standard/frameworks/kits/ability/ability_runtime/include\-I$(OHOS_ROOT)/foundation/aafwk/standard/接口/innerkits/ability_manager/include\-I$(OHOS_ROOT)/foundation/aafwk/standard/interfaces/innerkits/app_manager/include/appmgr\-I$(OHOS_ROOT)/third_party/jsoncpp/include\-I$(OHOS_ROOT)/third_party/json/include\-I$(OHOS_ROOT)/foundation/windowmanager/interfaces/innerkits/wm\-I$(OHOS_ROOT)/foundation/graphic/standard/frameworks/surface\-I$(OHOS_ROOT)/foundation/图形/标准/rosen/modules/render_service_base/include\-I$(OHOS_ROOT)/foundation/graphic/standard/rosen/modules/render_service_client/core\-I$(OHOS_ROOT)/foundation/graphic/standard/rosen/modules/渲染服务客户端\-I$(OHOS_ROOT)/third_party/flutter/skia\-I$(OHOS_ROOT)/third_party/flutter/skia/include/core\-I$(OHOS_ROOT)\-I$(OHOS_ROOT)/third_party/skiaINCLUDE_DIRS+=-I$(PROJECT_PATH)/include\-I$(PROJECT_PATH)/src/glad/include\-I$(PROJECT_PATH)/src/libmatrix\-I$(PROJECT_PATH)/srcexportCCCXXCFLAGSARLDARFLAGMODULE_SELECTPP_SOURCES=$(wildcard./src/*.cpp)CPP_OBJECTS=$(patsubst%.cpp,%.o,$(CPP_SOURCES))3.使用OpenGL绘制基本图形API,绘制基础图形-三角形源码如下,参考知乎的绘制过程部分#include"gl-headers.h"#include"options.h"#include"log.h"#include"util.h"#include"canvas-generic.h"#include"native-state-ohos.h"#include"gl-state-egl.h"usingstd::vector;usingstd::string;intmain(intargc,char*argv[]){if(!Options::parse_args(argc,argv))返回1;/*初始化日志类*/Log::init(Util::appname_from_path(argv[0]),Options::show_debug);if(Options::show_help){Options::print_help();返回0;}/*强制320x240输出以进行验证*/if(Options::validate&&Options::size!=std::pair(320,240)){Log::info("Ignoringcustomsize%dx%d用于验证。使用800x600。\n",Options::size.first,Options::size.second);选项::大小=std::pair(320,240);}//创建画布NativeStateOhosnative_state;GLStateEGLgl_state;CanvasGenericcanvas(native_state,gl_state,Options::size.首先,选项::大小。第二);canvas.offscreen(选项::离屏);canvas.visual_config(选项::visual_config);if(!canvas.init()){Log::error("%s:无法初始化画布\n",__FUNCTION__);返回1;}日志::信息("============================================================\n");canvas.print_info();日志::信息("=========================================================\n");canvas.visible(true);/****数据处理:生成并绑定VBO,设置属性指针**///三角顶点数据,归一化(x,y,z)必须映射到[-1,1之间]constfloattriangle[]={//位置-0.5f,-0.5f,0.0f,//左下0.5f,-0.5f,0.0f,//右下0.0f,0.5f,0.0f//上};//生成并绑定立方体的VBOGLuintvertex_buffer_object;//VBOglGenBuffers(1,&vertex_buffer_object);glBindBuffer(GL_ARRAY_BUFFER,vertex_buffer_object);//将顶点数据绑定到当前默认缓冲区,好处是不需要将顶点数据一个一个发送到显卡,可以借助VBO一次发送所有顶点数据//GL_STATIC_DRAW表示顶点数据不会改变glBufferData(GL_ARRAY_BUFFER,sizeof(三角形),三角形,GL_STATIC_DRAW);//设置顶点属性指针//第一个参数0:顶点着色器的位置值//第二个参数3:位置属性是一个三分量向量//第三个参数:顶点的类型//第四个参数:是否要对数据进行标准化,映射到[0,1]//第五个参数:步长,表示连续顶点属性之间的间隔,下一组数据在3个浮点数之后//第六个参数:数据的偏移量,position属性在开头,所以为0,另外还需要强制转换glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);glEnableVertexAttribArray(0);//启用通道0glBindBuffer(GL_ARRAY_BUFFER,0);/****shader:vertexandfragmentshader**//*shader源代码->生成并编译Shader->将shader链接到shader程序->删除shader*/constchar*vertex_shader_source="attributevec4a_Position;\n"//位置变量属性设置为0"voidmain()\n""{\n""gl_Position=a_Position;\n""}\n\0";/*设置片段像素的颜色为红色,vec4(r,g,b,a)*/constchar*fragment_shader_source="voidmain()\n""{\n""gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n""}\n\0";/****生成和编译着色器**//*顶点着色器*/intvertex_shader=glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex_shader,1,&vertex_shader_source,NULL);glCompileShader(vertex_shader);内部成功;字符信息日志[512];失败,打印错误信息*/glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&success);if(!success){glGetShaderInfoLog(vertex_shader,512,NULL,info_log);Log::error("SHADER::VERTEX::COMPILATION_FAIILED%s\n",info_log);}/*片段着色器*/intfragment_shader=glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment_shader,1,&fragment_shader_source,NULL);glCompileShader(片段着色器);/*检查着色器是否编译成功,如果没有,打印错误信息*/glGetShaderiv(fragment_shader,GL_COMPILE_STATUS,&success);if(!success){glGetShaderInfoLog(fragment_shader,512,NULL,info_log);Log::error("glGetShaderivfragment_shader失败%s\n",info_log);}/*将顶点和片段着色器链接到一个着色器程序*/intshader_program=glCreateProgram();glAttachShader(shader_program,vertex_shader);glAttachShader(shader_program,fragment_shader);glLinkProgram(shader_program);/*检查shader是否链接成功,如果链接失败,打印错误信息*/glGetProgramiv(shader_program,GL_LINK_STATUS,&);如果(!成功){glGetProgramInfoLog(shader_program,512,NULL,info_log);Log::error("glGetShaderivshader_program失败%s\n",info_log);}/*删除顶点和片段着色器*/glDeleteShader(vertex_shader);glDeleteShader(片段着色器);/****渲染**//*清除颜色缓冲区*/glClearColor(0.0f,0.0f,0.0f,1.0f);//用黑色背景颜色清除glClear(GL_COLOR_BUFFER_BIT);/*使用着色器程序*/glUseProgram(shader_program);/*绘制三角形*/glDrawArrays(GL_TRIANGLES,0,3);//绘制三角形,绘制三角形,顶点起始索引值,绘制量/*更新交换缓冲区*/canvas.update();glDeleteBuffers(1,&vertex_buffer_object);获取字符();return0;}四、运行效果展示1、运行项目编译的可执行程序native_main,打印日志如下:2、界面展示效果如下(左上角区域320x240):了解更多开源请访问:51CTO开源基础软件社区https://ost.51cto.com