如何在OpenGL中将纹理设置为背景?

Ped*_* GM 2 c++ opengl visual-studio visual-studio-2017

我想制作一个以空间纹理作为背景显示地球的程序.

  • 地球是具有地球纹理(.bmp)的3D制服.

  • 星星的空间是纹理(.bmp).

我总结了我要做的事情:

  • 创建一个新的模型矩阵
  • 将其放置在相机所在的位置
  • 在绘图前禁用深度测试
  • 反向剔除

这是加载功能:

     void load(){

    //Load The Shader
    Shader simpleShader("src/shader.vert", "src/shader.frag");
    g_simpleShader = simpleShader.program;

    // Create the VAO where we store all geometry (stored in g_Vao)
    g_Vao = gl_createAndBindVAO();

    //Create vertex buffer for positions, colors, and indices, and bind them to shader
    gl_createAndBindAttribute(&(shapes[0].mesh.positions[0]), shapes[0].mesh.positions.size() * sizeof(float), g_simpleShader, "a_vertex", 3);
    gl_createIndexBuffer(&(shapes[0].mesh.indices[0]), shapes[0].mesh.indices.size() * sizeof(unsigned int));
    gl_createAndBindAttribute(uvs, uvs_size, g_simpleShader, "a_uv", 2);
    gl_createAndBindAttribute(normal, normal_size, g_simpleShader, "a_normal", 2);

    //Unbind Everything
    gl_unbindVAO();

    //Store Number of Triangles (use in draw())
    g_NumTriangles = shapes[0].mesh.indices.size() / 3;

    //Paths of the earth and space textures
    Image* image = loadBMP("assets/earthmap1k.bmp");
    Image* space = loadBMP("assets/milkyway.bmp");

    //Generate Textures
    glGenTextures(1, &texture_id);
    glGenTextures(1, &texture_id2);

    //Bind Textures
    glBindTexture(GL_TEXTURE_2D, texture_id);
    glBindTexture(GL_TEXTURE_2D, texture_id2);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    //We assign your corresponding data
    glTexImage2D(GL_TEXTURE_2D,1,GL_RGB,image->width, image->height,GL_RGB,GL_UNSIGNED_BYTE,image->pixels);
    glTexImage2D(GL_TEXTURE_2D,1,GL_RGB,space->width, space->height,GL_RGB,GL_UNSIGNED_BYTE,space->pixels);

     }
Run Code Online (Sandbox Code Playgroud)

这是Draw功能:

    void draw(){

    //1. Enable/Disable
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);   
    glEnable(GL_CULL_FACE);     
    glCullFace(GL_FRONT);   

    //2. Shader Activation
    glUseProgram(g_simpleShader); 

    //3. Get All Uniform Locations

    //Space:
    GLuint model_loc2 = glGetUniformLocation (g_simpleShader, "u_model");
    GLuint u_texture2 = glGetUniformLocation(g_simpleShader, "u_texture2");
    GLuint u_light_dir2 = glGetUniformLocation(g_simpleShader,"u_light_dir2");

    //Earth
    GLuint model_loc = glGetUniformLocation(g_simpleShader, "u_model"); 
    GLuint projection_loc = glGetUniformLocation(g_simpleShader, "u_projection");
    GLuint view_loc = glGetUniformLocation(g_simpleShader, "u_view");
    GLuint u_texture = glGetUniformLocation(g_simpleShader, "u_texture");
    GLuint u_light_dir = glGetUniformLocation(g_simpleShader, "u_light_dir");

    //4. Get Values From All Uniforms
    mat4 model_matrix2 = translate(mat4(1.0f), vec3(1.0f,-3.0f,1.0f));
    mat4 model_matrix = translate(mat4(1.0f),vec3(0.0f,-0.35f,0.0f);
    mat4 projection_matrix = perspective(60.0f,1.0f,0.1f,50.0f);
    mat4 view_matrix = lookAt(vec3( 1.0f, -3.0f,  1.0f),vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)glm::vec3(0,1,0));

     //5. Upload Uniforms To Shader
     glUniformMatrix4fv(model_loc2, 1, GL_FALSE, glm::value_ptr(model_matrix2));

    glUniformMatrix4fv(model_loc, 1, GL_FALSE, glm::value_ptr(model_matrix));
    glUniformMatrix4fv(projection_loc, 1, GL_FALSE, glm::value_ptr(projection_matrix));
    glUniformMatrix4fv(view_loc, 1, GL_FALSE, glm::value_ptr(view_matrix));

    glUniform1i(u_texture, 0);
    glUniform3f(u_light_dir, g_light_dir.x, g_light_dir.y, g_light_dir.z);

    glUniform1i(u_texture2, 1);
    glUniform3f(u_light_dir2, g_light_dir.x, g_light_dir.y, g_light_dir.z);

    //6. Activate Texture Unit 0 and Bind our Texture Object
    glActiveTexture(GL_TEXTURE0);
    glActiveTexture(GL_TEXTURE1);

    glBindTexture(GL_TEXTURE_2D, texture_id);
    glBindTexture(GL_TEXTURE_2D, texture_id2);

    //7. Bind VAO
    gl_bindVAO(g_Vao);

    //8. Draw Elements
    glDrawElements(GL_TRIANGLES, 3 * g_NumTriangles, GL_UNSIGNED_INT, 0);

    }
Run Code Online (Sandbox Code Playgroud)

我还有两个片段着色器:

另外,顶点着色器返回顶点的位置:

    gl_Position = u_projection * u_view * u_model * vec4( a_vertex , 1.0 );
Run Code Online (Sandbox Code Playgroud)

当我编译时,它只显示地球,而它应该显示地球和空间作为背景.我已多次查看代码,但我无法找出它是什么.

  • 结果:

suposed_result

  • 我的结果

my_result

Spe*_*tre 5

  1. 如果我在其他事情中看到它你错误地绑定纹理

    glActiveTexture(GL_TEXTURE0);
    glActiveTexture(GL_TEXTURE1);
    
    glBindTexture(GL_TEXTURE_2D, texture_id);
    glBindTexture(GL_TEXTURE_2D, texture_id2);
    
    Run Code Online (Sandbox Code Playgroud)

    应该:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_id);
    
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture_id2);
    
    Run Code Online (Sandbox Code Playgroud)

    但我更喜欢最后设定的活跃单位是0......

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture_id2);
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_id);
    
    Run Code Online (Sandbox Code Playgroud)

    当你开始使用单纹理单元代码组合代码,将节省您很多麻烦......还望各位适当解除绑定出于同样的原因所使用的纹理单元...

  2. 你在经度0/360度的边缘上有一条丑陋的缝隙

    这可能是由错误计算的光照法线,错误的无缝纹理或仅仅伪造复制最后一个贴片的正确纹理坐标的边缘点引起的.看到:

    您还可以为您的星球添加气氛,凹凸贴图,云:

  3. 安德里亚是对的......

    将矩阵设置为单位矩阵并(+/-)1.0z=0.0+/-宽高比校正下渲染矩形,无需深度测试,面部剔除和深度写入......这样可以避免由于浮点错误引起的抖动和闪烁.

  4. Skybox更好,但还有其他选项可以增强

    和那里的所有子链接特别是星星.您可以将天空盒和恒星目录结合在一起以及更多......