Reputation: 854
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).
The space with the stars is a texture (.bmp).
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:
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.
Upvotes: 2
Views: 6991
Reputation: 51845
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...
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:
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.
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