Peter Palmer
Peter Palmer

Reputation: 854

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.

I have summarized what I have to do:

This is the Load function:

     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:

    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:

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

my_result

Upvotes: 2

Views: 6991

Answers (1)

Spektre
Spektre

Reputation: 51845

  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 ...

    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

    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.

  4. Skybox is better but there are also other options to enhance

    and all the sublinks in there especially stars. You can combine skybox and stellar catalog together and much much more...

Upvotes: 5

Related Questions