OpenGL開發關於VAO, VBO, EBO的理解,圖形渲染管線流程


  圖形渲染管線指的是對一些原始數據經過一系列的處理變換並最終把這些數據輸出到屏幕上的整個過程。 

  圖形渲染管線的整個處理流程可以被划分為幾個階段,上一個階段的輸出數據作為下一個階段的輸入數據,是一個串行的,面向過程的執行過程。每一個階段分別在GPU上運行各自的數據處理程序,這個程序就是着色器

  部分着色器允許我們使用着色語言(OpenGL Shading Language)編寫自定義的着色器,這樣就可以更為細致的控制圖像渲染流程中的特定處理過程了,下圖是一個圖形渲染管線每一個階段的抽象表示,藍色部分代表允許自定義着色器。

  

 

 

  1. 頂點數據(Verties Data): 頂點的集合,保存在GPU端的數據
  2. 基本圖元(Primitives): 點,線,三角形,等構成實體模型的基本單元類型.需要傳入頂點數據的同時通知OpenGL這些頂點數據要組成的基本圖元類型
  3. 頂點着色器(Vertex Shader): 對一些頂點屬性的基本處理;
  4. 圖元裝配(Shape Assembly): 將頂點數據作為輸入,並處理輸出為基本的圖元
  5. 幾何着色器(Geometry Shader): 把基本圖元形式的頂點作為輸入, 通過產生新的頂點等方式,構造並輸出為其他形狀的基本圖元.
  6. 細分着色器(Tessellation Shader): 把基本圖元細分為更多的基本圖形,創建出更加平滑的視覺效果.
  7. 光柵化(Rasterization): 像素化, 上一步的基本圖形,映射為屏幕網格上的像素點, 生成供着色器處理的片段(Ragment), 同時還有一個裁剪處理, 丟棄掉超出屏幕視圖范圍之外的像素.
  8. 片段着色器(Fragment Shader): 上一步輸出的像素數據, 處理計算出每個像素的點最終的顏色, 通常片段着色器包含3D場景的一些額外數據, 光線,陰影等.
  9. 測試與混合(Tests and Blending): 對上一步輸出的像素進行深度測試, Alpha測試等測試處理,  並進行顏色混合操作, 從而最終決定屏幕視窗(View Window) 上每個像素點的最終顏色以及透明度.  

  在整個渲染管線中需要自定義處理的主要是頂點着色器片段着色器

 

 

一、OpenGL渲染時涉及到的數據傳輸

  1. 准備好需要繪制的頂點數據。(自己定義的或者是從某些模型文件中讀取出來的)
  2. 顯卡的GPU(存儲空間)中開辟一塊內存緩沖區,用於存儲頂點的各類屬性信息(Vertices Attributes 數據,如頂點坐標, 頂點法向量, 頂點顏色等等)。
  3. 將頂點數據傳到上一步開辟的GPU的內存中。
  4. 着色器代碼轉化為着色器程序,並鏈接到當前的執行程序中
  5. GPU根據着色器的邏輯將這塊內存的數據進行計算。(指定該如何將數據發送給顯卡)
  6. 將這塊已經計算完的數據一並發送給顯卡進行渲染繪制

[1] 由於VBO存在於GPU的顯存空間,而不是在內存空間,更不是CPU內的寄存器(更加離譜,哈哈,僅僅是為了擴充對各個硬件的了解深度), 不需要從CPU從內存傳輸數據, 因此處理效率更高.

[2] VBO就是顯存的一個內存區域,可以用來保存大量的頂點屬性信息(Vertices Attribute 信息). 在顯存中可以開辟多個VBO, 每個開辟的VBO對象,在OpenGL中都有一個唯一的ID標識, 這個ID就與 在顯存中開辟的VBO顯存地址一一對應. 通過這個ID,就可以對特定的VBO內的數據進行存取操作

 

二、上述流程中涉及到的內存

 

  1. 根據上面的流程,可知整個數據渲染的流程中,涉及到兩個數據傳輸的流程,一個是將頂點數據(CPU端)傳輸到GPU中的內存、另一個是將GPU中的數據傳輸給顯卡(光柵化處理,顯示)
  2. GPU的內存通過頂點緩沖對象(Vertex Buffer Objects,VBO),也就是VBO來管理這個(GPU)內存,它會在GPU內存(通常被稱為顯存)中儲存大量頂點。
  3. 使用這VBO的好處是我們可以一次性的發送一大批數據到顯卡上,而不是每個頂點發送一次

三、VBO(GPU的頂點緩存對象(Vertex Buffer Objects,VBO))的API調用

1. 創建VBO((Vertex Buffer Objects,VBO))對象,使用glGenBuffer()函數.

  作用:通過GPU開辟(聲明) 顯存空間,並分配一個VBO的唯一ID標識.

 

 
         
GLuint vboId;//vertex buffer object句柄

int
vboId = glGenBuffers();

2. 綁定(激活)該頂點緩存對象

  創建的VBO[實質是唯一ID標識]可用來保存不同類型(GL_ARRAY_Buffer等)的頂點數據,創建之后需要通過分配的ID綁定(bind)一下經過GPU上一步分配(開配)VBO內存.[注意:申請與綁定是異步的,看分開進行實現],

  設置頂點緩沖對象的緩沖類型GL_ARRAY_BUFFER,將創建的vbo的ID標識綁定到 [GPU申請開辟的顯存VBO內存],也可以理解為激活. 使用glBindBuffer()函數.

  VBO的類型枚舉變量: 

  (1)GL_ARRAY_BUFFER

  (2)GL_ELEMENT_ARRAY_BUFFER

  (3)GL_PIXEL_PACK_BUFFER

  (4)GL_PIXEL_UNPACK_BUFFER

glBindBuffer(GL_ARRAY_BUFFER, vboId);

 

3. 將頂點數據傳輸(復制,拷貝)到VBO中

  將用戶准備好的頂點數據[CPU端的頂點數據,實質是內存頂點],復制(傳輸)到該顯存開辟的VBO緩沖內存[注意:該VBO對象已經綁定激活]中。使用glBufferData()函數.

  posBuffer為頂點數據,GL_STATIC_DRAW表示數據不會改變和幾乎不會改變。第三個參數一共有三個選擇:GL_STATIC_DRAW 表示數據不會或幾乎不會改變、GL_DYNAMIC_DRAW表示數據會被改變很多、GL_STREAM_DRAW 表示數據每次繪制時都會改變。

  比如說一個緩沖中的數據將頻繁被改變,那么使用的類型就是GL_DYNAMIC_DRAW或GL_STREAM_DRAW,這樣就能確保顯卡把數據放在能夠高速寫入的內存部分

glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);

 

 

  

4. 在渲染前指定OpenGL該如何解釋VBO(頂點緩存對象)中的vertices數據.,

  模型頂點數據傳輸(拷貝,復制)到GPU管理的顯存VBO空間內后,還需要通知OpenGL如何解釋這些頂點數據

  使用glVertexAttribPointer()函數實現.

glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
  • 第一個參數為頂點着色器中的location的值, layout (location=0) in vec3 position;。
  • 第二個參數為指定頂點屬性的維數(有幾個分量,3:則表示x,y,z),如果是vec3,它由3個值組成,所以大小是3
  • 第三個參數為數據的類型(確定內存中占用長度)
  • 第四個參數為是否希望數據被標准化,如果我們設置為GL_TRUE,所有數據都會被映射到0(對於有符號型signed數據是-1)到1之間。
  • 第五個參數叫步長(Stride),它告訴我們在連續的頂點屬性組之間的間隔。設置為0的意思是讓OpenGL自己去識別步長。
  • 最后一個參數表示位置數據在緩沖中起始位置的偏移量(Offset)。由於位置數據在數組的開頭,所以這里是0。

 四, 渲染VBO內存中的數據相關的API

1. 渲染操作

  執行完上面操作后,則將CPU端的頂點數據 傳輸到GPU端的內存中,並指定GPU如何對這些數據解析的方式.下一步就需要進行渲染.使用函數如下:

glEnableVertexAttribArray(0);//使vbo的內存變為可用狀態。 glUseProgram(shaderProgram);//調用着色器程序。 glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);//繪制方法

 注意:頂點屬性glVertexAttribPointer默認是關閉的,使用時要以頂點屬性位置值為參數調用glEnableVertexAttribArray開啟。如glEnableVertexAttribArray(0);

   

       當一個vbo(頂點緩存對象)中的數據准備完成以后,繪制的過程是需要執行以上 三步,如果程序中只有一種頂點類型的vbo,那倒還好;如果有很多種vbo(在激活vbo時,調用glBindBuffer時是可以選擇很多種類型的),這樣一來,在繪制這些vbo時,就需要重復調用很多次上面的三個步驟。為了簡化這個流程,也減少GPU和顯卡的交互次數,需要改進....

  思考:有沒有一些方法可以使我們把所有這些狀態配置儲存在一個對象中,並且可以通過綁定這個對象來恢復狀態,此時就提出了VAO的概念。

注意:

[1] VAO是一個保存了所有頂點數據屬性的狀態結合,它存儲了頂點數據的格式以及頂點數據所需的VBO對象的引用

[2]VAO本身並沒有存儲頂點的相關屬性數據,這些信息是存儲在VBO中的,VAO相當於是對很多個VBO的引用,把一些VBO組合在一起作為一個對象統一管理。

 

五, VAO[頂點數組對象]的概念,和相關的API

  VAO是頂點數組對象(Vertex Array Object, VAO).可以像VBO頂點緩沖對象那樣被創建綁定(激活)

  當一個VAO被創建綁定之后,任何隨后的頂點屬性調用都會儲存在這個VAO。 這樣一來如果有多個vbo對象,在渲染繪制時,就不用執行很多次前面提到的渲染程序,只需要執行一次綁定的VAO的渲染API即可

1. 創建VAO對象,調用glGenVertexArrays(), 和VBO類似

 

int vaoId = glGenVertexArrays();//創建

 

2. 綁定(激活)VAO對象,調用glBindVertexArray()函數

glBindVertexArray(vaoId);//綁定,激活

注意:

  執行VAO綁定之后, 其后的所有VBO配置都是這個VAO對象的一部分,可以說VBO是對頂點屬性信息的綁定,VAO是對很多個VBO的綁定。

 3.  使用當前激活的着色器進行繪制.

glDrawArrays (GLenum mode, GLint first, GLsizei count)

  OpenGL中所有的圖形都是通過分解成三角形的方式進行繪制,glDrawArrays函數負責把模型繪制出來,它使用當前激活的着色器,當前VAO對象中的VBO頂點數據和屬性配置來繪制出來基本圖形

第一個參數表示繪制的類型,有三種取值:

  • 1.GL_TRIANGLES:每三個頂之間繪制三角形,之間不連接;
  • 2.GL_TRIANGLE_FAN:以V0V1V2,V0V2V3,V0V3V4,……的形式繪制三角形;
  • 3.GL_TRIANGLE_STRIP:順序在每三個頂點之間均繪制三角形。這個方法可以保證從相同的方向上所有三角形均被繪制。以V0V1V2,V1V2V3,V2V3V4……的形式繪制三角形;

第二個參數定義從緩存中的哪一位開始繪制,一般定義為0;

第三個參數定義繪制的頂點數量;

 

4. 渲染VAO對象

glEnableVertexAttribArray(0);
glUseProgram(shaderProgram);
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);

六、索引緩沖對象EBO(Element Buffer Object)

  索引緩沖對象EBO相當於OpenGL中的頂點數組的概念,是為了解決同一個頂點多洗重復調用(效率低)的問題,可以減少內存空間浪費,提高執行效率。當需要使用重復的頂點時,通過頂點的位置索引來調用頂點,而不是對重復的頂點信息重復記錄,重復調用。

 

   EBO中存儲的內容就是頂點位置的索引indices,EBO跟VBO類似,也是在顯存中的一塊內存緩沖器,只不過EBO保存的是頂點的索引

 

1. 創建EBO

  創建EBO並綁定,用glBufferData(以GL_ELEMENT_ARRAY_BUFFER為參數)把索引存儲到EBO中:

 

    GLuint EBOID;
    glGenBuffers(1, &EBOID);

   //綁定(激活),將該EBOID標識,關聯到, GPU所申請的VBO顯存位置 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOID);

  //復制,傳輸,拷貝(將CPU管理的內存中的索引數組, 傳輸到 GPU管理的顯存中申請的EBO位置) glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices), indices, GL_STATIC_DRAW);

 

 2. 繪制基於EBO進行模型繪制 

  當用EBO綁定頂點索引的方式繪制模型時,需要使用glDrawElements而不是glDrawArrays:

 

 

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

 

  • 第一個參數指定了要繪制頂點數據的模式
  • 第二個參數指定要繪制的頂點個數
  • 第三個參數是索引的數據類型
  • 第四個參數是可選的EBO中偏移量設定

 

 

七, VBO和VAO的解綁(注銷)

 

1. VBO解綁(注銷)

 

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

 

2. VAO解綁(注銷)

glDisableVertexAttribArray(0);
glBindVertexArray(0);

 

 八,案例:

(1)第一個例子是使用VBO,VAO繪制一個矩形圖形:

//使用VAO VBO繪制矩形
#include <GL/glew.h>  
#include <GL/freeglut.h>  
 
void userInit();  //自定義初始化
void reshape(int w, int h);   //重繪
void display(void);
void keyboardAction(unsigned char key, int x, int y);   //鍵盤退出事件
 
GLuint vboId;//vertex buffer object VBO標識ID,聲明(GLuint變量), 句柄    
GLuint vaoId;//vertext array object, VAO標識ID聲明(BLUint變量), 句柄    
GLuint programId;//shader program (着色器編程ID標識,GLUint 變量)句柄    
 
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(512, 512);
    glutCreateWindow("Rectangle demo");
 
    //使用glew,需要執行glewInit,不然運行過程會報錯
    //glewInit要放在glut完成了基本的初始化之后執行
    glewInit();
 
    //自定義初始化,生成VAO,VBO對象
    userInit();
 
    //重繪函數
    glutReshapeFunc(reshape);
 
    glutDisplayFunc(display);
 
    //注冊鍵盤按鍵退出事件
    glutKeyboardFunc(keyboardAction);
 
    glutMainLoop();
    return 0;
}
 
//自定義初始化函數    
void userInit()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    //創建頂點數據    
    const GLfloat vertices[] = {
        -0.5f,-0.5f,0.0f,1.0f,
        0.5f,-0.5f,0.0f,1.0f,
        0.5f,0.5f,0.0f,1.0f,
        -0.5f,0.5f,0.0f,1.0f,
    };
 
    //創建VAO對象
    glGenVertexArrays(1, &vaoId);
    glBindVertexArray(vaoId);//綁定(激活,將該VAO 的ID標識關聯到 GPU申請的VOA顯存) //創建VBO對象    
    glGenBuffers(1, &vboId);
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    

  //傳入(賦值,拷貝,傳輸,將CPU端管理的CPU內存中的vertice數據傳輸到GPU端管理的顯存VBO中)VBO數據 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //解除VBO綁定, 操作完成,就需要解除,因為上一條指令,默認只針對當前激活的VBO進行綁定,操作,賦值,傳輸等等 glBindBuffer(GL_ARRAY_BUFFER, 0); } //調整窗口大小回調函數 void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); } //繪制回調函數 void display(void) { glClear(GL_COLOR_BUFFER_BIT); //重新綁定(激活)需要操作的VBO,即將其VBO的標識ID與GPU管理的VBO顯存關聯。 glBindBuffer(GL_ARRAY_BUFFER, vboId); glEnableVertexAttribArray(0);// 默認為關閉狀態,該指令是打開VBO的頂點屬性繪制 //解釋頂點數據方式 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); //繪制模型 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  // 解除,與當前VBO標識的綁定,或將當前VBO操作對象,注銷。方便其他位置的操作(確保,每次只操作當前激活的VBO對象) glBindBuffer(GL_ARRAY_BUFFER,
0); glDisableVertexAttribArray(0);// 還原為默認關閉狀態 glutSwapBuffers(); } //鍵盤按鍵回調函數 void keyboardAction(unsigned char key, int x, int y) { switch (key) { case 033: // Escape key exit(EXIT_SUCCESS); break; } }

 渲染結果:

  

 

 

(2)第二個例子使用EBO繪制兩個三角形,組成同樣的矩形圖形:

//使用EBO繪制矩形(兩個三角形)
#include <GL/glew.h>  
#include <GL/freeglut.h>  
 
void userInit();  //自定義初始化
void reshape(int w, int h);   //重繪
void display(void);
void keyboardAction(unsigned char key, int x, int y);   //鍵盤退出事件
 
GLuint eboId;//(聲明EBO,索引緩存對象,標識ID)element buffer object句柄    
GLuint vboId;//(聲明VBO,頂點緩存對象,標識ID)vertext buffer object句柄    
GLuint vaoId;//(聲明VAO,頂點數組對象, 標識ID)vertext array object句柄    
 
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(512, 512);
    glutCreateWindow("Rectangle demo");
 
    //使用glew,需要執行glewInit,不然運行過程會報錯
    //glewInit要放在glut完成了基本的初始化之后執行
    glewInit();
 
    //自定義初始化,生成VAO,VBO,EBO
    userInit();
 
    //重繪函數
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    //注冊鍵盤按鍵退出事件
    glutKeyboardFunc(keyboardAction);
    glutMainLoop();
    return 0;
}
 
//自定義初始化函數    
void userInit()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
 
  //CPU 端, 在內存中形成用於表征模型的vertices頂點數組數據,后續用於傳輸(發送,拷貝)給GPU管理的顯存VBO對象。
//創建頂點數據 const GLfloat vertices[] = { -0.5f,-0.5f,0.0f,1.0f, 0.5f,-0.5f,0.0f,1.0f, 0.5f,0.5f,0.0f,1.0f, -0.5f,0.5f,0.0f,1.0f, };
  // CPU 端, 在內存中形成 vertices頂點數組,對應的索引ID數據,(用於傳輸,拷貝,發送,給GPU端管理的EBO顯存)
// 索引數據 GLshort indices[] = { 0, 1, 3, // 第一個三角形 1, 2, 3 // 第二個三角形 }; //創建VAO對象 glGenVertexArrays(1, &vaoId); glBindVertexArray(vaoId);// 綁定(激活),實質是建立於GPU端開辟的VAO對象的關聯,影響:當前vaoid的VAO是活動狀態
              //可直接對其進行傳輸,或者操作。
//創建VBO對象,把頂點數組復制(傳輸,拷貝)到一個GPU管理的顯存中當前活動的VBO頂點緩沖中(實質就是vboid),供OpenGL使用 glGenBuffers(1, &vboId); glBindBuffer(GL_ARRAY_BUFFER, vboId); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //創建EBO對象 glGenBuffers(1, &eboId); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId); //傳入EBO數據 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //解釋頂點數據方式 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0);//GPU端開啟,采用opengl的顯存頂點屬性操作 //解綁VAO glBindVertexArray(0); //解綁EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //解綁VBO glBindBuffer(GL_ARRAY_BUFFER, 0); } //調整窗口大小回調函數 void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); } //繪制回調函數 void display(void) { glClear(GL_COLOR_BUFFER_BIT); //綁定VAO glBindVertexArray(vaoId); //繪制模型 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL); glutSwapBuffers(); } //鍵盤按鍵回調函數 void keyboardAction(unsigned char key, int x, int y) { switch (key) { case 033: // Escape key exit(EXIT_SUCCESS); break; } }

 

 

 

 顯卡-GPU-CUDA之間的關系

1.  什么是顯卡?

顯卡(Video card,Graphics card)全稱顯示接口卡,又稱顯示適配器,是計算機最基本配置、最重要的配件之一。就像電腦聯網需要網卡,主機里的數據要顯示在屏幕上就需要顯卡。因此, 顯卡是電腦進行數模信號轉換的設備,承擔輸出顯示圖形的任務。具體來說, 顯卡接在電腦主板上,它將電腦的數字信號轉換成模擬信號讓顯示器顯示出來

 2. 什么是GPU?

GPU這個概念是由Nvidia公司於1999年提出的。GPU是顯卡上的一塊芯片,就像CPU是主板上的一塊芯片。那么1999年之前顯卡上就沒有GPU嗎?當然有,只不過那時候沒有人給它命名,也沒有引起人們足夠的重視,發展比較慢。

 

自Nvidia提出GPU這個概念后,GPU就進入了快速發展時期。簡單來說,其經過了以下幾個階段的發展:

1)僅用於圖形渲染,此功能是GPU的初衷,這一點從它的名字就可以看出:Graphic Processing Unit,圖形處理單元;

2)后來人們發現,GPU這么一個強大的器件只用於圖形處理太浪費了,它應該用來做更多的工作,例如浮點運算。怎么做呢?直接把浮點運算交給GPU是做不到的,因為它只能用於圖形處理(那個時候)。最容易想到的,是浮點運算做一些處理,包裝成圖形渲染任務,然后交給GPU來做。這就是GPGPU(General Purpose GPU)的概念。不過這樣做有一個缺點,就是你必須有一定的圖形學知識,否則你不知道如何包裝。

3)於是,為了讓不懂圖形學知識的人也能體驗到GPU運算的強大,Nvidia公司又提出了CUDA的概念。

3. 什么是CUDA?

 

CUDA(Compute Unified Device Architecture),通用並行計算架構,是一種運算平台。它包含CUDA指令集架構以及GPU內部的並行計算引擎。你只要使用一種類似於C語言的CUDA C語言,就可以開發CUDA程序,從而可以更加方便的利用GPU強大的計算能力,而不是像以前那樣先將計算任務包裝成圖形渲染任務,再交由GPU處理。

注意,並不是所有GPU都支持CUDA。

4. CPU和GPU的關系

在沒有GPU之前,基本上所有的任務都是交給CPU來做的。有GPU之后,二者就進行了分工,CPU負責邏輯性強的事物處理和串行計算,GPU則專注於執行高度線程化的並行處理任務(大規模計算任務)。為什么這么分工?這是由二者的硬件構成決定的。

可以看出,CPU是“主(host)”而GPU是“從(device)”,GPU無論發展得多快,都只能是替CPU分擔工作,而不是取代CPU。

附1:獨立顯卡和集成顯卡的區別。

所謂集成,是指顯卡集成在主板上,不能隨意更換。而獨立顯卡是作為一個獨立的器件插在主板的AGP接口上的,可以隨時更換升級。

另外,集成顯卡使用物理內存,而獨立顯卡有自己的顯存。一般而言,同期推出的獨立顯卡的性能和速度要比集成顯卡好、快。

值得一提的是,集成顯卡和獨立顯卡都是有GPU的

 

附2:Nvidia顯卡分類。

GeForce系列:家庭娛樂。打游戲必備;

Quadro系列:專業繪圖設計。視頻渲染,經常使用3ds Max、Maya等軟件的必備。

Tesla系列:高端顯卡,用於大規模的並行計算。土豪必備。

 

 三、

 

 

 

 

 

 

 

 

 

 

 

 

 

參考博客:

  https://blog.csdn.net/weixin_30735745/article/details/95616490?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control

  https://blog.csdn.net/xyh930929/article/details/83352645


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM