运行环境我是直接跟着learn opengl里面的教程搞了,cmake编译一下,用VS2019(2017之类的同理)。在绘制三角形教程的基础上,主要注意修改一下顶点渲染器和片段渲染器里面的变量。
shader.cpp等不用动,这一部分是用来编译渲染器代码的。
给出需要修改的代码,在代码中给出注释进行对应学习也不错哈哈
1.主程序 main.cpp
// Include standard headers #include <stdio.h> #include <stdlib.h> #include <iostream> // Include GLEW #include <GL/glew.h> // Include GLFW #include <GLFW/glfw3.h> GLFWwindow* window; // Include GLM #include <glm/glm.hpp> using namespace glm; #include <common/shader.hpp> // 需要下载这个图像加载库! #define STB_IMAGE_IMPLEMENTATION #include "common/stb_image.h" int main( void ) { // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); getchar(); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Open a window and create its OpenGL context window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", NULL, NULL); if( window == NULL ){ fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" ); getchar(); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); getchar(); glfwTerminate(); return -1; } // Ensure we can capture the escape key being pressed below glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // Create and compile our GLSL program from the shaders GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" ); // 应用纹理 GLfloat vertices[] = { // ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下 -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上 }; // 索引 这里要学习一下EBO方面的内容 unsigned int indices[] = { 0, 1, 3, // 第一个三角形 1, 2, 3 // 第二个三角形 }; unsigned int 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); // 属性 // 顶点 glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(0 * sizeof(GLfloat))); glEnableVertexAttribArray(0); // 颜色 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // 纹理坐标 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO // 生成纹理 // 输入生成纹理的数量,然后把它们储存在第二个参数的GLuint数组中 //(我们的例子中只是一个单独的GLuint) GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture);// 绑定它,让之后任何的纹理指令都可以配置当前绑定的纹理 // 纹理环绕方式 有默认的行为 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 多级纹理 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 加载图片 int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // 一定要注意路径!否则绘制出来是黑色,但运行不会给出报错 unsigned char *data = stbi_load("C:/Users/Administrator/Desktop/container.jpg", &width, &height, &nrChannels, 0); // 手动进行加载检测,如果没什么东西就打印提示 if (data) { std::cout << "load pic success..." << std::endl; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "load error, check your pic_path..." << std::endl; } stbi_image_free(data); glBindTexture(GL_TEXTURE_2D, 0); do{ // Clear the screen glClear( GL_COLOR_BUFFER_BIT ); // 绑定纹理坐标和纹理单元 // 它会自动把纹理赋值给片段着色器的采样器 glBindTexture(GL_TEXTURE_2D, texture); // Use our shader glUseProgram(programID); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); // Draw the triangle ! //glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle //glDisableVertexAttribArray(0); // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ); // Cleanup VBO glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glDeleteVertexArrays(1, &VAO); glDeleteProgram(programID); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; }2.顶点渲染器
#version 330 core // 这里的location对应的属性里面的第一个数,对应好即可将变量关联过来 // Input vertex data, different for all executions of this shader. layout (location = 0) in vec3 vertexPosition_modelspace; layout (location = 1) in vec3 color; layout (location = 2) in vec2 texCoord; out vec3 ourColor; out vec2 TexCoord; void main(){ gl_Position.xyz = vertexPosition_modelspace; gl_Position.w = 1.0; ourColor = color; TexCoord = texCoord; }3.片段渲染器
#version 330 core in vec3 ourColor; in vec2 TexCoord; // Ouput data out vec4 color; //out vec4 FragColor; // 把纹理对象传给片段着色器 uniform sampler2D ourTexture; void main() { // Output color = red color = texture(ourTexture, TexCoord); //FragColor = texture(ourTexture, TexCoord); }效果
避坑:
加载图片要把路径写全,不然是黑色的,后来我加上检查才发现过来的是空指针,耽误了半晚上。 待办 立体物体的贴图探索位姿估计中训练数据的采样方式,设置虚拟相机进行数据渲染1.Docs » 入门 » 纹理 2.OpenGL之纹理贴图(Texture)
2020.10.05
每天看世界都还是美丽的,那晚上为什么还是会觉得寒冷饥饿呢…
