// render the scene with OpenGL void shade(Scene* scene, ShadeState* state) { // enable depth test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); // disable culling face glDisable(GL_CULL_FACE); // let the shader control the points glEnable(GL_POINT_SPRITE); // set up the viewport from the scene image size glViewport(0, 0, scene->image_width, scene->image_height); // clear the screen (both color and depth) - set cleared color to background glClearColor(scene->background.x, scene->background.y, scene->background.z, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // enable program glUseProgram(state->gl_program_id); // bind camera's position, inverse of frame and projection // use frame_to_matrix_inverse and frustum_matrix glUniform3fv(glGetUniformLocation(state->gl_program_id,"camera_pos"), 1, &scene->camera->frame.o.x); glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"camera_frame_inverse"), 1, true, &frame_to_matrix_inverse(scene->camera->frame)[0][0]); glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"camera_projection"), 1, true, &frustum_matrix(-scene->camera->dist*scene->camera->width/2, scene->camera->dist*scene->camera->width/2, -scene->camera->dist*scene->camera->height/2, scene->camera->dist*scene->camera->height/2, scene->camera->dist,10000)[0][0]); // bind ambient and number of lights glUniform3fv(glGetUniformLocation(state->gl_program_id,"ambient"),1,&scene->ambient.x); glUniform1i(glGetUniformLocation(state->gl_program_id,"lights_num"),scene->lights.size()); // foreach light auto count = 0; for(auto light : scene->lights) { // bind light position and internsity (create param name with tostring) glUniform3fv(glGetUniformLocation(state->gl_program_id,tostring("light_pos[%d]",count).c_str()), 1, &light->frame.o.x); glUniform3fv(glGetUniformLocation(state->gl_program_id,tostring("light_intensity[%d]",count).c_str()), 1, &light->intensity.x); count++; } // foreach mesh for(auto mesh : scene->meshes) { // draw mesh shade_mesh(mesh, scene->animation->time, scene->draw_wireframe, scene->animation->gpu_skinning, scene->draw_normals, state); } // foreach surface for(auto surface : scene->surfaces) { // draw display mesh shade_mesh(surface->_display_mesh, scene->animation->time, scene->draw_wireframe, scene->animation->gpu_skinning, scene->draw_normals, state); } }
// render the scene with OpenGL void shade(Scene* scene, ShadeState* state) { // enable depth test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); // disable culling face glDisable(GL_CULL_FACE); // let the shader control the points glEnable(GL_POINT_SPRITE); // set up the viewport from the scene image size glViewport(0, 0, scene->image_width, scene->image_height); // clear the screen (both color and depth) - set cleared color to background glClearColor(scene->background.x, scene->background.y, scene->background.z, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // enable program glUseProgram(state->gl_program_id); // bind camera's position, inverse of frame and projection // use frame_to_matrix_inverse and frustum_matrix glUniform3fv(glGetUniformLocation(state->gl_program_id,"camera_pos"), 1, &scene->camera->frame.o.x); glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"camera_frame_inverse"), 1, true, &frame_to_matrix_inverse(scene->camera->frame)[0][0]); glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"camera_projection"), 1, true, &frustum_matrix(-scene->camera->dist*scene->camera->width/2, scene->camera->dist*scene->camera->width/2, -scene->camera->dist*scene->camera->height/2, scene->camera->dist*scene->camera->height/2, scene->camera->dist,10000)[0][0]); // bind ambient and number of lights glUniform3fv(glGetUniformLocation(state->gl_program_id,"ambient"),1,&scene->ambient.x); glUniform1i(glGetUniformLocation(state->gl_program_id,"lights_num"),scene->lights.size()); // foreach light auto count = 0; for(auto light : scene->lights) { // bind light position and internsity (create param name with tostring) glUniform3fv(glGetUniformLocation(state->gl_program_id,tostring("light_pos[%d]",count).c_str()), 1, &light->frame.o.x); glUniform3fv(glGetUniformLocation(state->gl_program_id,tostring("light_intensity[%d]",count).c_str()), 1, &light->intensity.x); count++; } // foreach mesh for(auto mesh : scene->meshes) { // bind material kd, ks, n glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_kd"), 1,&mesh->mat->kd.x); glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_ks"), 1,&mesh->mat->ks.x); glUniform1f(glGetUniformLocation(state->gl_program_id,"material_n"), mesh->mat->n); // YOUR CODE GOES HERE --------------------- // bind texture params (txt_on, sampler) _bind_texture("material_kd_txt", "material_kd_txt_on", mesh->mat->kd_txt, 0, state); _bind_texture("material_ks_txt", "material_ks_txt_on", mesh->mat->ks_txt, 1, state); _bind_texture("material_norm_txt", "material_norm_txt_on", mesh->mat->norm_txt, 2, state); // bind mesh frame - use frame_to_matrix glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"mesh_frame"), 1,true,&frame_to_matrix(mesh->frame)[0][0]); // enable vertex attributes arrays and set up pointers to the mesh data auto vertex_pos_location = glGetAttribLocation(state->gl_program_id, "vertex_pos"); auto vertex_norm_location = glGetAttribLocation(state->gl_program_id, "vertex_norm"); // YOUR CODE GOES HERE --------------------- auto vertex_texcoord_location = glGetAttribLocation(state->gl_program_id, "vertex_texcoord"); glEnableVertexAttribArray(vertex_pos_location); glVertexAttribPointer(vertex_pos_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->pos[0].x); glEnableVertexAttribArray(vertex_norm_location); glVertexAttribPointer(vertex_norm_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->norm[0].x); // YOUR CODE GOES HERE --------------------- if (!mesh->texcoord.empty()) { glEnableVertexAttribArray(vertex_texcoord_location); glVertexAttribPointer(vertex_texcoord_location, 2, GL_FLOAT, GL_FALSE, 0, &mesh->texcoord[0].x); } // draw triangles and quads if(! scene->draw_wireframe) { if(mesh->triangle.size()) glDrawElements(GL_TRIANGLES, mesh->triangle.size()*3, GL_UNSIGNED_INT, &mesh->triangle[0].x); if(mesh->quad.size()) glDrawElements(GL_QUADS, mesh->quad.size()*4, GL_UNSIGNED_INT, &mesh->quad[0].x); } else { auto edges = EdgeMap(mesh->triangle, mesh->quad).edges(); glDrawElements(GL_LINES, edges.size()*2, GL_UNSIGNED_INT, &edges[0].x); } // draw line sets if(! mesh->line.empty()) glDrawElements(GL_LINES, mesh->line.size()*2, GL_UNSIGNED_INT, mesh->line.data()); for(auto segment : mesh->spline) glDrawElements(GL_LINE_STRIP, 4, GL_UNSIGNED_INT, &segment); // disable vertex attribute arrays glDisableVertexAttribArray(vertex_pos_location); glDisableVertexAttribArray(vertex_norm_location); // YOUR CODE GOES HERE --------------------- if (!mesh->texcoord.empty()) glDisableVertexAttribArray(vertex_texcoord_location); } }