OPENGL 紋理練習
阿新 • • 發佈:2019-02-01
#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include <glad\glad.h> #include <GLFW\glfw3.h> #include <iostream> const unsigned int WINDOW_WIDTH = 800; const unsigned int WINDOW_HEIGHT = 600; //位置 顏色 文理座標 const char* vertexSource = "#version 330 core\n" "layout(location = 0) in vec3 aPos;\n" "layout(location = 1) in vec3 aColor;\n" "layout(location = 2) in vec2 aTexCoord;\n" "out vec3 ourColor;\n" "out vec2 TexCoord;\n" "void main(){\n" "gl_Position = vec4(aPos, 1.0);\n" "ourColor = aColor;\n" "TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "}\n\0" ; //GLSL內建自帶的取樣器 const char* fragmentSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec3 ourColor;\n" "in vec2 TexCoord;\n" "uniform sampler2D texture1;\n" "void main(){\n" "FragColor = texture(texture1, TexCoord);\n" "}\n\0" ; void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow *window); int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X #endif GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Zhongqi", NULL, NULL); if (window == NULL) { std::cout << "Create Window Failed\n" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { return -1; } //建立頂點著色器 int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "Compile Vertex Error :" << infoLog << std::endl; } //建立片段著色器 int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "Compile Fragment Eror :" << infoLog << std::endl; } //建立著色器程式 unsigned int shaderPrograme = glCreateProgram(); glAttachShader(shaderPrograme, vertexShader); glAttachShader(shaderPrograme, fragmentShader); glLinkProgram(shaderPrograme); glGetProgramiv(shaderPrograme, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderPrograme, 512, NULL, infoLog); std::cout << "Link Programe Error\n" << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); //建立頂點資料 float firstTrangles[] = { //座標 顏色 紋理座標 //top left -0.5f,0.5f,0.0f, 1.0f,0.0f,0.0f, 0.0f,1.0f, //top right 0.5f,0.5f,0.0f, 0.0f,1.0f,0.0f, 1.0f,1.0f, //bottom left -0.5f,-0.5f,0.0f, 0.0f,0.0f,1.0f, 0.0f,0.0f, //bottom right 0.5f,-0.5f,0.0f, 1.0f,1.0f,0.0f, 1.0f,0.0f }; //建立索引資料 unsigned int indexes[] = { 0,1,3, 0,2,3 }; //建立VAO VBO EBO unsigned int VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(firstTrangles), firstTrangles, GL_STATIC_DRAW); //設定EBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW); //屬性指標 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(0)); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); //製作紋理 unsigned int firstTexTure; glGenTextures(1, &firstTexTure); glBindTexture(GL_TEXTURE_2D, firstTexTure); /*紋理環繞方式設定為GL_MIRRORED_REPEAT*/ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); /*紋理過濾設定 放大的時候臨近過濾 縮小的時候線性過濾*/ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //載入影象檔案 製作紋理 int texture_width, texture_height, mChannels; unsigned char* data = stbi_load("container.jpg", &texture_width, &texture_height, &mChannels, 0); //用影象資料生成紋理 if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed Load Image\n" << std::endl; } //釋放圖形記憶體 stbi_image_free(data); //渲染 while (!glfwWindowShouldClose(window)) { processInput(window); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, firstTexTure); glUseProgram(shaderPrograme); glBindVertexArray(VAO); //呼叫glDrawElements之前繫結紋理,它會自動把紋理賦值給片段著色器的取樣器: glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); // glfw: terminate, clearing all previously allocated GLFW resources. // ------------------------------------------------------------------ glfwTerminate(); return 0; } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }
效果圖