第一步:設置所須要的OpenGL環境
設置上下文環境
刪除已經存在的渲染的緩存
設置顏色緩存
設置幀緩存
清除緩存
設置窗口大小
開啓功能
編譯shander
使用program
獲取shader中的屬性和uniform索引數組
第二步:繪製圖片
獲取圖片數據而且的到對應的紋理id
指定紋理,綁定紋理
開始對圖形進行渲染
(
啓用頂點屬性數組紋理座標,將紋理座標傳遞到shader中
啓用頂點屬性數組頂點座標,將頂點座標傳遞到shader中
啓用索引數組
開始繪製
)
解綁紋理xcode
此次實現的過程有些艱難啊,走了不少的彎路,不過也所以學到蠻多的,本身寫的怎麼都運行不了,可是在別人的基礎上運行就不行,其中錯誤的地方有:1.紋理的數據錯誤,使用png的庫失敗;2.繪製函數的參數錯誤;3.使用新版本的glsl語言版本,可是xcode並不支持,並不熟悉期間的語言版本迭代;緩存
實現代碼:函數
#include "SOIL.h" static void error_callback(int error, const char* description) { fprintf(stderr, "Error: %s\n", description); } int main(void) { GLFWwindow* window; glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); if (!window) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); glfwSwapInterval(1); glViewport(0, 0, 640, 480); bool ret = getImageData("/Users/staff/Desktop/Moni/Moni/wall.png"); if (!ret) { cout << "get iamge data is failed." << endl; } else { cout << "get iamge data is success." << endl; //測試圖片數據 // FILE * file; // file = fopen("/Users/staff/Desktop/abc.png","wb"); // if (file) // { // fwrite(_sp_image_data.getBytes(),1,_sp_image_data.getSize(), file); // } // fclose(file); } // 第一行和第三行不是嚴格必須的,默認使用GL_TEXTURE0做爲當前激活的紋理單元 /** * GL_TEXTURE_2D表示操做2D紋理 * 建立紋理對象, * 綁定紋理對象, */ glPixelStorei(GL_UNPACK_ALIGNMENT, 8); glGenTextures(1, &_sp_textureID); glBindTexture(GL_TEXTURE_2D, _sp_textureID); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); // glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); /** * 將圖像數據傳遞給到GL_TEXTURE_2D中, 因其於textureID紋理對象已經綁定,因此即傳遞給了textureID紋理對象中。 * glTexImage2d會將圖像數據從CPU內存經過PCIE上傳到GPU內存。 * 不使用PBO時它是一個阻塞CPU的函數,數據量大會卡 */ // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _sp_image_size.getX(), _sp_image_size.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, _sp_image_data.getBytes()); // glGenerateMipmap(GL_TEXTURE_2D); int width, height; unsigned char* image = SOIL_load_image("/Users/staff/Desktop/fgh/fgh/wall.jpg", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); _vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(_vertexShader, 1, &CCPositionTextureColorVert, NULL); glCompileShader(_vertexShader); GLint status; glGetShaderiv(_vertexShader, GL_COMPILE_STATUS, &status); if (!status) { GLint infoLen = 0; glGetShaderiv(_vertexShader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen)); glGetShaderInfoLog(_vertexShader, infoLen, NULL, infoLog); cout << "compile vert shader wrong..." << infoLog << endl; } } else { cout << "compile vert shader success..." << endl; } _fragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(_fragShader, 1, &CCPositionTextureColorFrag, NULL); glCompileShader(_fragShader); glGetShaderiv(_fragShader, GL_COMPILE_STATUS, &status); if (!status) { GLint infoLen = 0; glGetShaderiv(_fragShader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen)); glGetShaderInfoLog(_fragShader, infoLen, NULL, infoLog); cout << "compile frag shader wrong..." << infoLog << endl; } } else { cout << "compile vert frag success..." << endl; } _program = glCreateProgram(); glAttachShader(_program, _vertexShader); glAttachShader(_program, _fragShader); glLinkProgram(_program); glGetProgramiv(_program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint infoLen = 0; glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen)); glGetProgramInfoLog(_program, infoLen, NULL, infoLog); cout << "link program wrong..." << infoLog << endl; } } else { cout << "the program link success." << endl; } //設置頂點數據(和緩衝)和屬性指針 GLfloat vertices[] = { // Positions // Colors // Texture Coords 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 0.1f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.8f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.8f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.1f }; GLuint indices[] = { 0, 1, 3, 1, 2, 3 }; GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); GLuint _positionSlot = glGetAttribLocation(_program, "position"); GLuint _colorSlot = glGetAttribLocation(_program, "color"); GLuint _textureCoordsSlot = glGetAttribLocation(_program, "texCoord"); //GLuint _textureSlot = glGetUniformLocation(shader.program, "ourTexture"); glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(_positionSlot); glVertexAttribPointer(_colorSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(_colorSlot); glVertexAttribPointer(_textureCoordsSlot, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(_textureCoordsSlot); glBindVertexArray(0); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); //use glUseProgram(_program); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _sp_textureID); // 綁定,便可從_textureID中取出圖像數據 glUniform1i(glGetUniformLocation(_program, "ourTexture1"), 0); //draw glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); glfwPollEvents(); glfwSwapBuffers(window); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }
上面是主程序的代碼,除了這個,還須要頂點shader和片元shader;其實這裏有個坑,就是glsl的語言版本,越望越後面,增長了更多的新 功能,致使我不認識,從而使用了新版本的,同時xcode只更新了到了2.0上,其餘版本在xcode並不能使用,所以導編編譯失敗。測試
const char* CCPositionTextureColorVert = STRINGIFY( attribute vec3 position; attribute vec3 color; attribute vec2 texCoord; varying vec3 ourColor; varying vec2 TexCoord; void main() { gl_Position = vec4(position, 1.0); ourColor = color; TexCoord = texCoord; } );
const char* CCPositionTextureColorFrag = STRINGIFY( varying vec3 ourColor; varying vec2 TexCoord; //varying vec4 color; uniform sampler2D ourTexture1; uniform sampler2D ourTexture2; uniform float mixValue; void main() { gl_FragColor = mix(texture2D(ourTexture1, TexCoord) * vec4(ourColor, 1.0), texture2D(ourTexture2, vec2(-TexCoord.x, TexCoord.y)), mixValue); } );