97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

好看的手機(jī)端網(wǎng)站開發(fā)頁面上海建站模板平臺(tái)

鶴壁市浩天電氣有限公司 2026/01/24 10:26:40
好看的手機(jī)端網(wǎng)站開發(fā)頁面,上海建站模板平臺(tái),騰訊 網(wǎng)站開發(fā),網(wǎng)站建設(shè)用什么語言好1 前言1.1 開發(fā)該框架的動(dòng)機(jī)? OpenGL ES 是一個(gè)渲染指令接口集合#xff0c;每渲染一幀圖像都是一系列渲染指令的排列組合。常用的渲染指令約有 70 個(gè)#xff0c;記住這些渲染指令及其排列組合方式#xff0c;是一件痛苦的事情。另外#xff0c;在圖形開發(fā)中#xff0c;經(jīng)…1 前言1.1 開發(fā)該框架的動(dòng)機(jī)? OpenGL ES 是一個(gè)渲染指令接口集合每渲染一幀圖像都是一系列渲染指令的排列組合。常用的渲染指令約有 70 個(gè)記住這些渲染指令及其排列組合方式是一件痛苦的事情。另外在圖形開發(fā)中經(jīng)常因?yàn)楣?、丟幀等問題需要性能優(yōu)化如何從框架層面進(jìn)行性能優(yōu)化是一件有挑戰(zhàn)的問題。? 基于上述原因筆者手撕了一個(gè) nimi 版的渲染框架將這些常用的渲染指令有條理地封裝、組織、歸類方便愉快并高效地進(jìn)行 OpenGL ES 渲染開發(fā)。筆者在 OpenGL ES 領(lǐng)域從業(yè)也有些時(shí)日對(duì)現(xiàn)有碎片化的知識(shí)進(jìn)行歸納凝練形成系統(tǒng)的認(rèn)知是件勢在必行的事。1.2 一個(gè) mini 版的渲染框架應(yīng)該具備哪些能力? 一個(gè) mini 版的渲染框架需要對(duì) OpenGL ES 的常用指令進(jìn)行歸類如下圖封裝 EGL、error check、Shader Program、Mesh、VAO、VBO、IBO、Texture、FBO 等類方便開發(fā)者快速開發(fā)渲染程序?qū)⒏嗟淖⒁饬劢乖跇I(yè)務(wù)上而不是如何去組織 OpenGL ES 指令上。img1.3 為什么強(qiáng)調(diào) mini 版渲染框架? 從渲染指令的角度來看OpenGL ES 3.0 約有 300 個(gè)渲染指令本文框架只封裝其中最常用的 70 個(gè)指令覆蓋程度仍有較大提升空間。? 從功能的角度來看筆者深知一個(gè)成熟完備的渲染框架應(yīng)該具備相機(jī)、光源、光照模型Lambert、Phong、PBR 等、陰影、射線拾取、重力、碰撞檢測、粒子系統(tǒng)等功能。? 鑒于上述原因筆者審慎地保留了 mini 前綴。1.4 本框架的優(yōu)勢? 本框架具有以下優(yōu)勢。封裝友好對(duì)常用的 EGL 和 GL 指令約 70 個(gè)進(jìn)行封裝提供了 EGL 環(huán)境搭建、著色器程序生成、網(wǎng)格構(gòu)建、紋理貼圖、離屏渲染、異常檢測等基礎(chǔ)能力方便開發(fā)者快速開發(fā)渲染程序?qū)⒕姆彪s的渲染指令中解放出來將更多的注意力聚焦到業(yè)務(wù)上。代碼規(guī)整框架中多處設(shè)計(jì)了 bind 和 unbind 接口用于綁定和解綁 OpenGL ES 狀態(tài)機(jī)相關(guān) “插槽”如VBO、IBO、VAO 中都設(shè)計(jì)了 bind 和 unbind 接口ShaderProgram、Texture、FBO、TextureAction 中都設(shè)計(jì)了 bind 接口另外在 FBO 中設(shè)計(jì)了 begin 和 end 接口很直觀地告訴用戶夾在這中間的內(nèi)容將渲染到 FBO。接口規(guī)整簡潔方便用戶記憶。易于擴(kuò)展定義了 TextureAction 接口并提供 bind 函數(shù)GLTexture、FBO 都繼承了 TextureAction用戶自定義的渲染器或特效類也可以繼承 TextureAction將它們統(tǒng)一視為紋理活動(dòng)可綁定這在特效疊加或后處理中非常有用方便管理多渲染目標(biāo)圖層易于擴(kuò)展。性能高效封裝了 VBO、IBO、VAO用于緩存頂點(diǎn)數(shù)據(jù)、索引、格式等信息到顯存減少 CPU 到 GPU 的數(shù)據(jù)傳輸提高渲染效率緩存了 attribute 和 uniform 變量的 location避免 CPU 頻繁向 GPU 查詢 location進(jìn)一步提高渲染效率基于 C 語言實(shí)現(xiàn)渲染框架代碼執(zhí)行效率較高??缙脚_(tái)基于 C 語言實(shí)現(xiàn)具有更好的跨平臺(tái)特性封裝了 core_lib使得平臺(tái)相關(guān)頭文件可以輕松替換封裝了 Application使得平臺(tái)相關(guān) api 可以輕松替換。方便調(diào)試設(shè)計(jì)了 EGL_CALL 和 GL_CALL 兩個(gè)宏對(duì)每個(gè) EGL 和 GL 指令進(jìn)行異常檢測方便調(diào)試渲染指令并且通過預(yù)編譯宏 DEBUG 開關(guān)動(dòng)態(tài)控制是否生成異常檢測的代碼Release 版本會(huì)自動(dòng)屏蔽異常檢測代碼避免帶來額外功耗。2 渲染框架? 經(jīng)過深思熟慮筆者給該渲染框架命名為 glcore命名空間也是 glcore。Windows 上 OpenGL 環(huán)境搭建主要有 GLFW / freeglut Glad / GLEW 方案詳見 → Windows上OpenGL環(huán)境搭建本文采用目前廣泛使用的 GLFW Glad 方案。Android 版本的 glcore 實(shí)現(xiàn)詳見 → 在Android上手撕一個(gè)mini版的渲染框架。? 本文完整資源包含 glcore 框架和第 4 節(jié)的應(yīng)用詳見 →【OpenGL ES】一個(gè)mini版的Windows渲染框架。2.1 框架結(jié)構(gòu)img2.2 CMakeLists? CMakeLists.txt# 設(shè)置庫名set(LIB_GL_CORE_NAME glcore)# 遞歸添加源文件列表file(GLOB_RECURSE GL_CORE_SOURCES ./src/ *.cpp)# 添加預(yù)構(gòu)建庫add_library(${LIB_GL_CORE_NAME} ${GL_CORE_SOURCES})# 將當(dāng)前目錄設(shè)為公共頭文件目錄 (任何鏈接glcore庫的目標(biāo)都能自動(dòng)獲得這個(gè)頭文件路徑)target_include_directories(${LIB_GL_CORE_NAME} PUBLIC ./)2.3 核心頭文件? 核心頭文件分為對(duì)內(nèi)和對(duì)外的即內(nèi)部依賴 core_lib外部開放 core。? core_lib.h#pragma once/*** glcore 依賴的核心 GL 庫, 便于將 glcore 移植到其他平臺(tái)* Android: EGL GLESv3* Windows: glfw / freeglut glad / glew** author little fat sheep*/#include glad/glad.h#include GLFW/glfw3.h? 之所以要單獨(dú)拎出 core_lib.h是為了方便將該框架遷移到其他平臺(tái)如 Android 上依賴的三方渲染庫是 EGL GLESv3如果不抽出 core_lib.h就需要將很多地方的 glfw3.h glad.h 改為 egl.h gl3.h 工作量大也容易漏改。另外還可以很方便地替換渲染環(huán)境如將 glfw3.h glad.h 替換為 freeglut.h glew.h。? core.h#pragma once/*** glcore核心頭文件* 該頭文件是留給外部使用的, glcore內(nèi)部不能使用, 避免自己包含自己* author little fat sheep*/// OpenGL ES API#include core_lib.h// glcore 核心頭文件#include application.h#include elg_surface_view.h#include format.h#include frame_buffer_object.h#include gl_inspector.h#include gl_texture.h#include mesh.h#include mesh_utils.h#include shader_program.h#include texture_action.h#include vertex_attribute.h? core.h 只提供給外部使用方便外部只需要包含一個(gè)頭文件就能獲取 glcore 的基礎(chǔ)能力。2.4 Application? Application 主要用于管理全局環(huán)境使用單例模式方便獲取一些全局的變量。它也是 glcore 中唯一一個(gè)依賴平臺(tái)相關(guān)的接口除日志 log 接口外如m_window 是 Windows 特有的如果將 glcore 遷移到 Android 中就需要將該變量替換為 ANativeWindow* 類型將這些平臺(tái)相關(guān)變量都集中在 Application 中遷移平臺(tái)時(shí)修改起來也比較容易避免太分散容易漏掉。另外還可以很方便地替換渲染環(huán)境如渲染平臺(tái)替換為 freeglut 時(shí)需要將 GLFWwindow 替換為 void*因?yàn)?freeglut 未提供類似 window 的數(shù)據(jù)結(jié)構(gòu)。? application.h#pragma once#include core_lib.h#define app Application::getInstance()namespace glcore{/*** 應(yīng)用程序, 存儲(chǔ)全局的參數(shù), 便于訪問* author little fat sheep*/class Application {private:static Application* sInstance;public:int width 0;int height 0;float aspect 1.0f;private:GLFWwindow* m_window nullptr;public:static Application* getInstance();~Application();void resize(int width, int height);GLFWwindow* getWindow() { return m_window; }void setWindow(GLFWwindow* window);void releaseWindow();private:Application() {};};} // namespace glcore? application.cpp#include glcore/application.hnamespace glcore{Application* Application::sInstance nullptr;Application *Application::getInstance(){if (sInstance nullptr){sInstance new Application();}return sInstance;}Application::~Application(){}void Application::resize(int width, int height){this-width width;this-height height;this-aspect (float) width / (float) height;}void Application::setWindow(GLFWwindow* window){m_window window;int width, height;glfwGetFramebufferSize(window, width, height);resize(width, height);}void Application::releaseWindow(){if (m_window){m_window nullptr;}}} // namespace glcore2.5 GLInspector? GLInspector 主要用于異常信息檢測另外設(shè)計(jì)了 EGL_CALL 和 GL_CALL 兩個(gè)宏分別對(duì) EGL 和 GL 指令進(jìn)行裝飾。如果定義了 DEBUG 宏就會(huì)對(duì)每個(gè) EGL 和 GL 指令進(jìn)行異常檢測方便調(diào)試代碼如果未定義了 DEBUG 宏就不會(huì)進(jìn)行異常檢測。? 用戶可以在 CMakeLists.txt 中添加預(yù)編譯宏 DEBUG這樣就可以根據(jù) Release 和 Debug 版本自動(dòng)構(gòu)建不同的版本。if (CMAKE_BUILD_TYPE STREQUAL Debug)# 添加預(yù)編譯宏add_definitions(-DDEBUG)endif ()? gl_inspector.h#pragma once#include core_lib.h#ifdef DEBUG#define EGL_CALL(func) func;GLInspector::checkEGLError();#define GL_CALL(func) func;GLInspector::checkGLError();#else#define EGL_CALL(func) func;#define GL_CALL(func) func;#endifnamespace glcore{/*** OpenGL ES命令報(bào)錯(cuò)監(jiān)視器* author little fat sheep*/class GLInspector{public:static void checkEGLError(const char* tag); // 檢查EGL配置static void checkEGLError(); // 通用檢查EGL錯(cuò)誤static void printShaderInfoLog(GLuint shader, const char* tag); // 打印Shader錯(cuò)誤日志static void printProgramInfoLog(GLuint program, const char* tag); // 打印Program錯(cuò)誤日志static void checkGLError(const char* tag); // 檢查GL報(bào)錯(cuò)信息static void checkGLError(); // 通用檢查GL錯(cuò)誤};} // namespace glcore? gl_inspector.cpp#include iostream#include assert.h#include string#include glcore/core_lib.h#include glcore/gl_inspector.h// 以下內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的 (glfw/freeglut已經(jīng)創(chuàng)建了egl環(huán)境)#define EGL_SUCCESS 0x3000#define EGL_NOT_INITIALIZED 0x3001#define EGL_BAD_ACCESS 0x3002#define EGL_BAD_ALLOC 0x3003#define EGL_BAD_ATTRIBUTE 0x3004#define EGL_BAD_CONFIG 0x3005#define EGL_BAD_CONTEXT 0x3006#define EGL_BAD_SURFACE 0x3007#define EGL_BAD_DISPLAY 0x3008#define EGL_BAD_CURRENT_SURFACE 0x3009#define EGL_BAD_NATIVE_PIXMAP 0x300A#define EGL_BAD_NATIVE_WINDOW 0x300D#define EGL_BAD_PARAMETER 0x300C#define EGL_BAD_MATCH 0x3010#define EGL_CONTEXT_LOST 0x300E// 以上內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的#define TAG GLInspectorint eglGetError() { return 0; }using namespace std;namespace glcore{void GLInspector::checkEGLError(const char *tag){int error eglGetError();if (error ! EGL_SUCCESS) {printf(%s: %s failed: 0x%x , TAG, tag, error);}}void GLInspector::checkEGLError(){GLenum errorCode eglGetError();if (errorCode ! EGL_SUCCESS) {string error;switch (errorCode){case EGL_BAD_DISPLAY:error EGL_BAD_DISPLAY;break;case EGL_NOT_INITIALIZED:error EGL_NOT_INITIALIZED;break;case EGL_BAD_CONFIG:error EGL_BAD_CONFIG;break;case EGL_BAD_CONTEXT:error EGL_BAD_CONTEXT;break;case EGL_BAD_NATIVE_WINDOW:error EGL_BAD_NATIVE_WINDOW;break;case EGL_BAD_SURFACE:error EGL_BAD_SURFACE;break;case EGL_BAD_CURRENT_SURFACE:error EGL_BAD_CURRENT_SURFACE;break;case EGL_BAD_ACCESS:error EGL_BAD_ACCESS;break;case EGL_BAD_ALLOC:error EGL_BAD_ALLOC;break;case EGL_BAD_ATTRIBUTE:error EGL_BAD_ATTRIBUTE;break;case EGL_BAD_PARAMETER:error EGL_BAD_PARAMETER;break;case EGL_BAD_NATIVE_PIXMAP:error EGL_BAD_NATIVE_PIXMAP;break;case EGL_BAD_MATCH:error EGL_BAD_MATCH;break;case EGL_CONTEXT_LOST:error EGL_CONTEXT_LOST;break;default:error UNKNOW;break;}printf(checkEGLError failed: %s, 0x%x, error.c_str(), errorCode);assert(false);}}void GLInspector::printShaderInfoLog(GLuint shader, const char* tag){char infoLog[512];glGetShaderInfoLog(shader, 512, nullptr, infoLog);printf(%s: %s failed: %s , TAG, tag, infoLog);}void GLInspector::printProgramInfoLog(GLuint program, const char* tag){char infoLog[512];glGetProgramInfoLog(program, 512, nullptr, infoLog);printf(%s: %s failed: %s , TAG, tag, infoLog);}void GLInspector::checkGLError(const char *tag) {GLenum error glGetError();if(error ! GL_NO_ERROR) {printf(%s: %s failed: 0x%x , TAG, tag, error);}}void GLInspector::checkGLError(){GLenum errorCode glGetError();if (errorCode ! GL_NO_ERROR){string error;switch (errorCode){case GL_INVALID_ENUM:error GL_INVALID_ENUM;break;case GL_INVALID_VALUE:error GL_INVALID_VALUE;break;case GL_INVALID_OPERATION:error GL_INVALID_OPERATION;break;case GL_INVALID_INDEX:error GL_INVALID_INDEX;break;case GL_INVALID_FRAMEBUFFER_OPERATION:error GL_INVALID_FRAMEBUFFER_OPERATION;break;case GL_OUT_OF_MEMORY:error GL_OUT_OF_MEMORY;break;default:error UNKNOW;break;}printf(checkError failed: %s, 0x%x , error.c_str(), errorCode);assert(false);}}} // namespace glcore2.6 EGLSurfaceView? EGLSurfaceView 主要承載了 EGL 環(huán)境搭建。EGL 詳細(xì)介紹見 → 【OpenGL ES】EGLFBO離屏渲染。? 由于 GLFW 中已經(jīng)創(chuàng)建了 EGL 環(huán)境EGLSurfaceView 實(shí)際上是多余的為了保持 glcore 在各個(gè)平臺(tái)上的代碼具有高度一致性并且方便隨時(shí)自主創(chuàng)建 EGL 環(huán)境這里仍然保留了 EGLSurfaceView。本文中主要使用到 EGLSurfaceView 的內(nèi)部類 Renderer起到定制渲染流程規(guī)范的作用。? elg_surface_view.h#pragma once#include core_lib.h// 以下內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的 (glfw/freeglut創(chuàng)建了egl環(huán)境)typedef void* EGLDisplay;typedef void* EGLConfig;typedef void* EGLContext;typedef void* EGLSurface;// 以上內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的namespace glcore{/*** EGL環(huán)境封裝類* glfw和freeglut中創(chuàng)建了egl環(huán)境, 因此該類可以去掉,* 但是為了方便將glcore遷移到需要用戶搭建egl環(huán)境的平臺(tái)中,* 暫時(shí)保留該類.** author little fat sheep*/class EGLSurfaceView{public:class Renderer;private:Renderer* m_renderer nullptr;EGLDisplay m_eglDisplay;EGLConfig m_eglConfig;EGLContext m_eglContext;EGLSurface m_eglSurface;bool m_firstCreateSurface true;public:EGLSurfaceView();~EGLSurfaceView();void setRenderer(Renderer* renderer);bool surfaceCreated();void surfaceChanged(int width, int height);void drawFrame();void surfaceDestroy();private:void createDisplay();void createConfig();void createContext();void createSurface();void makeCurrent();public:/*** 渲染器接口, 類比GLSurfaceView.Renderer* author little fat sheep*/class Renderer {public:virtual ~Renderer() {};virtual void onSurfaceCreated() 0;virtual void onSurfaceChanged(int width, int height) 0;virtual void onDrawFrame() 0;};};} // namespace glcore? elg_surface_view.cpp#include iostream#include glcore/application.h#include glcore/elg_surface_view.h#include glcore/gl_inspector.h#define TAG EGLSurfaceView// 以下內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的 (glfw/freeglut已經(jīng)創(chuàng)建了egl環(huán)境)#define EGL_RED_SIZE 0x3024#define EGL_GREEN_SIZE 0x3023#define EGL_BLUE_SIZE 0x3022#define EGL_ALPHA_SIZE 0x3021#define EGL_DEPTH_SIZE 0x3025#define EGL_RENDERABLE_TYPE 0x3040#define EGL_OPENGL_ES3_BIT 0x0040#define EGL_SURFACE_TYPE 0x3033#define EGL_WINDOW_BIT 0x0004#define EGL_NONE 0x3038#define EGL_CONTEXT_CLIENT_VERSION 0x3098#define EGL_DEFAULT_DISPLAY ((EGLDisplay)0)#define EGL_NO_DISPLAY ((EGLDisplay)0)#define EGL_NO_CONTEXT ((EGLContext)0)#define EGL_NO_SURFACE ((EGLSurface)0)typedef int32_t EGLint;EGLDisplay eglGetDisplay(EGLDisplay a1) { return nullptr; }void eglInitialize(EGLDisplay a1, int* a3, int* a4) {}void eglChooseConfig(EGLDisplay a1, const EGLint* a2, EGLConfig* a3, EGLint a4, EGLint* a5) {}EGLContext eglCreateContext(EGLDisplay a1, EGLConfig a2, EGLContext a3, const EGLint* a4) { return nullptr; }EGLSurface eglCreateWindowSurface(EGLDisplay a1, EGLConfig a2, void* a3, const EGLint* a4) { return nullptr; }void eglMakeCurrent(EGLDisplay a1, EGLSurface a2, EGLSurface a3, EGLContext a4) {}void eglSwapBuffers(EGLDisplay a1, EGLSurface a2) {}void eglDestroySurface(EGLDisplay a1, EGLSurface a2) {}void eglDestroyContext(EGLDisplay a1, EGLContext a2) {}void eglTerminate(EGLDisplay a1) {}// 以上內(nèi)容為了不報(bào)錯(cuò)臨時(shí)添加的namespace glcore{EGLSurfaceView::EGLSurfaceView(){printf(%s: init , TAG);createDisplay();createConfig();createContext();}EGLSurfaceView::~EGLSurfaceView(){printf(%s: destroy , TAG);if (m_renderer){delete m_renderer;m_renderer nullptr;}if (m_eglDisplay m_eglDisplay ! EGL_NO_DISPLAY){// 與顯示設(shè)備解綁EGL_CALL(eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));// 銷毀 EGLSurfaceif (m_eglSurface m_eglSurface ! EGL_NO_SURFACE){EGL_CALL(eglDestroySurface(m_eglDisplay, m_eglSurface));delete m_eglSurface;}// 銷毀 EGLContextif (m_eglContext m_eglContext ! EGL_NO_CONTEXT){EGL_CALL(eglDestroyContext(m_eglDisplay, m_eglContext));delete m_eglContext;}// 銷毀 EGLDisplay (顯示設(shè)備)EGL_CALL(eglTerminate(m_eglDisplay));delete m_eglDisplay;}app-releaseWindow();delete app;}void EGLSurfaceView::setRenderer(Renderer *renderer){printf(%s: setRenderer , TAG);m_renderer renderer;}bool EGLSurfaceView::surfaceCreated(){printf(%s: surfaceCreated , TAG);app-resize(app-width, app-height);createSurface();makeCurrent();if (m_renderer m_firstCreateSurface){m_renderer-onSurfaceCreated();m_firstCreateSurface false;}return true;}void EGLSurfaceView::surfaceChanged(int width, int height){printf(%s: surfaceChanged, width: %d, height: %d , TAG, width, height);app-resize(width, height);if (m_renderer){m_renderer-onSurfaceChanged(width, height);}}void EGLSurfaceView::drawFrame(){if (!m_eglSurface || m_eglSurface EGL_NO_SURFACE || !m_renderer){return;}m_renderer-onDrawFrame();EGL_CALL(eglSwapBuffers(m_eglDisplay, m_eglSurface));}void EGLSurfaceView::surfaceDestroy(){printf(%s: surfaceDestroy , TAG);if (m_eglDisplay m_eglDisplay ! EGL_NO_DISPLAY){// 與顯示設(shè)備解綁EGL_CALL(eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));// 銷毀 EGLSurfaceif (m_eglSurface m_eglSurface ! EGL_NO_SURFACE){EGL_CALL(eglDestroySurface(m_eglDisplay, m_eglSurface));m_eglSurface nullptr;}}app-releaseWindow();}// 1.創(chuàng)建EGLDisplayvoid EGLSurfaceView::createDisplay(){EGL_CALL(m_eglDisplay eglGetDisplay(EGL_DEFAULT_DISPLAY));EGL_CALL(eglInitialize(m_eglDisplay, nullptr, nullptr));}// 2.創(chuàng)建EGLConfigvoid EGLSurfaceView::createConfig(){if (m_eglDisplay m_eglDisplay ! EGL_NO_DISPLAY){const EGLint configAttrs[] {EGL_RED_SIZE, 8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8,EGL_DEPTH_SIZE, 8,EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,EGL_SURFACE_TYPE, EGL_WINDOW_BIT,EGL_NONE};EGLint numConfigs;EGL_CALL(eglChooseConfig(m_eglDisplay, configAttrs, m_eglConfig, 1, numConfigs));}}// 3.創(chuàng)建EGLContextvoid EGLSurfaceView::createContext(){if (m_eglConfig){const EGLint contextAttrs[] {EGL_CONTEXT_CLIENT_VERSION, 3,EGL_NONE};EGL_CALL(m_eglContext eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs));}}// 4.創(chuàng)建EGLSurfacevoid EGLSurfaceView::createSurface(){if (m_eglContext m_eglContext ! EGL_NO_CONTEXT) {EGL_CALL(m_eglSurface eglCreateWindowSurface(m_eglDisplay, m_eglConfig, app-getWindow(), nullptr));}}// 5.綁定EGLSurface和EGLContext到顯示設(shè)備EGLDisplayvoid EGLSurfaceView::makeCurrent(){if (m_eglSurface m_eglSurface ! EGL_NO_SURFACE){EGL_CALL(eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));}}} // namespace glcore2.7 ShaderProgram? ShaderProgram 主要用于編譯 Shader、鏈接 Program、設(shè)置 attribute 屬性、更新 uniform 屬性。? glGetAttribLocation、glGetUniformLocation 兩個(gè)接口需要 CPU 向 GPU 查詢 location 信息并且會(huì)頻繁調(diào)用為提高性能筆者設(shè)計(jì)了 m_attributes 和 m_uniforms 兩個(gè) map 存儲(chǔ) name 到 location 的映射方便快速獲取 location避免 CPU 頻繁與 GPU 交互以提高渲染性能。? shader_program.h#pragma once#include map#include core_lib.husing namespace std;namespace glcore{/*** 著色器程序* author little fat sheep*/class ShaderProgram{public:static constexpr char* ATTRIBUTE_POSITION a_position; // 著色器中位置屬性名static constexpr char* ATTRIBUTE_NORMAL a_normal; // 著色器中位法線性名static constexpr char* ATTRIBUTE_COLOR a_color; // 著色器中顏色屬性名static constexpr char* ATTRIBUTE_TEXCOORD a_texCoord; // 著色器中紋理坐標(biāo)屬性名static constexpr char* ATTRIBUTE_TANGENT a_tangent; // 著色器中切線屬性名static constexpr char* ATTRIBUTE_BINORMAL a_binormal; // 著色器中副切線屬性名static constexpr char* UNIFORM_TEXTURE u_texture; // 著色器中紋理名static constexpr char* UNIFORM_VP u_projectionViewMatrix; // 著色器中VP名private:GLuint m_program;mapconst char*, int m_attributes;mapconst char*, int m_uniforms;public:ShaderProgram(const char* vertexCode, const char* fragmentCode);~ShaderProgram();void bind();GLuint getHandle() { return m_program; }// 操作attribute屬性void enableVertexAttribArray(const char* name);void enableVertexAttribArray(int location);void setVertexAttribPointer(const char* name, int size, int type, bool normalize, int stride, int offset);void setVertexAttribPointer(int location, int size, int type, bool normalize, int stride, int offset);void disableVertexAttribArray(const char* name);void disableVertexAttribArray(int location);// 操作uniform屬性void setUniformi(const char* name, int value);void setUniformi(int location, int value);void setUniformi(const char* name, int value1, int value2);void setUniformi(int location, int value1, int value2);void setUniformi(const char* name, int value1, int value2, int value3);void setUniformi(int location, int value1, int value2, int value3);void setUniformi(const char* name, int value1, int value2, int value3, int value4);void setUniformi(int location, int value1, int value2, int value3, int value4);void setUniformf(const char* name, float value);void setUniformf(int location, float value);void setUniformf(const char* name, float value1, float value2);void setUniformf(int location, float value1, float value2);void setUniformf(const char* name, float value1, float value2, int value3);void setUniformf(int location, float value1, float value2, int value3);void setUniformf(const char* name, float value1, float value2, int value3, int value4);void setUniformf(int location, float value1, float value2, int value3, int value4);void setUniform1fv(const char* name, int length, const float values[]);void setUniform1fv(int location, int count, float const values[]);void setUniform2fv(const char* name, int count, const float values[]);void setUniform2fv(int location, int count, const float values[]);void setUniform3fv(const char* name, int count, const float values[]);void setUniform3fv(int location, int count, const float values[]);void setUniform4fv(const char* name, int count, const float values[]);void setUniform4fv(int location, int count, const float values[]);void setUniformMatrix2fv(const char* name, int count, bool transpose, const float *value);void setUniformMatrix2fv(int location, int count, bool transpose, const float *value);void setUniformMatrix3fv(const char* name, int count, bool transpose, const float *value);void setUniformMatrix3fv(int location, int count, bool transpose, const float *value);void setUniformMatrix4fv(const char* name, int count, bool transpose, const float *value);void setUniformMatrix4fv(int location, int count, bool transpose, const float *value);int fetchAttributeLocation(const char* name);int fetchUniformLocation(const char* name);private:void compileShaders(const char* vertexCode, const char* fragmentCode);GLuint loadShader(GLenum type, const char* source);GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);};} // namespace glcore? shader_program.cpp#include iostream#include glcore/gl_inspector.h#include glcore/shader_program.h#define TAG ShaderProgramnamespace glcore{ShaderProgram::ShaderProgram(const char* vertexCode, const char* fragmentCode){compileShaders(vertexCode, fragmentCode);}ShaderProgram::~ShaderProgram(){if (m_program){GL_CALL(glUseProgram(0));GL_CALL(glDeleteProgram(m_program));m_program 0;}m_attributes.clear();m_uniforms.clear();}void ShaderProgram::bind(){GL_CALL(glUseProgram(m_program));}void ShaderProgram::enableVertexAttribArray(const char* name){int location fetchAttributeLocation(name);enableVertexAttribArray(location);}void ShaderProgram::enableVertexAttribArray(int location){GL_CALL(glEnableVertexAttribArray(location));}void ShaderProgram::setVertexAttribPointer(const char *name, int size, int type, bool normalize, int stride, int offset){int location fetchAttributeLocation(name);
版權(quán)聲明: 本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

沈陽網(wǎng)站建設(shè)工作室有沒有專門做外包銷售的公司

沈陽網(wǎng)站建設(shè)工作室,有沒有專門做外包銷售的公司,自學(xué)網(wǎng)站開發(fā)條件,python 網(wǎng)站架構(gòu)體測成績計(jì)算器小程序介紹 一、基本信息 小程序名稱#xff1a;體測成績計(jì)算器 核心功能#xff1a;全國學(xué)生體

2026/01/23 09:33:01

建設(shè)網(wǎng)站所需要什么百度不收錄網(wǎng)站

建設(shè)網(wǎng)站所需要什么,百度不收錄網(wǎng)站,石家莊網(wǎng)站建設(shè)公司,寧波seo排名如何優(yōu)化WindowResizer#xff1a;5分鐘掌握智能窗口管理的實(shí)用指南 【免費(fèi)下載鏈接】WindowResizer 一個(gè)

2026/01/23 06:34:01

洛陽網(wǎng)站推廣怎么做對(duì)網(wǎng)絡(luò)營銷的認(rèn)識(shí)300字

洛陽網(wǎng)站推廣怎么做,對(duì)網(wǎng)絡(luò)營銷的認(rèn)識(shí)300字,網(wǎng)站沒收錄,新網(wǎng)站seo技術(shù)文章目錄具體實(shí)現(xiàn)截圖主要技術(shù)與實(shí)現(xiàn)手段系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)的思路系統(tǒng)設(shè)計(jì)方法java類核心代碼部分展示結(jié)論源碼lw獲取/同行可拿貨,

2026/01/21 19:33:01

上海網(wǎng)站制作上海網(wǎng)站制作婚慶公司賺錢嗎

上海網(wǎng)站制作上海網(wǎng)站制作,婚慶公司賺錢嗎,進(jìn)口商品代理平臺(tái),自己開發(fā)一款app軟件Bypass Paywalls Clean終極指南#xff1a;免費(fèi)解鎖付費(fèi)內(nèi)容的完整教程 【免費(fèi)下載鏈接】bypas

2026/01/23 04:47:01

網(wǎng)站服務(wù)器地址怎么查php手機(jī)網(wǎng)站開發(fā)教程

網(wǎng)站服務(wù)器地址怎么查,php手機(jī)網(wǎng)站開發(fā)教程,商丘睢陽區(qū)市政建設(shè)局網(wǎng)站,溫州設(shè)計(jì)集團(tuán)網(wǎng)站建設(shè)Temporal工作流引擎深度解析#xff1a;五大行業(yè)場景的技術(shù)實(shí)現(xiàn)與商業(yè)價(jià)值 【免費(fèi)下載鏈接】tempo

2026/01/23 01:05:01