c++ - OPENGL How do I correctly render these 2 objects with different textures/mapping? -
i trying incorporate both normal mapping & cube mapping single program, having trouble getting them render correctly. working on simple exercise me before going onto more complexed. trying render both these objects single program. both have different textures , torus uses cube mapping while wall uses normal mapping.
these supposed individually:
currently, i've got. torus renders correctly wall's textures don't appear.
i using 2 separate shader programs this, , first time using more 1 shader program, program. suspect issue initialising of shader variables, or obvious i'm not getting. using 2 different vertex structs objects.
struct vertex2 { glfloat position[3]; glfloat normal[3]; glfloat tangent[3]; glfloat texcoord[2]; }; vertex2 g_vertices[] = { // front: triangle 1 // vertex 1 -1.0f, 1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 0.0f, 1.0f, // texture coordinate // vertex 2 -1.0f, -1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 0.0f, 0.0f, // texture coordinate // vertex 3 1.0f, 1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 1.0f, 1.0f, // texture coordinate // triangle 2 // vertex 1 1.0f, 1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 1.0f, 1.0f, // texture coordinate // vertex 2 -1.0f, -1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 0.0f, 0.0f, // texture coordinate // vertex 3 1.0f, -1.0f, 0.0f, // position 0.0f, 0.0f, 1.0f, // normal 1.0f, 0.0f, 0.0f, // tangent 1.0f, 0.0f, // texture coordinate };
main.cpp init function:
static void init(glfwwindow* window) { glenable(gl_depth_test); // enable depth buffer test glenable(gl_texture_2d); // read image data glint imagewidth[5]; //image width info glint imageheight[5]; //image height info g_teximage[front] = readbitmaprgbimage("images/cm_front.bmp", &imagewidth[0], &imageheight[0]); g_teximage[back] = readbitmaprgbimage("images/cm_back.bmp", &imagewidth[0], &imageheight[0]); g_teximage[left] = readbitmaprgbimage("images/cm_left.bmp", &imagewidth[0], &imageheight[0]); g_teximage[right] = readbitmaprgbimage("images/cm_right.bmp", &imagewidth[0], &imageheight[0]); g_teximage[top] = readbitmaprgbimage("images/cm_top.bmp", &imagewidth[0], &imageheight[0]); g_teximage[bottom] = readbitmaprgbimage("images/cm_bottom.bmp", &imagewidth[0], &imageheight[0]); g_teximage[6] = readbitmaprgbimage("images/fieldstone.bmp", &imagewidth[1], &imageheight[1]); g_teximage[7] = readbitmaprgbimage("images/fieldstonebumpdot3.bmp", &imagewidth[2], &imageheight[2]); glgentextures(10, g_textureid); // ... // create , compile our glsl program shader files g_shaderprogramid[0] = loadshaders("cubeenvmapvs.vert", "cubeenvmapfs.frag"); g_shaderprogramid[1] = loadshaders("normalmappingvs.vert", "normalmappingfs.frag"); // find location of shader variables (int = 0; < 2; i++) { positionindex[i] = glgetattriblocation(g_shaderprogramid[i], "aposition"); normalindex[i] = glgetattriblocation(g_shaderprogramid[i], "anormal"); texcoordindex[i] = glgetattriblocation(g_shaderprogramid[i], "atexcoord"); g_mvp_index[i] = glgetuniformlocation(g_shaderprogramid[i], "umodelviewprojectionmatrix"); g_m_index[i] = glgetuniformlocation(g_shaderprogramid[i], "umodelmatrix"); g_viewpointindex[i] = glgetuniformlocation(g_shaderprogramid[i], "uviewpoint"); g_lightpositionindex[i] = glgetuniformlocation(g_shaderprogramid[i], "ulightingproperties.position"); g_lightambientindex[i] = glgetuniformlocation(g_shaderprogramid[i], "ulightingproperties.ambient"); g_lightdiffuseindex[i] = glgetuniformlocation(g_shaderprogramid[i], "ulightingproperties.diffuse"); g_lightspecularindex[i] = glgetuniformlocation(g_shaderprogramid[i], "ulightingproperties.specular"); g_lightshininessindex[i] = glgetuniformlocation(g_shaderprogramid[i], "ulightingproperties.shininess"); g_materialambientindex[i] = glgetuniformlocation(g_shaderprogramid[i], "umaterialproperties.ambient"); g_materialdiffuseindex[i] = glgetuniformlocation(g_shaderprogramid[i], "umaterialproperties.diffuse"); g_materialspecularindex[i] = glgetuniformlocation(g_shaderprogramid[i], "umaterialproperties.specular"); } g_envmapsamplerindex = glgetuniformlocation(g_shaderprogramid[0], "uenvironmentmap"); tangentindex = glgetattriblocation(g_shaderprogramid[1], "atangent"); g_texsamplerindex = glgetuniformlocation(g_shaderprogramid[1], "utexturesampler"); g_normalsamplerindex = glgetuniformlocation(g_shaderprogramid[1], "unormalsampler"); // initialise model matrix identity matrix g_mm_torus = glm::mat4(1.0f); g_mm_wall = mat4(1.0f); // ... // load mesh // load_mesh("models/sphere.obj"); load_mesh("models/torus.obj"); // ... // generate identifier vbos , copy data gpu glgenbuffers(5, g_vbo); glbindbuffer(gl_array_buffer, g_vbo[0]); glbufferdata(gl_array_buffer, sizeof(vertex)*g_numberofvertices, g_pmeshvertices, gl_static_draw); // generate identifier ibo , copy data gpu glbindbuffer(gl_element_array_buffer, g_vbo[1]); glbufferdata(gl_element_array_buffer, sizeof(glint) * 3 * g_numberoffaces, g_pmeshindices, gl_static_draw); // generate identifiers vao glgenvertexarrays(5, g_vao); // create vao , specify vbo data glbindvertexarray(g_vao[0]); glbindbuffer(gl_array_buffer, g_vbo[0]); glbindbuffer(gl_element_array_buffer, g_vbo[1]); glvertexattribpointer(positionindex[0], 3, gl_float, gl_false, sizeof(vertex), reinterpret_cast<void*>(offsetof(vertex, position))); glvertexattribpointer(normalindex[0], 3, gl_float, gl_false, sizeof(vertex), reinterpret_cast<void*>(offsetof(vertex, normal))); glenablevertexattribarray(positionindex[0]); // enable vertex attributes glenablevertexattribarray(normalindex[0]); // generate identifier vbos , copy data gpu glbindbuffer(gl_array_buffer, g_vbo[2]); glbufferdata(gl_array_buffer, sizeof(g_vertices), g_vertices, gl_static_draw); // create vao , specify vbo data glbindvertexarray(g_vao[1]); glbindbuffer(gl_array_buffer, g_vbo[2]); glvertexattribpointer(positionindex[1], 3, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, position))); glvertexattribpointer(normalindex[1], 3, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, normal))); glvertexattribpointer(tangentindex, 3, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, tangent))); glvertexattribpointer(texcoordindex[0], 2, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, texcoord))); // enable vertex attributes glenablevertexattribarray(positionindex[1]); glenablevertexattribarray(normalindex[1]); glenablevertexattribarray(tangentindex); glenablevertexattribarray(texcoordindex[0]); }
render scene function:
static void render_scene() { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); // clear colour buffer , depth buffer gluseprogram(g_shaderprogramid[0]); // use shaders associated shader program glbindvertexarray(g_vao[0]); // make vao active // set uniform shader variables glm::mat4 mvp = g_camera.getprojectionmatrix() * g_camera.getviewmatrix() * g_mm_torus; gluniformmatrix4fv(g_mvp_index[0], 1, gl_false, &mvp[0][0]); gluniformmatrix4fv(g_m_index[0], 1, gl_false, &g_mm_torus[0][0]); gluniform3fv(g_viewpointindex[0], 1, &g_camera.getposition()[0]); gluniform4fv(g_lightpositionindex[0], 1, &g_lightproperties.position[0]); gluniform4fv(g_lightambientindex[0], 1, &g_lightproperties.ambient[0]); gluniform4fv(g_lightdiffuseindex[0], 1, &g_lightproperties.diffuse[0]); gluniform4fv(g_lightspecularindex[0], 1, &g_lightproperties.specular[0]); gluniform1fv(g_lightshininessindex[0], 1, &g_lightproperties.shininess); gluniform4fv(g_materialambientindex[0], 1, &g_materialproperties.ambient[0]); gluniform4fv(g_materialdiffuseindex[0], 1, &g_materialproperties.diffuse[0]); gluniform4fv(g_materialspecularindex[0], 1, &g_materialproperties.specular[0]); glactivetexture(gl_texture0); glbindtexture(gl_texture_cube_map, g_textureid[0]); gluniform1i(g_envmapsamplerindex, 0); gldrawelements(gl_triangles, g_numberoffaces * 3, gl_unsigned_int, 0); // display vertices based on indices , primitive type gluseprogram(g_shaderprogramid[1]); // use shaders associated shader program glbindvertexarray(g_vao[1]); // make vao active // set uniform shader variables glclear(gl_depth_buffer_bit); mvp = g_camera.getprojectionmatrix() * g_camera.getviewmatrix() * g_mm_wall; gluniformmatrix4fv(g_mvp_index[1], 1, gl_false, &mvp[0][0]); gluniformmatrix4fv(g_m_index[1], 1, gl_false, &g_mm_wall[0][0]); gluniform3fv(g_viewpointindex[1], 1, &g_camera.getposition()[0]); gluniform4fv(g_lightpositionindex[1], 1, &g_lightproperties.position[0]); gluniform4fv(g_lightambientindex[1], 1, &g_lightproperties.ambient[0]); gluniform4fv(g_lightdiffuseindex[1], 1, &g_lightproperties.diffuse[0]); gluniform4fv(g_lightspecularindex[1], 1, &g_lightproperties.specular[0]); gluniform1fv(g_lightshininessindex[1], 1, &g_lightproperties.shininess); gluniform4fv(g_materialambientindex[1], 1, &g_materialproperties.ambient[0]); gluniform4fv(g_materialdiffuseindex[1], 1, &g_materialproperties.diffuse[0]); gluniform4fv(g_materialspecularindex[1], 1, &g_materialproperties.specular[0]); glactivetexture(gl_texture1); glbindtexture(gl_texture_2d, g_textureid[6]); glactivetexture(gl_texture2); glbindtexture(gl_texture_2d, g_textureid[7]); gluniform1i(g_texsamplerindex, 1); gluniform1i(g_normalsamplerindex, 2); gldrawarrays(gl_triangles, 0, 36); glflush(); // flush pipeline }
vertex shader torus:
#version 330 core // input data (different executions of shader) in vec3 aposition; in vec3 anormal; // uniform input data uniform mat4 umodelviewprojectionmatrix; uniform mat4 umodelmatrix; // output data (will interpolated each fragment) out vec3 vnormal; out vec3 vposition; void main() { // set vertex position gl_position = umodelviewprojectionmatrix * vec4(aposition, 1.0); // world space vposition = (umodelmatrix * vec4(aposition, 1.0)).xyz; vnormal = (umodelmatrix * vec4(anormal, 0.0)).xyz; }
fragment shader torus:
#version 330 core // interpolated values vertex shaders in vec3 vnormal; in vec3 vposition; // uniform input data struct lightproperties { vec4 position; vec4 ambient; vec4 diffuse; vec4 specular; float shininess; }; struct materialproperties { vec4 ambient; vec4 diffuse; vec4 specular; }; uniform lightproperties ulightingproperties; uniform materialproperties umaterialproperties; uniform vec3 uviewpoint; uniform samplercube uenvironmentmap; // output data out vec3 fcolor; void main() { vec3 n = normalize(vnormal); vec3 l; // determine whether light point light source or directional light if(ulightingproperties.position.w == 0.0f) l = normalize((ulightingproperties.position).xyz); else l = normalize((ulightingproperties.position).xyz - vposition); vec3 v = normalize(uviewpoint - vposition); vec3 r = reflect(-l, n); // calculate ambient, diffuse , specular components vec4 ambient = ulightingproperties.ambient * umaterialproperties.ambient; vec4 diffuse = ulightingproperties.diffuse * umaterialproperties.diffuse * max(dot(l, n), 0.0); vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f); if(dot(l, n) > 0.0f) { specular = ulightingproperties.specular * umaterialproperties.specular * pow(max(dot(v, r), 0.0), ulightingproperties.shininess); } vec3 reflectenvmap = reflect(-v, n); // set output color fcolor = texture(uenvironmentmap, reflectenvmap).rgb; fcolor *= (diffuse + specular + ambient).rgb; }
vertex shader wall:
#version 330 core // input data (different executions of shader) in vec3 aposition; in vec3 anormal; in vec3 atangent; in vec2 atexcoord; // uniform input data uniform mat4 umodelviewprojectionmatrix; uniform mat4 umodelmatrix; // output data (will interpolated each fragment) out vec3 vposition; out vec3 vnormal; out vec3 vtangent; out vec2 vtexcoord; void main() { // set vertex position gl_position = umodelviewprojectionmatrix * vec4(aposition, 1.0); // world space vposition = (umodelmatrix * vec4(aposition, 1.0)).xyz; vnormal = (umodelmatrix * vec4(anormal, 0.0)).xyz; vtangent = (umodelmatrix * vec4(atangent, 0.0)).xyz; vtexcoord = atexcoord; }
fragment shader wall:
#version 330 core // interpolated values vertex shaders in vec3 vposition; in vec3 vnormal; in vec3 vtangent; in vec2 vtexcoord; // uniform input data struct lightproperties { vec4 position; vec4 ambient; vec4 diffuse; vec4 specular; float shininess; }; struct materialproperties { vec4 ambient; vec4 diffuse; vec4 specular; }; uniform lightproperties ulightingproperties; uniform materialproperties umaterialproperties; uniform vec3 uviewpoint; uniform sampler2d utexturesampler; uniform sampler2d unormalsampler; // output data out vec3 fcolor; void main() { // calculate normal map vectors vec3 normal = normalize(vnormal); vec3 tangent = normalize(vtangent); vec3 bitangent = normalize(cross(tangent, normal)); vec3 normalmap = 2.0f * texture(unormalsampler, vtexcoord).xyz - 1.0f; // calculate vectors lighting vec3 n = normalize(mat3(tangent, bitangent, normal) * normalmap); vec3 l; // determine whether light point light source or directional light if(ulightingproperties.position.w == 0.0f) l = normalize((ulightingproperties.position).xyz); else l = normalize((ulightingproperties.position).xyz - vposition); vec3 v = normalize(uviewpoint - vposition); vec3 r = reflect(-l, n); // calculate phong lighting vec4 ambient = ulightingproperties.ambient * umaterialproperties.ambient; vec4 diffuse = ulightingproperties.diffuse * umaterialproperties.diffuse * max(dot(l, n), 0.0); vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f); if(dot(l, n) > 0.0f) { specular = ulightingproperties.specular * umaterialproperties.specular * pow(max(dot(v, r), 0.0), ulightingproperties.shininess); } // set output color fcolor = (diffuse + specular + ambient).rgb; fcolor *= texture(utexturesampler, vtexcoord).rgb; }
ps: sorry if bit irresponsible questions yesterday. of advice didn't understand , didn't reply.
when drawing 2nd part (wall), binding textures texture units gl_texture1
, gl_texture2
:
glactivetexture(gl_texture1); glbindtexture(gl_texture_2d, g_textureid[6]); glactivetexture(gl_texture2); glbindtexture(gl_texture_2d, g_textureid[7]);
but setting texture unit indices 0 , 1 texture sampler uniforms utexturesampler
, unormalsampler
:
gluniform1i(g_texsamplerindex, 0); gluniform1i(g_normalsamplerindex, 1);`
adapt code this:
gluniform1i(g_texsamplerindex, 1); // gl_texture1 gluniform1i(g_normalsamplerindex, 2); // gl_texture2
futher attribute index of "atexcoord"
stored texcoordindex[i]
g_shaderprogramid[i]
:
for (int = 0; < 2; i++) { .... texcoordindex[i] = glgetattriblocation(g_shaderprogramid[i], "atexcoord"); ..... }
you have aware of when set vertex attribute pointer , enable vertex attribute
change this:
glvertexattribpointer(texcoordindex[0], 2, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, texcoord))); ..... glenablevertexattribarray(texcoordindex[0]);
to this:
glvertexattribpointer(texcoordindex[1], 2, gl_float, gl_false, sizeof(vertex2), reinterpret_cast<void*>(offsetof(vertex2, texcoord))); ..... glenablevertexattribarray(texcoordindex[1]);
Comments
Post a Comment