手动生成 mipmap

Posted

技术标签:

【中文标题】手动生成 mipmap【英文标题】:Generating mipmaps manually 【发布时间】:2017-03-04 13:21:12 【问题描述】:

原帖: https://computergraphics.stackexchange.com/questions/4793/how-can-i-generate-mipmaps-manually 这是一个愚蠢的错误,我忘记设置所有纹理坐标:P

OpenGL 相当难学。 根据我对 mipmap 的理解,我可以手动设置每个 mipmap 级别,这样我就可以在纹理看起来更大或更小的时候更改要使用的图像。

我尝试了以下代码,但三角形的大小无关紧要,它总是采用第一个 mipmap 级别。为什么?如果三角形更接近任何其他 mipmap 级别,为什么不采用它?

我真的很讨厌在我的问题中放一堆代码,因为我强迫别人浪费时间分析代码而不是放最相关的 sn-p 代码,但我不知道问题出在哪里,我别无选择.对不起:(

#include <iostream> #define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h> const GLchar* VERTEX_SHADER_SOURCE = "#version 330 core \n" "layout (location = 0) in vec2 position; \n" "layout (location = 1) in vec2 myTexCoord; \n" " \n" "out vec2 TexCoord; \n" " \n" "void main() \n" " \n" " gl_Position = vec4(position,0.0f, 1.0f);\n" " TexCoord = myTexCoord; \n" " \n"; const GLchar* FRAGMENT_SHADER_SOURCE = "#version 330 core \n" "in vec2 TexCoord; \n" " \n" "out vec4 color; \n" " \n" "uniform sampler2D ourTexture; \n" " \n" "void main() \n" " \n" " color = texture(ourTexture, TexCoord);\n" " \n"; int main() //Change the value of size by 1,2,4,8,16,32,64,128 or 256 and see how the color of the triangle doesn't change. Why does it happen? GLint size = 128; //INIT STUFFS glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(size,size, "", nullptr, nullptr); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); glViewport(0, 0,size,size); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); //Our image for the mipmap with odd level and green color //The dimensions are 256 x 256 and is multiplied by 3 because I defined R,G and B colors unsigned char imageArray[256*256*3]; for(int i = 0; i < 256*256*3; i++) if((i+2)%3 == 0) imageArray[i] = 255; else imageArray[i] = 0; //Our image for the mipmap with pair level and red color unsigned char imageArray2[256*256*3]; for(int i = 0; i < 256*256*3; i++) if(i%3 == 0) imageArray2[i] = 255; else imageArray2[i] = 0; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 8); //All mipmap levels defined by hand glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray); glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray); glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2); glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray); glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2); glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray); glTexImage2D(GL_TEXTURE_2D, 7, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2); glTexImage2D(GL_TEXTURE_2D, 8, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray); GLfloat vertices[] = -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, //vertex coordinates 0.0f, 0.0f //Triangle's texture coordinates ; //VAOs AND VBOs GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)(sizeof(GLfloat)*3*2)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); //SHADERS GLuint program; GLuint vertex, fragment; vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &VERTEX_SHADER_SOURCE, NULL); glCompileShader(vertex); fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &FRAGMENT_SHADER_SOURCE, NULL); glCompileShader(fragment); program = glCreateProgram(); glAttachShader(program, vertex); glAttachShader(program, fragment); glLinkProgram(program); glDeleteShader(vertex); glDeleteShader(fragment); glUseProgram(program); //DRAWING OUR TRIANGLE glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0,3); glfwSwapBuffers(window); while (!glfwWindowShouldClose(window)) glfwPollEvents(); glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glfwTerminate(); return 0;

【问题讨论】:

看起来只有一组纹理坐标而不是三个。 @pleluron 你说得对,那是我的错误。请把它作为答案发布。 【参考方案1】:

你的 mipmap 设置看起来不错。但我看到你有这个:

  GLfloat vertices[] = 
        -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,  //vertex coordinates
        0.0f, 0.0f                              //Triangle's texture coordinates
  ;

您似乎缺少其他 2 个顶点的 UV。 另外,我不会费心手动生成 mipmap,除非你想完全控制过滤技术等。

【讨论】:

以上是关于手动生成 mipmap的主要内容,如果未能解决你的问题,请参考以下文章

手动生成 VS 2005 .vcproj

JDK13手动生成jre模块

Laravel 手动生成重置密码令牌:收到错误“此密码重置令牌无效”

python使用fpdf将生成的长字符串手动换行写入pdf

markdown 生成手动po文件

手动生成 WMS GetFeatureInfo URL