简体   繁体   English

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

[英]How to set a texture as background in OpenGL?

I want to make a program that shows the earth with a space texture as the background. 我想制作一个程序,显示以空间纹理为背景的地球

  • The earth is a 3D Uniform with a earth texture (.bmp). 地球是具有地球纹理(.bmp)的3D制服。

  • The space with the stars is a texture (.bmp). 带有星星的空间是一个纹理(.bmp)。

I have summarized what I have to do: 我总结了我要做的事情:

  • Create a new Model Matrix 创建一个新的模型矩阵
  • Position it at the same place where the camera is 将其放置在相机所在的同一位置
  • Disable depth test before drawing 绘制前禁用深度测试
  • Reverse culling 反向剔除

This is the Load function: 这是Load函数:

     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);

     }

This is the Draw function: 这是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);

    }

Also I have two Fragment Shaders : 我也有两个片段着色器

  • The first one returns this: 第一个返回以下内容:

     fragColor = vec4(final_color, 1.0); 
  • The second one returns this: 第二个返回此:

     fragColor = vec4(texture_color.xyz, 1.0); 

Also the Vertex Shader returns the position of the vertex: 顶点着色器也返回顶点的位置:

    gl_Position = u_projection * u_view * u_model * vec4( a_vertex , 1.0 );

When I compile, it only shows the earth while it should show the earth and the space as background. 当我编译时,它仅显示地球,而应显示地球和空间作为背景。 I have reviewed the code several times but I can not find out what it is. 我已经多次检查了该代码,但是我找不到它是什么。

  • Suposed result: 预期结果:

suposed_result

  • My Result 我的结果

my_result

  1. If I see it right among other things you are wrongly binding textures 如果我认为正确,则说明您错误地绑定了纹理

     glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture_id); glBindTexture(GL_TEXTURE_2D, texture_id2); 

    should be: 应该:

     glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture_id); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture_id2); 

    but I prefer that last set active units is 0 ... 但我更喜欢最后设置的活动单位为0 ...

     glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture_id2); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture_id); 

    that will save you a lot of troubles when you start combine code with single texture unit code ... Also hope you are properly unbinding the used texture units for the same reasons... 当您开始将代码与单个纹理单元代码结合在一起时,这将为您省去很多麻烦。也希望出于相同的原因,您可以正确地解除对使用的纹理单元的绑定...

  2. You got ugly seam on the edge 0/360deg of longitude 您在经度0/360度的边缘上有难看的接缝

    this might be caused by wrongly computed normal for lighting, wrong not seamless texture or just by forgeting to duplicate the edge points with correct texture coordinates for the last patch. 这可能是由于错误地计算了照明的法线,错误的非无缝纹理,或者只是忘记为最后一个色块使用正确的纹理坐标来复制边缘点而导致的。 See: 看到:

    You can also add atmosphere,bump map, clouds to your planet: 您还可以向您的星球添加气氛,凹凸贴图,云层:

  3. Andrea is right... 安德里亚是对的...

    set matrices as unit matrix and render (+/-)1.0 rectangle at z=0.0 +/- aspect ratio correction without depth test, face culling and depth write ... That way you will avoid jitter and flickering stuff due to floating point errors. 将矩阵设置为单位矩阵,并在z=0.0 +/-宽高比校正下渲染(+/-)1.0矩形,而无需进行深度测试,面部剔除和深度写入...这样,您将避免由于浮点错误而引起的抖动和闪烁现象。

  4. Skybox is better but there are also other options to enhance Skybox更好,但还有其他选择可以增强

    and all the sublinks in there especially stars. 以及其中的所有子链接,尤其是星星。 You can combine skybox and stellar catalog together and much much more... 您可以将skybox和星型目录结合在一起,甚至更多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM