青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

黎明的剔透里伸出了你沁清的曖昧

Graphics|EngineDev|GameDev|2D&3D Art

  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  60 隨筆 :: 1 文章 :: 18 評(píng)論 :: 0 Trackbacks

        OpenGL拋棄glEnable(),glColor(),glVertex(),glEnable()這一套流程的函數(shù)和管線以后,就需要一種新的方法來(lái)傳遞數(shù)據(jù)到Graphics Card來(lái)渲染幾何體,我們可以用VBO, 在3+版本我們可以使用Vertex Array Object-VAO,VAO是一個(gè)對(duì)象,其中包含一個(gè)或者更多的Vertex Buffer Objects。而VBO是Graphics Card中的一個(gè)內(nèi)存緩沖區(qū),用來(lái)保存頂點(diǎn)信息,顏色信息,法線信息,紋理坐標(biāo)信息和索引信息等等。

       VAO在Graphics Card線性的存儲(chǔ)幾個(gè)對(duì)象信息,替代了以前發(fā)送我們需要的數(shù)據(jù)到Graphics Card上,這也是Direct3D沒(méi)有立即模式情況下工作的方法,這就意味著應(yīng)用程序不需要傳輸數(shù)據(jù)到Graphics Card上而得到較高的性能。

 

Coding:

unsigned int vaoID[1]; // Our Vertex Array Object

 unsigned int vboID[1]; // Our Vertex Buffer Object

 

float* vertices = new float[18]; // Vertices for our square

 
 最后不能忘記

delete [] vertices; // Delete our vertices from memory

 

現(xiàn)在要填充頂點(diǎn)的數(shù)據(jù)值,把所有頂點(diǎn)的Z軸值設(shè)置為0,正方形的邊長(zhǎng)為1,左上角(-0.5, 0.5, 0.0),右下角(0.5,-0.5, 0.0):

image

/** 
createSquare is used to create the Vertex Array Object which will hold our square. We will 
be hard coding in the vertices for the square, which will be done in this method. 
*/  
void OpenGLContext::createSquare(void) {  
float* vertices = new float[18];  // Vertices for our square  
  
vertices[0] = -0.5; vertices[1] = -0.5; vertices[2] = 0.0; // 左下  1
vertices[3] = -0.5; vertices[4] = 0.5; vertices[5] = 0.0;  // 左上  2 
vertices[6] = 0.5; vertices[7] = 0.5; vertices[8] = 0.0;   // 右上  3
  
vertices[9] = 0.5; vertices[10] = -0.5; vertices[11] = 0.0; // 右下 4 
vertices[12] = -0.5; vertices[13] = -0.5; vertices[14] = 0.0; //左下1
vertices[15] = 0.5; vertices[16] = 0.5; vertices[17] = 0.0; // 右上 3  
delete [] vertices; // Delete our vertices from memory  
}

    設(shè)置數(shù)據(jù)以后,我們需要用 glGenVertexArrays 創(chuàng)建一個(gè)Vertex Array Object, 然后使用glBindVertexArray綁定VAO,一旦VAO綁定后,使glGenBuffers 創(chuàng)建一個(gè)Vertex Buffer Object, 當(dāng)然仍然需要使用glBindBuffer綁定VBO;

    順序如下:

    1. Generate Vertex Array Object
    2. Bind Vertex Array Object
    3. Generate Vertex Buffer Object
    4. Bind Vertex Buffer Object

   下面要使用glBufferData來(lái)初始化和用剛VAO創(chuàng)建的數(shù)據(jù)分配數(shù)據(jù)給VBO,再告訴VBO的數(shù)據(jù)是從VAO而來(lái),需要清理Vertex Attributr Array和Vertex Array Object.

glGenVertexArrays(1, &vaoID[0]); // Create our Vertex Array Object  
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object so we can use it  
  
glGenBuffers(1, vboID); // Generate our Vertex Buffer Object  
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]); // Bind our Vertex Buffer Object  
glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW  
  
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer  
  
glEnableVertexAttribArray(0); // Disable our Vertex Array Object  
glBindVertexArray(0); // Disable our Vertex Buffer Object  
  
delete [] vertices; // Delete our vertices from memory

繪制:

glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object  
  
glDrawArrays(GL_TRIANGLES, 0, 6); // Draw our square  
  
glBindVertexArray(0); // Unbind our Vertex Array Object

主要使用API:

void glGenVertexArrays(GLSize n, GLuint * *arrays);

返回n個(gè)當(dāng)前未使用的名字,用作數(shù)組arrays中的頂點(diǎn)數(shù)組對(duì)象,

創(chuàng)建了VAO以后,需要初始化新的對(duì)象,并且把要使用的頂點(diǎn)數(shù)組數(shù)據(jù)的對(duì)象的集合與單個(gè)已分配的對(duì)象關(guān)聯(lián)起來(lái),

GLvoid glBingVertexArray(GLuint array);

glBingVertexArray做了三件事,當(dāng)使用的值array 不是零并且是從glGenVertexArrays()返回的值時(shí),創(chuàng)建一個(gè)新的VAO,,并且分配該名字;當(dāng)綁定到之前創(chuàng)建的一個(gè)VAO的時(shí)候,該VAO就是當(dāng)前活動(dòng)的;當(dāng)綁定到一個(gè)為0的數(shù)組時(shí),就停止使用VAO,并且返回頂點(diǎn)數(shù)組的默認(rèn)狀態(tài)。

如果array不是之前從glGenVertexArray返回的值,如果是glDeleteVertexArray()已經(jīng)釋放的值,如果調(diào)用任何一個(gè)gl*Pointer()函數(shù)來(lái)指定一個(gè)頂點(diǎn)數(shù)組,而在綁定一個(gè)非0VAO的時(shí)候,它沒(méi)有和緩沖區(qū)對(duì)象關(guān)聯(lián)起來(lái),將會(huì)返回GL_INVALID_OPERATION錯(cuò)誤。

這個(gè)函數(shù)是綁定VAO到上下文,并沒(méi)有像glBindBuffer那樣take a target。

void glVertexAttribPointer()

 首先要清楚關(guān)聯(lián)a buffer object和 a vertex attribute并不發(fā)生在glBindBuffer(GL_ARRAY_BUFFER),而是發(fā)生在glVertexAttribPointer();當(dāng)你調(diào)用glVertexAttribPointer() ,OpenGL 獲取緩沖區(qū)綁定到GL_ARRAY_BUFFER 并且關(guān)聯(lián)頂點(diǎn)屬性,想象一下GL_ARRAY_BUFFER就像一個(gè)全局指針。

void glDrawArrays(GLenum type ,GLint start, GLint count);

ArrayDraw的方式:

void glDrawArrays(GLenum type, GLint start, GLint count)
{
    for(GLint element = start; element < start + count; element++)
    {
        VertexShader(positionAttribArray[element], colorAttribArray[element]);
    }
}

 

void glDrawElements(GLenum type, GLint count, GLenum type, GLsizeiptr indices)

Indexed Draw 的方式:

 

GLvoid *elementArray;

void glDrawElements(GLenum type, GLint count, GLenum type, GLsizeiptr indices)
{
    GLtype *ourElementArray = (type*)((GLbyte *)elementArray + indices);

    for(GLint elementIndex = 0; elementIndex < count; elementIndex++)
    {
        GLint element = ourElementArray[elementIndex];
        VertexShader(positionAttribArray[element], colorAttribArray[element]);
    }
}

假設(shè)頂點(diǎn)屬性是:
  Position Array:  Pos0, Pos1, Pos2, Pos3
  Color     Array:   Clr0,  Clr1,  Clr2,   Clr3

可以使用這些頂點(diǎn)數(shù)據(jù)以arraydraw的方式先繪制一個(gè)三角形,在繪制另外一個(gè)三角形(start=0,count=2),而如果使用index draw使用這個(gè)四個(gè)頂點(diǎn)能繪制4個(gè)三角行

   Element Array: 0, 1, 2,  0, 2, 3,  0, 3, 1,  1, 2, 3
即:
  (Pos0, Clr0), (Pos1, Clr1), (Pos2, Clr2),
  (Pos0, Clr0), (Pos2, Clr2), (Pos3, Clr3),
  (Pos0, Clr0), (Pos3, Clr3), (Pos1, Clr1),
  (Pos1, Clr1), (Pos2, Clr2), (Pos3, Clr3),

使用index draw需要準(zhǔn)備兩件事:a properly constructed element array ,using a drawing command

Element arrays, 是存儲(chǔ)在buffer object:GL_ELEMENT_ARRAY_BUFFER 用法上是和GL_ARRAY_BUFFER一樣,但是必須要知道indexed drawing is only possible when a buffer object is bound to this binding point, and the element array comes from this buffer object.

so In order to do indexed drawing, we must bind the buffer to GL_ELEMENT_ARRAY_BUFFER and then call glDrawElements

void glDrawElements(GLenum mode,  GLsizei count,   GLenum type,  GLsizeiptr indices);

The first parameter is the same as the first parameter of glDrawArrays.

The count parameter defines how many indices will be pulled from the element array.

The type field defines what the basic type of the indices in the element array are. For example, if the indices are stored as 16-bit unsigned shorts (GLushort), then this field should be GL_UNSIGNED_SHORT. This allows the user the freedom to use whatever size of index they want.GL_UNSIGNED_BYTE and GL_UNSIGNED_INT (32-bit) are also allowed; indices must be unsigned.

The last parameter is the byte-offset into the element array at which the index data begins. Index data (and vertex data, for that matter) should always be aligned to its size. So if we are using 16-bit unsigned shorts for indices, then indices should be an even number.

有一個(gè)實(shí)例:

const int numberOfVertices = 36;

#define RIGHT_EXTENT 0.8f
#define LEFT_EXTENT -RIGHT_EXTENT
#define TOP_EXTENT 0.20f
#define MIDDLE_EXTENT 0.0f
#define BOTTOM_EXTENT -TOP_EXTENT
#define FRONT_EXTENT -1.25f
#define REAR_EXTENT -1.75f

#define GREEN_COLOR 0.75f, 0.75f, 1.0f, 1.0f
#define BLUE_COLOR     0.0f, 0.5f, 0.0f, 1.0f
#define RED_COLOR 1.0f, 0.0f, 0.0f, 1.0f
#define GREY_COLOR 0.8f, 0.8f, 0.8f, 1.0f
#define BROWN_COLOR 0.5f, 0.5f, 0.0f, 1.0f

const float vertexData[] = {
    //Object 1 positions
    LEFT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,
    LEFT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    RIGHT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    RIGHT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,

    LEFT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,
    LEFT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    RIGHT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    RIGHT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,

    LEFT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,
    LEFT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    LEFT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,

    RIGHT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,
    RIGHT_EXTENT,    MIDDLE_EXTENT,    FRONT_EXTENT,
    RIGHT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,

    LEFT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,
    LEFT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,
    RIGHT_EXTENT,    TOP_EXTENT,        REAR_EXTENT,
    RIGHT_EXTENT,    BOTTOM_EXTENT,    REAR_EXTENT,

    //Object 2 positions
    TOP_EXTENT,        RIGHT_EXTENT,    REAR_EXTENT,
    MIDDLE_EXTENT,    RIGHT_EXTENT,    FRONT_EXTENT,
    MIDDLE_EXTENT,    LEFT_EXTENT,    FRONT_EXTENT,
    TOP_EXTENT,        LEFT_EXTENT,    REAR_EXTENT,

    BOTTOM_EXTENT,    RIGHT_EXTENT,    REAR_EXTENT,
    MIDDLE_EXTENT,    RIGHT_EXTENT,    FRONT_EXTENT,
    MIDDLE_EXTENT,    LEFT_EXTENT,    FRONT_EXTENT,
    BOTTOM_EXTENT,    LEFT_EXTENT,    REAR_EXTENT,

    TOP_EXTENT,        RIGHT_EXTENT,    REAR_EXTENT,
    MIDDLE_EXTENT,    RIGHT_EXTENT,    FRONT_EXTENT,
    BOTTOM_EXTENT,    RIGHT_EXTENT,    REAR_EXTENT,
                    
    TOP_EXTENT,        LEFT_EXTENT,    REAR_EXTENT,
    MIDDLE_EXTENT,    LEFT_EXTENT,    FRONT_EXTENT,
    BOTTOM_EXTENT,    LEFT_EXTENT,    REAR_EXTENT,
                    
    BOTTOM_EXTENT,    RIGHT_EXTENT,    REAR_EXTENT,
    TOP_EXTENT,        RIGHT_EXTENT,    REAR_EXTENT,
    TOP_EXTENT,        LEFT_EXTENT,    REAR_EXTENT,
    BOTTOM_EXTENT,    LEFT_EXTENT,    REAR_EXTENT,

    //Object 1 colors
    GREEN_COLOR,
    GREEN_COLOR,
    GREEN_COLOR,
    GREEN_COLOR,

    BLUE_COLOR,
    BLUE_COLOR,
    BLUE_COLOR,
    BLUE_COLOR,

    RED_COLOR,
    RED_COLOR,
    RED_COLOR,

    GREY_COLOR,
    GREY_COLOR,
    GREY_COLOR,

    BROWN_COLOR,
    BROWN_COLOR,
    BROWN_COLOR,
    BROWN_COLOR,

    //Object 2 colors
    RED_COLOR,
    RED_COLOR,
    RED_COLOR,
    RED_COLOR,

    BROWN_COLOR,
    BROWN_COLOR,
    BROWN_COLOR,
    BROWN_COLOR,

    BLUE_COLOR,
    BLUE_COLOR,
    BLUE_COLOR,

    GREEN_COLOR,
    GREEN_COLOR,
    GREEN_COLOR,

    GREY_COLOR,
    GREY_COLOR,
    GREY_COLOR,
    GREY_COLOR,
};

const GLshort indexData[] =
{
    0, 2, 1,
    3, 2, 0,

    4, 5, 6,
    6, 7, 4,

    8, 9, 10,
    11, 13, 12,

    14, 16, 15,
    17, 16, 14,
};

GLuint vertexBufferObject;
GLuint indexBufferObject;

GLuint vaoObject1, vaoObject2;

 

void InitializeVertexBuffer()
{
    glGenBuffers(1, &vertexBufferObject);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &indexBufferObject);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

 

void InitializeVertexArrayObjects()
{
    glGenVertexArrays(1, &vaoObject1);
    glBindVertexArray(vaoObject1);

    size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

    glBindVertexArray(0);

    glGenVertexArrays(1, &vaoObject2);
    glBindVertexArray(vaoObject2);

    size_t posDataOffset = sizeof(float) * 3 * (numberOfVertices/2);
    colorDataOffset += sizeof(float) * 4 * (numberOfVertices/2);

    //Use the same buffer object previously bound to GL_ARRAY_BUFFER.
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)posDataOffset);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

    glBindVertexArray(0);
}

 

Draw:

    glBindVertexArray(vaoObject1);
    glUniform3f(offsetUniform, 0.0f, 0.0f, 0.0f);
    glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

    glBindVertexArray(vaoObject2);
    glUniform3f(offsetUniform, 0.0f, 0.0f, -1.0f);
    glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

    glBindVertexArray(0);

例子:

#include <stdlib.h>
#include <stdio.h>
/* Ensure we are using opengl's core profile only */
#define GL3_PROTOTYPES 1
#include <GL3/gl3.h>
 
#include <SDL.h>
 
#define PROGRAM_NAME "Tutorial2"
 
/* A simple function that will read a file into an allocated char pointer buffer */
char* filetobuf(char *file)
{
    FILE *fptr;
    long length;
    char *buf;
 
    fptr = fopen(file, "rb"); /* Open file for reading */
    if (!fptr) /* Return NULL on failure */
        return NULL;
    fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */
    length = ftell(fptr); /* Find out how many bytes into the file we are */
    buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */
    fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */
    fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */
    fclose(fptr); /* Close the file */
    buf[length] = 0; /* Null terminator */
 
    return buf; /* Return the buffer */
}
 
/* A simple function that prints a message, the error code returned by SDL, and quits the application */
void sdldie(char *msg)
{
    printf("%s: %s\n", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}
 
void setupwindow(SDL_WindowID *window, SDL_GLContext *context)
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) /* Initialize SDL's Video subsystem */
        sdldie("Unable to initialize SDL"); /* Or die on error */
 
    /* Request an opengl 3.2 context.
     * SDL doesn't have the ability to choose which profile at this time of writing,
     * but it should default to the core profile */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
 
    /* Turn on double buffering with a 24bit Z buffer.
     * You may need to change this to 16 or 32 for your system */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
    /* Create our window centered at 512x512 resolution */
    *window = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (!*window) /* Die if creation failed */
        sdldie("Unable to create window");
 
    /* Create our opengl context and attach it to our window */
    *context = SDL_GL_CreateContext(*window);
 
    /* This makes our buffer swap syncronized with the monitor's vertical refresh */
    SDL_GL_SetSwapInterval(1);
}
 
void drawscene(SDL_WindowID window)
{
    int i; /* Simple iterator */
    GLuint vao, vbo[2]; /* Create handles for our Vertex Array Object and two Vertex Buffer Objects */
    int IsCompiled_VS, IsCompiled_FS;
    int IsLinked;
    int maxLength;
    char *vertexInfoLog;
    char *fragmentInfoLog;
    char *shaderProgramInfoLog;
 
    /* We're going to create a simple diamond made from lines */
    const GLfloat diamond[4][2] = {
    {  0.0,  1.0  }, /* Top point */           |
    {  1.0,  0.0  }, /* Right point */         | 
    {  0.0, -1.0  }, /* Bottom point */
    { -1.0,  0.0  } }; /* Left point */
 
    const GLfloat colors[4][3] = {
    {  1.0,  0.0,  0.0  }, /* Red */
    {  0.0,  1.0,  0.0  }, /* Green */
    {  0.0,  0.0,  1.0  }, /* Blue */
    {  1.0,  1.0,  1.0  } }; /* White */
 
    /* These pointers will receive the contents of our shader source code files */
    GLchar *vertexsource, *fragmentsource;
 
    /* These are handles used to reference the shaders */
    GLuint vertexshader, fragmentshader;
 
    /* This is a handle to the shader program */
    GLuint shaderprogram;
 
    /* Allocate and assign a Vertex Array Object to our handle */
    glGenVertexArrays(1, &vao);
 
    /* Bind our Vertex Array Object as the current used object */
    glBindVertexArray(vao);
 
    /* Allocate and assign two Vertex Buffer Objects to our handle */
    glGenBuffers(2, vbo);
 
    /* Bind our first VBO as being the active buffer and storing vertex attributes (coordinates) */
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
 
    /* Copy the vertex data from diamond to our buffer */
    /* 8 * sizeof(GLfloat) is the size of the diamond array, since it contains 8 GLfloat values */
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);
 
    /* Specify that our coordinate data is going into attribute index 0, and contains two floats per vertex */
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
 
    /* Enable attribute index 0 as being used */
    glEnableVertexAttribArray(0);
 
    /* Bind our second VBO as being the active buffer and storing vertex attributes (colors) */
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
 
    /* Copy the color data from colors to our buffer */
    /* 12 * sizeof(GLfloat) is the size of the colors array, since it contains 12 GLfloat values */
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), colors, GL_STATIC_DRAW);
 
    /* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
 
    /* Enable attribute index 1 as being used */
    glEnableVertexAttribArray(1);
 
    /* Read our shaders into the appropriate buffers */
    vertexsource = filetobuf("tutorial2.vert");
    fragmentsource = filetobuf("tutorial2.frag");
 
    /* Create an empty vertex shader handle */
    vertexshader = glCreateShader(GL_VERTEX_SHADER);
 
    /* Send the vertex shader source code to GL */
    /* Note that the source code is NULL character terminated. */
    /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
    glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
 
    /* Compile the vertex shader */
    glCompileShader(vertexshader);
 
    glGetShaderiv(vertexshader, GL_COMPILE_STATUS, &IsCompiled_VS);
    if(IsCompiled_VS == FALSE)
    {
       glGetShaderiv(vertexshader, GL_INFO_LOG_LENGTH, &maxLength);
 
       /* The maxLength includes the NULL character */
       vertexInfoLog = (char *)malloc(maxLength);
 
       glGetShaderInfoLog(vertexshader, maxLength, &maxLength, vertexInfoLog);
 
       /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
       /* In this simple program, we'll just leave */
       free(vertexInfoLog);
       return;
    }
 
    /* Create an empty fragment shader handle */
    fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
 
    /* Send the fragment shader source code to GL */
    /* Note that the source code is NULL character terminated. */
    /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
    glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);
 
    /* Compile the fragment shader */
    glCompileShader(fragmentshader);
 
    glGetShaderiv(fragmentshader, GL_COMPILE_STATUS, &IsCompiled_FS);
    if(IsCompiled_FS == FALSE)
    {
       glGetShaderiv(fragmentshader, GL_INFO_LOG_LENGTH, &maxLength);
 
       /* The maxLength includes the NULL character */
       fragmentInfoLog = (char *)malloc(maxLength);
 
       glGetShaderInfoLog(fragmentshader, maxLength, &maxLength, fragmentInfoLog);
 
       /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
       /* In this simple program, we'll just leave */
       free(fragmentInfoLog);
       return;
    }
 
    /* If we reached this point it means the vertex and fragment shaders compiled and are syntax error free. */
    /* We must link them together to make a GL shader program */
    /* GL shader programs are monolithic. It is a single piece made of 1 vertex shader and 1 fragment shader. */
    /* Assign our program handle a "name" */
    shaderprogram = glCreateProgram();
 
    /* Attach our shaders to our program */
    glAttachShader(shaderprogram, vertexshader);
    glAttachShader(shaderprogram, fragmentshader);
 
    /* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */
    /* Attribute locations must be setup before calling glLinkProgram. */
    glBindAttribLocation(shaderprogram, 0, "in_Position");
    glBindAttribLocation(shaderprogram, 1, "in_Color");
 
    /* Link our program */
    /* At this stage, the vertex and fragment programs are inspected, optimized and a binary code is generated for the shader. */
    /* The binary code is uploaded to the GPU, if there is no error. */
    glLinkProgram(shaderprogram);
 
    /* Again, we must check and make sure that it linked. If it fails, it would mean either there is a mismatch between the vertex */
    /* and fragment shaders. It might be that you have surpassed your GPU's abilities. Perhaps too many ALU operations or */
    /* too many texel fetch instructions or too many interpolators or dynamic loops. */
 
    glGetProgramiv(shaderprogram, GL_LINK_STATUS, (int *)&IsLinked);
    if(IsLinked == FALSE)
    {
       /* Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. */
       glGetProgramiv(shaderprogram, GL_INFO_LOG_LENGTH, &maxLength);
 
       /* The maxLength includes the NULL character */
       shaderProgramInfoLog = (char *)malloc(maxLength);
 
       /* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */
       glGetProgramInfoLog(shaderprogram, maxLength, &maxLength, shaderProgramInfoLog);
 
       /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
       /* In this simple program, we'll just leave */
       free(shaderProgramInfoLog);
       return;
    }
 
    /* Load the shader into the rendering pipeline */
    glUseProgram(shaderprogram);
 
    /* Loop our display increasing the number of shown vertexes each time.
     * Start with 2 vertexes (a line) and increase to 3 (a triangle) and 4 (a diamond) */
    for (i=2; i <= 4; i++)
    {
        /* Make our background black */
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
        /* Invoke glDrawArrays telling that our data is a line loop and we want to draw 2-4 vertexes */
        glDrawArrays(GL_LINE_LOOP, 0, i);
 
        /* Swap our buffers to make our changes visible */
        SDL_GL_SwapWindow(window);
 
        /* Sleep for 2 seconds */
        SDL_Delay(2000);
    }
 
    /* Cleanup all the things we bound and allocated */
    glUseProgram(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDetachShader(shaderprogram, vertexshader);
    glDetachShader(shaderprogram, fragmentshader);
    glDeleteProgram(shaderprogram);
    glDeleteShader(vertexshader);
    glDeleteShader(fragmentshader);
    glDeleteBuffers(2, vbo);
    glDeleteVertexArrays(1, &vao);
    free(vertexsource);
    free(fragmentsource);
}
 
void destroywindow(SDL_WindowID window, SDL_GLContext context)
{
    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();
}
 
/* Our program's entry point */
int main(int argc, char *argv[])
{
    SDL_WindowID mainwindow; /* Our window handle */
    SDL_GLContext maincontext; /* Our opengl context handle */
 
    /* Create our window, opengl context, etc... */
    setupwindow(&mainwindow, &maincontext);
 
    /* Call our function that performs opengl operations */
    drawscene(mainwindow);
 
    /* Delete our opengl context, destroy our window, and shutdown SDL */
    destroywindow(mainwindow, maincontext);
 
    return 0;
}

參考:

VAOs,_VBOs,_Vertex_and_Fragment_Shaders

VAO

opengl-3-3-glsl-1-5-sample

Vertex array object

Open GL : Using Vertex Array Objects to Organize Your Buffers

Vertex Buffer Objects

posted on 2012-02-21 17:42 情絕格調(diào)(fresmaster) 閱讀(17342) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Graphics
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲在线免费| 伊人男人综合视频网| 一区二区三区免费网站| 亚洲黄色免费电影| 欧美理论电影在线播放| 亚洲无玛一区| 欧美一区三区二区在线观看| 狠狠综合久久av一区二区老牛| 久久精品人人爽| 久久综合色一综合色88| 亚洲免费av片| 亚洲伊人伊色伊影伊综合网| 国产香蕉97碰碰久久人人| 欧美chengren| 欧美日韩午夜在线视频| 欧美专区福利在线| 欧美18av| 性高湖久久久久久久久| 久久婷婷国产综合精品青草| 99精品国产在热久久下载| 亚洲一区二区黄色| 亚洲高清在线播放| 国产精品99久久久久久久久久久久| 国产精品美女久久久免费| 麻豆91精品91久久久的内涵| 欧美激情中文字幕乱码免费| 销魂美女一区二区三区视频在线| 久久久无码精品亚洲日韩按摩| 亚洲精品日韩久久| 欧美一区亚洲二区| 亚洲天堂第二页| 久久久蜜臀国产一区二区| 亚洲性视频网站| 麻豆成人在线| 久久精品国产精品亚洲精品| 欧美日本高清视频| 久久综合久久综合久久综合| 欧美午夜精品电影| 欧美激情麻豆| 激情av一区| 亚洲伊人第一页| 亚洲网站在线播放| 欧美激情国产高清| 久久一区二区精品| 国产精品永久免费在线| 亚洲美女尤物影院| 亚洲区国产区| 久久久综合免费视频| 欧美亚洲尤物久久| 欧美午夜一区二区福利视频| 亚洲国产日韩在线一区模特| 影音先锋久久| 久久精品99国产精品日本| 欧美怡红院视频一区二区三区| 欧美日本高清视频| 亚洲欧洲视频| 亚洲激情社区| 久久久av水蜜桃| 久久午夜精品一区二区| 国产一级揄自揄精品视频| 亚洲一区久久久| 午夜在线一区| 国产欧美一区二区三区在线看蜜臀 | 久久精品主播| 久久免费的精品国产v∧| 国产欧美日韩综合一区在线观看| 夜夜嗨av色一区二区不卡| 一区二区高清| 国产精品v欧美精品v日韩| 日韩视频免费观看高清在线视频| 99视频在线观看一区三区| 欧美精品91| 99精品免费网| 亚洲在线观看视频网站| 国产精品免费aⅴ片在线观看| 在线亚洲一区| 久久国产精品久久国产精品| 国产欧美一区二区精品性| 欧美中文在线观看国产| 免费成人你懂的| 91久久精品日日躁夜夜躁欧美| 欧美大秀在线观看| 99re热这里只有精品视频| 欧美在线一级va免费观看| 国产综合18久久久久久| 玖玖精品视频| 日韩视频免费| 欧美在线视频观看| 91久久中文| 国产精品第一页第二页第三页| 亚洲欧美日韩爽爽影院| 狂野欧美性猛交xxxx巴西| 日韩一区二区精品| 国产目拍亚洲精品99久久精品| 久久福利精品| 亚洲日本在线视频观看| 欧美亚洲综合网| 亚洲第一成人在线| 欧美日韩视频在线一区二区| 欧美诱惑福利视频| 日韩亚洲精品在线| 免费不卡视频| 欧美亚洲免费高清在线观看| 亚洲高清久久| 国产免费成人| 欧美日韩一区二区三区在线观看免| 午夜亚洲影视| 日韩午夜av| 欧美96在线丨欧| 久久精品国产亚洲一区二区| 一区二区激情| 亚洲激情国产精品| 黄色资源网久久资源365| 国产精品初高中精品久久| 欧美大片网址| 久热精品视频在线| 久久成人免费电影| 亚洲欧美视频在线观看| 亚洲精选中文字幕| 久久精品一区| 亚洲一二区在线| 红桃视频欧美| 欧美精品一区二区三区蜜臀| 久久久精品网| 亚洲一区在线免费观看| 欧美va天堂va视频va在线| 亚洲欧美日韩精品久久奇米色影视 | 亚洲女性喷水在线观看一区| 国内精品国产成人| 欧美日韩三级| 久久成人精品无人区| 亚洲淫片在线视频| 亚洲激情一区| 免费一级欧美在线大片| 小黄鸭精品密入口导航| 亚洲精品日韩欧美| 亚洲精品欧美精品| 精品动漫3d一区二区三区免费| 国产精品日韩一区| 欧美精品在线一区二区三区| 免费看成人av| 欧美在线91| 久久精品99国产精品| 香蕉av777xxx色综合一区| 亚洲午夜免费视频| av不卡在线看| 亚洲专区欧美专区| 亚洲视频久久| 亚洲香蕉成视频在线观看| 亚洲免费观看| 亚洲一品av免费观看| 一本久道综合久久精品| 91久久国产综合久久91精品网站| 男人的天堂亚洲在线| 欧美一区深夜视频| 美女免费视频一区| 久久综合伊人77777蜜臀| 久久综合福利| 蜜臀久久久99精品久久久久久 | 亚洲视频一区| 亚洲午夜羞羞片| 亚洲一区二区视频在线| 亚洲一区二区三区午夜| 日韩系列在线| 欧美亚洲自偷自偷| 久久黄色级2电影| 久久亚洲精品伦理| 欧美激情一区二区三区在线| 91久久亚洲| 亚洲毛片网站| 亚洲网站在线| 欧美一级电影久久| 欧美区一区二区三区| 国产精品播放| 国产亚洲欧美日韩在线一区| 狠狠v欧美v日韩v亚洲ⅴ| 国产欧美日韩免费看aⅴ视频| 亚洲国产精品久久久久| 一区二区三区精密机械公司| 亚洲欧美日本日韩| 久久久亚洲高清| 99精品久久久| 久久国产一二区| 欧美国产日韩一二三区| 欧美日韩日本视频| 亚洲国产专区校园欧美| 亚洲午夜一级| 欧美国产日韩二区| 亚洲精品在线电影| 久久亚洲捆绑美女| 欧美午夜精品一区| 在线观看视频一区二区欧美日韩 | 欧美久久综合| 国产一区二区三区观看| 亚洲欧美成人一区二区在线电影| 老色鬼精品视频在线观看播放| 亚洲国产欧美国产综合一区| 亚洲欧美中日韩| 欧美日韩在线精品| 亚洲福利免费|