![OpenGLES入門資料_第1頁](http://file2.renrendoc.com/fileroot_temp3/2021-6/5/03b43093-8773-4569-8e74-c161d1bfb913/03b43093-8773-4569-8e74-c161d1bfb9131.gif)
![OpenGLES入門資料_第2頁](http://file2.renrendoc.com/fileroot_temp3/2021-6/5/03b43093-8773-4569-8e74-c161d1bfb913/03b43093-8773-4569-8e74-c161d1bfb9132.gif)
![OpenGLES入門資料_第3頁](http://file2.renrendoc.com/fileroot_temp3/2021-6/5/03b43093-8773-4569-8e74-c161d1bfb913/03b43093-8773-4569-8e74-c161d1bfb9133.gif)
![OpenGLES入門資料_第4頁](http://file2.renrendoc.com/fileroot_temp3/2021-6/5/03b43093-8773-4569-8e74-c161d1bfb913/03b43093-8773-4569-8e74-c161d1bfb9134.gif)
![OpenGLES入門資料_第5頁](http://file2.renrendoc.com/fileroot_temp3/2021-6/5/03b43093-8773-4569-8e74-c161d1bfb913/03b43093-8773-4569-8e74-c161d1bfb9135.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、OpenGL ES 入門一、前言OpenGL ES 是 Khronos Group 創(chuàng) 建 的 一 系 列 API 中 的 一 種 ( 官 方 組 織 是 : /) 。在桌面計算機上有兩套標準的 3DAPI : Direct3D 和 OpenGL 。 Direct3D 實際上是運行在 windows 操作系統(tǒng)上的標準 3DAPI ,而 OpenGL 則是跨平臺的, 適用于 Linux 、多種 UNIX 、 MAC OS X 和 windows 。由于 OpenGL 得到了廣范圍的認可, 所以,基于嵌入式的 3DAPI-OpenGL ES 也就應運而生。
2、沃 Phone 使用的芯片高通 7227 ,它能很好的提供對 OpenGL ES 的支持,了解 OpenGL ES 的種種特性,不僅能開發(fā)出很好的適用于沃Phone的3D游戲、3D應用等。借助于OpenGLES 的平臺無關性,只要稍微修改 EGL ,理論上就可以將開發(fā)的 3D 游戲、 3D 應用移植到任 何支持 OpenGL ES 的平臺上去。本篇文檔就從零開始,深入簡出,跟大家介紹一下 OpenGL ES 的原理和開發(fā)。OpenGL ES 簡介什么是 OpenGL ESOpenGL ES是一套適用于手持嵌入式設備的3DAPI。比如手機、PDA、汽車、航空等等上面都可以使用到 OpenGL E
3、S。 OpenGL ES 是免授權費的、跨平臺的、功能完善的 2D 和 3D 圖形應用程序接口 API ,它是桌面 OpenGL 的子集,是從 OpenGL 裁剪定制而來的。由于手 持設備的相關局限性, OpenGL ES 相對于 OpenGL 不可避免的進行了相關的精簡。去除了 OpenGL 中比如 glBegin/glEnd ,四邊形 (GL_QUADS) 、多邊形 (GL_POL YGONS) 等復雜圖元 等許多非絕對必要的特性。但是OpenGL方面的很多知識,OpenGL ES都是可以借鑒的。OpenGL ES 其實是一個狀態(tài)機 (State machine) ,它保存一種狀態(tài)直至其改
4、變。每個狀態(tài)都有 本身默認的缺省值,可以通過相關的查詢和設置函數進行相關的查詢和設置。大多數的 OpenGL ES 的應用都采用的是相同的操作順序,這一系列的處理階段被稱作OpenGL ES 的渲染管線 (pipeline) 。二、OpenGL ES 的處理流程2.1 固定渲染管線流程:1) Primitive Processing :這一步是圖元運算過程,所謂圖元,其實就是一個點集。在OpenGL ES 中,所有的物體,幾何元素最終都是以頂點的形式表述的。一般來說,這些頂點將會產生三角形、直線或點。 它做的工作就是將頂點提供給頂點處理器進行處理。頂點的數據包括頂點的位置(空間坐標)、大小、顏
5、色、頂點的法向量(用于光照計算 )、紋理坐標 (可能有多個 )等等。2) Transform and Lighting :這一步是轉換和光照過程。其中 Transform 是通過模型、視圖、投影變換矩陣,將所有的頂 點坐標變換成人眼坐標系下的一致坐標。 變換矩陣同樣會改變物體的頂點法向量。 如果激活 了紋理,還可以進行紋理坐標轉換,以及自動紋理坐標的生產。Lighting 處理的就是光照部分,它會利用光源、材質、轉換后的頂點位置和法向量計算每個頂點的顏色值。3) Primitive Assembly :圖元裝配過程。 管線中這個流程是對所有的點數據進行點線面等基礎圖元的組裝。這個過程會對所有的
6、圖元進行剪切和篩選。 對于不在視區(qū)空間中的部分進行剪切, 對于不可見的面進 行篩選。4) Resterizar:光柵化。光柵化的過程就是對所有的經過 Primitive Assembly 圖元轉換成屏幕上可以顯示的 二維Fragment(片元)。片元和將要顯示的像素一一對應。5) Texture Environment : 紋理處理。利用紋理坐標來進行紋理的相關處理。6) Colour Sum : 顏色疊加。根據紋理顏色等相關屬性確定最終的頂點顏色。7) Fog:霧。霧化處理。8) Alpha Test:Alpha 測試。判斷某些片元是否拋棄。比如可以規(guī)定 Alpha 小于 0.2 的片元就需
7、要拋棄。9) Depth Stencil :深度測試和模板測試。 深度測試需要一個深度緩沖區(qū), 是在后面的會被在前的遮蓋, 需要拋 棄。模板測試需要一個模板緩沖區(qū), 也就是模板緩沖區(qū)中為每個像素保存了一個 “模板值”, 當像素需要進行模板測試時,將設定的模板參考值與該像素的 “模板值”進行比較,符合條 件的通過測試, 不符合條件的則被丟棄, 不進行繪制。 條件的設置與 Alpha 測試中的條件設 置相似。但注意 Alpha 測試中是用浮點數來進行比較,而模板測試則是用整數來進行比較。10) Color Buffer blend :跟顏色緩沖區(qū)進行混合。最終生成的片元顏色需要跟顏色緩沖區(qū)中本來的
8、進行混合(也可以理解成為跟背景混合 ),以生成最終的顏色。11) Dither :抖動。 在可用顏色數量較少的系統(tǒng)中, 可能需要對顏色值進行抖動, 在適當損失顏色質量的 情況下增加可使用的顏色數量。12) Frame Buffer :最終結果就寫進了 Frame Buffer。一個流程就算結束了。2.2 可編程渲染管線流程對比固定渲染管線流程圖和可編程渲染管線流程圖, 可以看出來, 大部分的流程都是一樣的, 只是可編程將固定中的幾個功能合并了,新增了兩個新的流程,Vertex Shader 和 FragmentShader。也就是著色器(shader)作為 OpenGL ES2.0 的一部分,
9、著色器允許應用程序顯式地指定處理頂點和片斷時候所執(zhí)行 的操作。Shader language 簡介:編寫 OpenGL ES 程序使用的著色器類似于使用基于編譯器的語言 (比如 C 語言)編寫程序。 我們需要用編譯器來分析程序, 檢查它所存在的錯誤,并把它轉換成為目標代碼。 接著,在 鏈接階段, 鏈接器把一組目標文件組合在一起, 形成一個可執(zhí)行的程序。 著色器的創(chuàng)建流程 如下:對于每個著色器對象:1. 創(chuàng)建一個著色器對象。2. 把著色器源代碼編譯為目標代碼。3. 驗證這個著色器已經成功通過編譯。 然后,為了把多個著色器對象鏈接到一個著色器程序中,需要:1. 創(chuàng)建一個著色器程序。2. 把適當的著
10、色器對象連接到這個著色器程序中。3. 鏈接著色器程序。4. 驗證著色器程序鏈接成功。5. 使用著色器進行頂點或片段處理。1)Vertex Shader:包含了固定渲染管線中的 Transform and lighting 的所有操作。2)Fragment Shader:包含了固定渲染管線中的紋理處理、顏色疊加、霧、 alpha 測試等內容。具體著色器語言和兩個著色器的使用,可見后續(xù)的 sample 分析。三、EGL 簡介OpenGL 實現(xiàn)跨平臺的功能,在不同的操作系統(tǒng)上需要不同的類似適配層的內容,比如在 Windows 操作系統(tǒng)上需要 WGL 。同樣的, OpenGL ES 是一個平臺中立的圖
11、形庫,在它能夠 工作前,需要與一個實際的窗口關聯(lián)起來,但是,與 OpenGL 不一樣的是, OpenGL 是每個 窗口系統(tǒng)需要一個與之對應的適配層, Windows 需要 WGL ,X-Window 需要 xgl, Mac OS 需要agio而OpenGL ES的這層,是統(tǒng)一的一個標準。這個標準就是EGL。(一) 初識 EGLEGL是介于 RenderAPI(比如 OpenGL ES和OpenVG)和本地基礎系統(tǒng)的一套接口。里面涉及了 OpenGL ES和OpenVG的一些相關描述,所以需要和 OpenGL ES和OpenVG文檔一起閱 讀。EGL使用OpenGLES的命名習慣來命名函數入口和
12、宏定義。具體的接口和相關宏定義 可以參見 egl.ho(二) EGL 的使用1. 獲取 Display :Display代表的是顯示器,有的系統(tǒng)上有多個顯示器,也就會有多個display。獲得Display需 要 調 用 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id); , 參 數 一 般 為 EGL_DEFAULT_DISPLAY 。該參數的實際意義是平臺相關的,比如在 windows 平臺上,一 般返回的就是 DC。沃Phone上就是TDC。2. 初始化 egl:獲得了 Display 后,調用 EGLBoolean eg
13、lInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor); 該函數會進行一些相關的內部初始化工作。我們可以通過這個函數獲得egl 的版本號。3. 選擇 Config :Config 實際就是 FrameBuffer 的參數,在 Windows 下對應于 PixelFormat,在 X-Window 下 對應 Visual ??梢杂煤瘮?EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint confi
14、g_size, EGLint *num_config); ,其中 attrib_list 是 以 EGL_NONE 結束的參數數組,通常以 id,value 依次存放,對于個別標識性的屬性可以只 有 id,沒有 value。另一個辦法是用 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); 來獲得所有 config。這兩個函數都會返回 不多于 config_size 個 Config ,結果保存在 configs 中,系統(tǒng)的總 Config 個
15、數保存在 num_config 中??梢岳?eglGetConfig() 中間兩個參數為 0 來查詢系統(tǒng)支持的 Config 總個數。 Config 有 眾多的 Attribute ,這些 Attribute 決定 FrameBuffer 的格式和能力,通過 eglGetConfigAttrib () 來讀取,但不能修改。4. 構造 Surface:有了 Config,就可以開始構造 Surface 了。Surface實際上就是一個 FrameBuffer。通過函數 EGLSurfaceeglCreateWindowSurface(EGLDisplaydpy,EGLConfigcon fig
16、,EGLNativeWi ndowType win, const EGLi nt *attrib_list) 可以創(chuàng)建一個 Surface。系統(tǒng)通常還支持另外兩種 Surface:PixmapSurface 和 PBufferSurface ,這兩種都不是可顯示的Surface,PixmapSurface 是保存在系統(tǒng)內存中的位圖, PBuffer 則是保存在顯存中的幀。 Surface 也有 一 些 attribute , 基 本 上 都 可 以 故 名 思 意 , EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER EGL_TEXTURE_FORMAT EGL
17、_TEXTURE_TARGET EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL , 通 過 eglSurfaceAttrib() 設 置 、 eglQuerySurface() 讀取。5. 創(chuàng)建 Context :OpenGL ES 的 pipeline 從程序的角度看就是一個狀態(tài)機,有當前的顏色、紋理坐標、變換矩 陣、渲染模式等一大堆狀態(tài), 這些狀態(tài)作用于程序提交的頂點坐標等圖元從而形成幀緩沖內 的像素。在 OpenGL ES 的編程接口中, Context 就代表這個狀態(tài)機,程序的主要工作就是向 Context 提 供圖元 、設置狀 態(tài), 偶爾也從 Context
18、里 獲取一 些信 息。用 EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)來創(chuàng)建一個 Con text。6. 繪制:應用程序通過 OpenGL API 進行繪制,一幀完成之后,調用 eglSwapBuffers(EGLDisplay dpy,EGLContext ctx) 來顯示。OpenGL ES 的 HelloWorldcpp view plain copy 在 CODE 上查看代碼片派生到我的代碼片/ 頭文件包含#include T
19、G3.h#include#include#include OGLES2Hello*.h/ 宏定義#define VERTEX_ARRAY 0/ 定義 Display、config 、surface、contextEGLDisplay eglDisplay = 0;EGLConfig eglConfig = 0;EGLSurface eglSurface = 0;EGLContext eglContext = 0;EGLNativeWindowType eglWindow = 0;/沃Phone窗口指針extern TWindow *g_pThis;bool TestEGLError()/egl
20、GetError 返回上一個 egl 中的錯誤,用戶在每個 egl 函數調用結束都需要調用這個函 數。EGLint iErr = eglGetError(); if (iErr != EGL_SUCCESS)return false;return true;bool CreateEGLContext()/ 第一步:獲得或者創(chuàng)建一個可以用于 OpenGL ES 輸出的 EGLNativeWindowType eglWindow = (EGLNativeWindowType)g_pThis;/ 第 二 步 : 獲 得 默 認 的 Display 。 通 常 我 們 只 有 一 塊 屏 幕 , 參
21、數 傳 EGL_DEFAULT_DISPLAY 就可以了。eglDisplay = eglGetDisplay(EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);/第三步:初始化 EGL ,如果我們不想要版本號,后兩個參數也可以傳NULL 進去。EGLint iMajorVersion, iMinorVersion;if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)return false;/第四步:指定需要的配置屬性,一個EGL 的配置描述了 Surfaces 上像素的格式信息。當前
22、我們要的是 Windows的surface,在屏幕上是可見的,以EGL_NONE結尾。const EGLint pi32ConfigAttribs =EGL_LEVEL, 0,EGL_SURFACE_TYPE, EGL_WINDOW_BIT,EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,EGL_NATIVE_RENDERABLE, EGL_FALSE,EGL_DEPTH_SIZE, EGL_DONT_CARE,EGL_NONE;/第五步:尋找一個符合所有要求的配置,我們需要的只是其中一個,所以可以限制 config 的個數為 1。int iConfigs;if
23、 (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) | (iConfigs != 1)return false;pbuffers 都是不可見的。eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL);if(eglSurface = EGL_NO_SURFACE)eglGetError(); / Clear erroreglSurface = eglCreateWindowSurface(eglDisp
24、lay, eglConfig, NULL, NULL);if (!TestEGLError()return false;/第七步:創(chuàng)建 Co ntext。我們Ope nGL ES的資源,比如紋理只有在這個con text里是可見的。/綁定API (可以是 OpenGLES或者 OpenVG) eglBindAPI(EGL_OPENGL_ES_API);EGLint ai32ContextAttribs = EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE ; eglContext = eglCreateContext(eglDisplay, eglConfig,
25、NULL, ai32ContextAttribs);if (!TestEGLError()return false;/第八步:將創(chuàng)建的 context 綁定到當前的線程,使用我們創(chuàng)建的 surface 進行讀和寫。 Con text綁定到線程上,你就可以不用擔心其他的進程影響你的Ope nGL ES應用程序。eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);if (!TestEGLError()return false;return true;bool Render()/第九步:使用 OpenGL ES API 畫一些
26、東西。到這里,所有的東西都已準備就緒,我們 做好了往屏幕上畫東西的準備。bool bRet = false;/單元矩陣,用于投影和模型變換float pfIdentity =1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,0.0f,1.0f ;/ Vertex 和 Fragment 的 shader/ gl_FragColor 指定了最終的像素顏色。/ gl_position 則指定了最終的點在人眼坐標中的位置。char szFragShaderSrc = void main (void)gl_Frag
27、Color = vec4(1.0, 1.0, 0.66 ,1.0); ;char szVertShaderSrc = attribute highp vec4 myVertex;uniform mediump mat4 myPMVMatrix; void main(void)gl_Position = myPMVMatrix * myVertex; ;char * pszFragShader = (char *)szFragShaderSrc;char * pszVertShader = (char *)szVertShaderSrc;GLuint uiFragShader = 0;GLuin
28、t uiVertShader = 0; /* 用來存放 Vertex 和 Fragment shader 的句柄 */GLuint uiProgramObject = 0; /* 用來存放創(chuàng)建的 program 的句柄 */GLint bShaderCompiled;GLint bLinked;/ 我們要畫一個三角形,所以,我們先創(chuàng)建一個頂點緩沖區(qū)GLuint ui32Vbo = 0; / 頂點緩沖區(qū)對象句柄/頂點數據 這 9 個數據分別為 3個點的 X、Y、Z 坐標GLfloat afVertices = -0.4f,-0.4f,0.0f, / Position0.4f ,-0.4f,0.0
29、f,0.0f ,0.4f ,0.0f;int i32InfoLogLength, i32CharsWritten; char* pszInfoLog = NULL;int i32Location = 0; unsigned int uiSize = 0;/創(chuàng)建 Fragment 著色器對象 uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);/ 將代碼加載進來 glShaderSource(uiFragShader, 1, (const char*)&pszFragShader, NULL);/編譯代碼 glCompileShader(uiFra
30、gShader);/看編譯是否成功進行 glGetShaderiv(uiFragShader, GL_COMPILE_STA TUS, &bShaderCompiled);if (!bShaderCompiled)/ 錯誤發(fā)生,首先獲取錯誤的長度 glGetShaderiv(uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); /開辟足夠的空間來存儲錯誤信息pszInfoLog = new chari32InfoLogLength; glGetShaderInfoLog(uiFragShader, i32InfoLogLength, &i3
31、2CharsWritten, pszInfoLog); delete pszInfoLog;goto cleanup;/ 使用同樣的方法加載 Vertex Shader uiVertShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(uiVertShader, 1, (const char*)&pszVertShader, NULL); glCompileShader(uiVertShader);glGetShaderiv(uiVertShader, GL_COMPILE_STA TUS, &bShaderCompiled);if
32、 (!bShaderCompiled) glGetShaderiv(uiVertShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); pszInfoLog = new ari32InfoLogLength;glGetShaderInfoLog(uiVertShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); delete pszInfoLog;goto cleanup;/ 創(chuàng)建著色器程序 uiProgramObject = glCreateProgram();/ 將 Vertex 和 Frag
33、ment Shader 綁定進去。 glAttachShader(uiProgramObject, uiFragShader); glAttachShader(uiProgramObject, uiVertShader);/將用戶自定義的頂點屬性 myVertex 綁定到 VERTEX_ARRAY 。 glBindAttribLocation(uiProgramObject, VERTEX_ARRAY , myVertex);/ 鏈接著色器程序 glLinkProgram(uiProgramObject);/ 判斷鏈接是否成功的操作glGetProgramiv(uiProgramObject,
34、 GL_LINK_STATUS, &bLinked);if (!bLinked)glGetProgramiv(uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); pszInfoLog = new hari32InfoLogLength; glGetProgramInfoLog(uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);delete pszInfoLog;goto cleanup;/ 使用著色器程序glUseProgram(uiProgramObj
35、ect);/ 設置清除顏色,以 RGBA 的模式,每個分量的值從 0.0 到 1.0 glClearColor(0.6f, 0.8f, 1.0f, 1.0f);/生成一個頂點緩沖區(qū)對象glGenBuffers(1, &ui32Vbo);/綁定生成的緩沖區(qū)對象到 GL_ARRAY_BUFFER glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);/ 加載頂點數據uiSize = 3 * (sizeof(GLfloat) * 3); / Calc afVertices size (3 vertices * stride (3 GLfloats per vertex)glB
36、ufferData(GL_ARRAY_BUFFER, uiSize, afV ertices, GL_STATIC_DRAW);/ 畫三角形/清除顏色緩沖區(qū)。 glClear 同樣也能清除深度緩沖區(qū) (GL_DEPTH_BUFFER) 和模板 緩沖區(qū) (GL_STENCIL_BUFFER_BIT)glClear(GL_COLOR_BUFFER_BIT);/獲取 myPMVMatrix 在 shader 中的位置i32Location = glGetUniformLocation(uiProgramObject, myPMVMatrix);/傳值給獲取到的位置,也就是將pfIdentity 傳給
37、 myPMVMatrixglUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);/將 VERTEX_ARRAY 置為有效。 glEnableVertexAttribArray(VERTEX_ARRAY);/ 將定點數據傳到 VERTEX_ARRAY glVertexAttribPointer(VERTEX_ARRAY , 3, GL_FLOAT, GL_FALSE, 0, 0);/畫一個三角形。 glDrawArrays(GL_TRIANGLES, 0, 3);/SwapBuffers 。就可以將三角形顯示出來 eglSwapBuff
38、ers(eglDisplay, eglSurface);bRet = true;cleanup:/ 釋放資源 if (uiProgramObject) glDeleteProgram(uiProgramObject);if (uiFragShader) glDeleteShader(uiFragShader);if (uiVertShader) glDeleteShader(uiVertShader);/ Delete the VBO as it is no longer neededif (ui32Vbo) glDeleteBuffers(1, &ui32Vbo);return bRet;bool DestroyEGLContext()/第十步:結束 OpenGL ES 并刪除創(chuàng)建的 Windows (如果存在的話) .eglminate 已經負 責清除con tex
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年公司年會老板致辭范文(17篇)
- 涉外購貨合同(3篇)
- 設計車輛出入口流量與停車位布局方案
- 2024-2025學年四川省九校高二上學期12月聯(lián)考歷史試卷
- 2025年協(xié)作資金合同解析
- 2025年中小型企業(yè)品牌共建合作協(xié)議書
- 2025年專利權許可與技術轉移合同分析
- 2025年住宅裝飾施工合同
- 2025年企業(yè)流動資金貸款償還協(xié)議合同
- 2025年城市規(guī)劃策劃合作發(fā)展協(xié)議
- 2025年一種板式過濾膜裝置項目投資可行性研究分析報告
- BMS基礎知識培訓
- 質保管理制度
- 2024年全國卷新課標1高考英語試題及答案
- 2024年10月自考13003數據結構與算法試題及答案
- 華為經營管理-華為激勵機制(6版)
- 2024年標準化工地建設管理實施細則(3篇)
- 干燥綜合征診斷及治療指南
- 糧油廠食品安全培訓
- 南京信息工程大學《教師領導力》2022-2023學年第一學期期末試卷
- 電力基本知識培訓課件
評論
0/150
提交評論