int main( int argc, char* argv[] ) { // Initialise window pangolin::View& container = SetupPangoGLWithCuda(1024, 768); size_t cu_mem_start, cu_mem_end, cu_mem_total; cudaMemGetInfo( &cu_mem_start, &cu_mem_total ); glClearColor(1,1,1,0); // Open video device hal::Camera video = OpenRpgCamera(argc,argv); // Capture first image pb::ImageArray images; // N cameras, each w*h in dimension, greyscale const size_t N = video.NumChannels(); if( N != 2 ) { std::cerr << "Two images are required to run this program!" << std::endl; exit(1); } const size_t nw = video.Width(); const size_t nh = video.Height(); // Capture first image video.Capture(images); // Downsample this image to process less pixels const int max_levels = 6; const int level = roo::GetLevelFromMaxPixels( nw, nh, 640*480 ); // const int level = 4; assert(level <= max_levels); // Find centered image crop which aligns to 16 pixels at given level const NppiRect roi = roo::GetCenteredAlignedRegion(nw,nh,16 << level,16 << level); // Load Camera intrinsics from file GetPot clArgs( argc, argv ); const std::string filename = clArgs.follow("","-cmod"); if( filename.empty() ) { std::cerr << "Camera models file is required!" << std::endl; exit(1); } const calibu::CameraRig rig = calibu::ReadXmlRig(filename); if( rig.cameras.size() != 2 ) { std::cerr << "Two camera models are required to run this program!" << std::endl; exit(1); } Eigen::Matrix3f CamModel0 = rig.cameras[0].camera.K().cast<float>(); Eigen::Matrix3f CamModel1 = rig.cameras[1].camera.K().cast<float>(); roo::ImageIntrinsics camMod[] = { {CamModel0(0,0),CamModel0(1,1),CamModel0(0,2),CamModel0(1,2)}, {CamModel1(0,0),CamModel1(1,1),CamModel1(0,2),CamModel1(1,2)} }; for(int i=0; i<2; ++i ) { // Adjust to match camera image dimensions const double scale = nw / rig.cameras[i].camera.Width(); roo::ImageIntrinsics camModel = camMod[i].Scale( scale ); // Adjust to match cropped aligned image camModel = camModel.CropToROI( roi ); camMod[i] = camModel; } const unsigned int w = roi.width; const unsigned int h = roi.height; const unsigned int lw = w >> level; const unsigned int lh = h >> level; const Eigen::Matrix3d& K0 = camMod[0].Matrix(); const Eigen::Matrix3d& Kl = camMod[0][level].Matrix(); std::cout << "K Matrix: " << std::endl << K0 << std::endl; std::cout << "K Matrix - Level: " << std::endl << Kl << std::endl; std::cout << "Video stream dimensions: " << nw << "x" << nh << std::endl; std::cout << "Chosen Level: " << level << std::endl; std::cout << "Processing dimensions: " << lw << "x" << lh << std::endl; std::cout << "Offset: " << roi.x << "x" << roi.y << std::endl; // print selected camera model std::cout << "Camera Model used: " << std::endl << camMod[0][level].Matrix() << std::endl; Eigen::Matrix3d RDFvision;RDFvision<< 1,0,0, 0,1,0, 0,0,1; Eigen::Matrix3d RDFrobot; RDFrobot << 0,1,0, 0,0, 1, 1,0,0; Eigen::Matrix4d T_vis_ro = Eigen::Matrix4d::Identity(); T_vis_ro.block<3,3>(0,0) = RDFvision.transpose() * RDFrobot; Eigen::Matrix4d T_ro_vis = Eigen::Matrix4d::Identity(); T_ro_vis.block<3,3>(0,0) = RDFrobot.transpose() * RDFvision; const Sophus::SE3d T_rl_orig = T_rlFromCamModelRDF(rig.cameras[0], rig.cameras[1], RDFvision); // TODO(jmf): For now, assume cameras are rectified. Later allow unrectified cameras. /* double k1 = 0; double k2 = 0; if(cam[0].Type() == MVL_CAMERA_WARPED) { k1 = cam[0].GetModel()->warped.kappa1; k2 = cam[0].GetModel()->warped.kappa2; } */ const bool rectify = false; if(!rectify) { std::cout << "Using pre-rectified images" << std::endl; } // Check we received at least two images if(images.Size() < 2) { std::cerr << "Failed to capture first stereo pair from camera" << std::endl; return -1; } // Define Camera Render Object (for view / scene browsing) pangolin::OpenGlRenderState s_cam( pangolin::ProjectionMatrixRDF_TopLeft(w,h,K0(0,0),K0(1,1),K0(0,2),K0(1,2),0.1,10000), pangolin::IdentityMatrix(pangolin::GlModelViewStack) ); pangolin::GlBufferCudaPtr vbo(pangolin::GlArrayBuffer, lw*lh,GL_FLOAT, 4, cudaGraphicsMapFlagsWriteDiscard, GL_STREAM_DRAW ); pangolin::GlBufferCudaPtr cbo(pangolin::GlArrayBuffer, lw*lh,GL_UNSIGNED_BYTE, 4, cudaGraphicsMapFlagsWriteDiscard, GL_STREAM_DRAW ); pangolin::GlBuffer ibo = pangolin::MakeTriangleStripIboForVbo(lw,lh); // Allocate Camera Images on device for processing roo::Image<unsigned char, roo::TargetHost, roo::DontManage> hCamImg[] = {{0,nw,nh},{0,nw,nh}}; roo::Image<float2, roo::TargetDevice, roo::Manage> dLookup[] = {{w,h},{w,h}}; roo::Image<unsigned char, roo::TargetDevice, roo::Manage> upload(w,h); roo::Pyramid<unsigned char, max_levels, roo::TargetDevice, roo::Manage> img_pyr[] = {{w,h},{w,h}}; roo::Image<float, roo::TargetDevice, roo::Manage> img[] = {{lw,lh},{lw,lh}}; roo::Volume<float, roo::TargetDevice, roo::Manage> vol[] = {{lw,lh,MAXD},{lw,lh,MAXD}}; roo::Image<float, roo::TargetDevice, roo::Manage> disp[] = {{lw,lh},{lw,lh}}; roo::Image<float, roo::TargetDevice, roo::Manage> meanI(lw,lh); roo::Image<float, roo::TargetDevice, roo::Manage> varI(lw,lh); roo::Image<float, roo::TargetDevice, roo::Manage> temp[] = {{lw,lh},{lw,lh},{lw,lh},{lw,lh},{lw,lh}}; roo::Image<float,roo::TargetDevice, roo::Manage>& imgd = disp[0]; roo::Image<float,roo::TargetDevice, roo::Manage> depthmap(lw,lh); roo::Image<float,roo::TargetDevice, roo::Manage> imga(lw,lh); roo::Image<float2,roo::TargetDevice, roo::Manage> imgq(lw,lh); roo::Image<float,roo::TargetDevice, roo::Manage> imgw(lw,lh); roo::Image<float4, roo::TargetDevice, roo::Manage> d3d(lw,lh); roo::Image<unsigned char, roo::TargetDevice,roo::Manage> Scratch(lw*sizeof(roo::LeastSquaresSystem<float,6>),lh); typedef ulong4 census_t; roo::Image<census_t, roo::TargetDevice, roo::Manage> census[] = {{lw,lh},{lw,lh}}; // Stereo transformation (post-rectification) Sophus::SE3d T_rl = T_rl_orig; const double baseline = T_rl.translation().norm(); std::cout << "Baseline: " << baseline << std::endl; cudaMemGetInfo( &cu_mem_end, &cu_mem_total ); std::cout << "CuTotal: " << cu_mem_total/(1024*1024) << ", Available: " << cu_mem_end/(1024*1024) << ", Used: " << (cu_mem_start-cu_mem_end)/(1024*1024) << std::endl; pangolin::Var<bool> step("ui.step", false, false); pangolin::Var<bool> run("ui.run", false, true); pangolin::Var<bool> lockToCam("ui.Lock to cam", false, true); pangolin::Var<int> show_slice("ui.show slice",MAXD/2, 0, MAXD-1); pangolin::Var<int> maxdisp("ui.maxdisp",MAXD, 0, MAXD); pangolin::Var<bool> subpix("ui.subpix", true, true); pangolin::Var<bool> use_census("ui.use census", true, true); pangolin::Var<int> avg_rad("ui.avg_rad",0, 0, 100); pangolin::Var<bool> do_dtam("ui.do dtam", false, true); pangolin::Var<bool> dtam_reset("ui.reset", false, false); pangolin::Var<float> g_alpha("ui.g alpha", 14, 0,4); pangolin::Var<float> g_beta("ui.g beta", 2.5, 0,2); pangolin::Var<float> theta("ui.theta", 100, 0,100); pangolin::Var<float> lambda("ui.lambda", 20, 0,20); pangolin::Var<float> sigma_q("ui.sigma q", 0.7, 0, 1); pangolin::Var<float> sigma_d("ui.sigma d", 0.7, 0, 1); pangolin::Var<float> huber_alpha("ui.huber alpha", 0.002, 0, 0.01); pangolin::Var<float> beta("ui.beta", 0.00001, 0, 0.01); pangolin::Var<float> alpha("ui.alpha", 0.9, 0,1); pangolin::Var<float> r1("ui.r1", 100, 0,0.01); pangolin::Var<float> r2("ui.r2", 100, 0,0.01); pangolin::Var<bool> filter("ui.filter", false, true); pangolin::Var<float> eps("ui.eps",0.01*0.01, 0, 0.01); pangolin::Var<int> rad("ui.radius",9, 1, 20); pangolin::Var<bool> leftrightcheck("ui.left-right check", false, true); pangolin::Var<float> maxdispdiff("ui.maxdispdiff",1, 0, 5); pangolin::Var<int> domedits("ui.median its",1, 1, 10); pangolin::Var<bool> domed9x9("ui.median 9x9", false, true); pangolin::Var<bool> domed7x7("ui.median 7x7", false, true); pangolin::Var<bool> domed5x5("ui.median 5x5", false, true); pangolin::Var<int> medi("ui.medi",12, 0, 24); pangolin::Var<float> filtgradthresh("ui.filt grad thresh", 0, 0, 20); pangolin::Var<bool> save_depthmaps("ui.save_depthmaps", false, true); int jump_frames = 0; pangolin::RegisterKeyPressCallback(' ', [&run](){run = !run;} ); pangolin::RegisterKeyPressCallback('l', [&lockToCam](){lockToCam = !lockToCam;} ); pangolin::RegisterKeyPressCallback(pangolin::PANGO_SPECIAL + GLUT_KEY_RIGHT, [&step](){step=true;} ); pangolin::RegisterKeyPressCallback(']', [&jump_frames](){jump_frames=100;} ); pangolin::RegisterKeyPressCallback('}', [&jump_frames](){jump_frames=1000;} ); pangolin::Handler2dImageSelect handler2d(lw,lh,level); // ActivateDrawPyramid<unsigned char,max_levels> adleft(img_pyr[0],GL_LUMINANCE8, false, true); // ActivateDrawPyramid<unsigned char,max_levels> adright(img_pyr[1],GL_LUMINANCE8, false, true); pangolin::ActivateDrawImage<float> adleft(img[0],GL_LUMINANCE32F_ARB, false, true); pangolin::ActivateDrawImage<float> adright(img[1],GL_LUMINANCE32F_ARB, false, true); pangolin::ActivateDrawImage<float> adisp(disp[0],GL_LUMINANCE32F_ARB, false, true); pangolin::ActivateDrawImage<float> adw(imgw,GL_LUMINANCE32F_ARB, false, true); // ActivateDrawImage<float> adCrossSection(dCrossSection,GL_RGBA_FLOAT32_APPLE, false, true); pangolin::ActivateDrawImage<float> adVol(vol[0].ImageXY(show_slice),GL_LUMINANCE32F_ARB, false, true); SceneGraph::GLSceneGraph graph; SceneGraph::GLVbo glvbo(&vbo,&ibo,&cbo); graph.AddChild(&glvbo); SetupContainer(container, 6, (float)w/h); container[0].SetDrawFunction(boost::ref(adleft)).SetHandler(&handler2d); container[1].SetDrawFunction(boost::ref(adright)).SetHandler(&handler2d); container[2].SetDrawFunction(boost::ref(adisp)).SetHandler(&handler2d); container[3].SetDrawFunction(boost::ref(adVol)).SetHandler(&handler2d); container[4].SetDrawFunction(SceneGraph::ActivateDrawFunctor(graph, s_cam)) .SetHandler( new pangolin::Handler3D(s_cam, pangolin::AxisNone) ); container[5].SetDrawFunction(boost::ref(adw)).SetHandler(&handler2d); for(unsigned long frame=0; !pangolin::ShouldQuit();) { bool go = frame==0 || jump_frames > 0 || run || Pushed(step); for(; jump_frames > 0; jump_frames--) { video.Capture(images); } if(go) { if(frame>0) { if( video.Capture(images) == false) { exit(1); } } frame++; ///////////////////////////////////////////////////////////// // Upload images to device (Warp / Decimate if necessery) for(int i=0; i<2; ++i ) { hCamImg[i].ptr = images[i].data(); if(rectify) { upload.CopyFrom(hCamImg[i].SubImage(roi)); Warp(img_pyr[i][0], upload, dLookup[i]); }else{ img_pyr[i][0].CopyFrom(hCamImg[i].SubImage(roi)); } roo::BoxReduce<unsigned char, max_levels, unsigned int>(img_pyr[i]); } } go |= avg_rad.GuiChanged() | use_census.GuiChanged(); if( go ) { for(int i=0; i<2; ++i ) { roo::ElementwiseScaleBias<float,unsigned char,float>(img[i], img_pyr[i][level],1.0f/255.0f); if(avg_rad > 0 ) { roo::BoxFilter<float,float,float>(temp[0],img[i],Scratch,avg_rad); roo::ElementwiseAdd<float,float,float,float>(img[i], img[i], temp[0], 1, -1, 0.5); } if(use_census) { Census(census[i], img[i]); } } } if( go | g_alpha.GuiChanged() || g_beta.GuiChanged() ) { ExponentialEdgeWeight(imgw, img[0], g_alpha, g_beta); } go |= filter.GuiChanged() | leftrightcheck.GuiChanged() | rad.GuiChanged() | eps.GuiChanged() | alpha.GuiChanged() | r1.GuiChanged() | r2.GuiChanged(); if(go) { if(use_census) { roo::CensusStereoVolume<float, census_t>(vol[0], census[0], census[1], maxdisp, -1); if(leftrightcheck) roo::CensusStereoVolume<float, census_t>(vol[1], census[1], census[0], maxdisp, +1); }else{ CostVolumeFromStereoTruncatedAbsAndGrad(vol[0], img[0], img[1], -1, alpha, r1, r2); if(leftrightcheck) CostVolumeFromStereoTruncatedAbsAndGrad(vol[1], img[1], img[0], +1, alpha, r1, r2); } if(filter) { // Filter Cost volume for(int v=0; v<(leftrightcheck?2:1); ++v) { roo::Image<float, roo::TargetDevice, roo::Manage>& I = img[v]; roo::ComputeMeanVarience<float,float,float>(varI, temp[0], meanI, I, Scratch, rad); for(int d=0; d<maxdisp; ++d) { roo::Image<float> P = vol[v].ImageXY(d); roo::ComputeCovariance(temp[0],temp[2],temp[1],P,meanI,I,Scratch,rad); GuidedFilter(P,temp[0],varI,temp[1],meanI,I,Scratch,temp[2],temp[3],temp[4],rad,eps); } } } } static int n = 0; // static float theta = 0; // go |= Pushed(dtam_reset); // if(go ) if(Pushed(dtam_reset)) { n = 0; theta.Reset(); // Initialise primal and auxillary variables CostVolMinimumSubpix(imgd,vol[0], maxdisp,-1); imga.CopyFrom(imgd); // Initialise dual variable imgq.Memset(0); } const double min_theta = 1E-0; if(do_dtam && theta > min_theta) { for(int i=0; i<5; ++i ) { // Auxillary exhaustive search CostVolMinimumSquarePenaltySubpix(imga, vol[0], imgd, maxdisp, -1, lambda, (theta) ); // Dual Ascent roo::WeightedHuberGradU_DualAscentP(imgq, imgd, imgw, sigma_q, huber_alpha); // Primal Descent roo::WeightedL2_u_minus_g_PrimalDescent(imgd, imgq, imga, imgw, sigma_d, 1.0f / (theta) ); theta= theta * (1-beta*n); ++n; } if( theta <= min_theta && save_depthmaps ) { cv::Mat dmap = cv::Mat( lh, lw, CV_32FC1 ); // convert disparity to depth roo::Disp2Depth(imgd, depthmap, Kl(0,0), baseline ); depthmap.MemcpyToHost( dmap.data ); // save depth image char Index[10]; sprintf( Index, "%05d", frame ); std::string DepthPrefix = "SDepth-"; std::string DepthFile; DepthFile = DepthPrefix + Index + ".pdm"; std::cout << "Depth File: " << DepthFile << std::endl; std::ofstream pDFile( DepthFile.c_str(), std::ios::out | std::ios::binary ); pDFile << "P7" << std::endl; pDFile << dmap.cols << " " << dmap.rows << std::endl; unsigned int Size = dmap.elemSize1() * dmap.rows * dmap.cols; pDFile << 4294967295 << std::endl; pDFile.write( (const char*)dmap.data, Size ); pDFile.close(); // save grey image std::string GreyPrefix = "Left-"; std::string GreyFile; GreyFile = GreyPrefix + Index + ".pgm"; std::cout << "Grey File: " << GreyFile << std::endl; cv::Mat gimg = cv::Mat( lh, lw, CV_8UC1 ); img_pyr[0][level].MemcpyToHost( gimg.data ); cv::imwrite( GreyFile, gimg ); // reset step = true; dtam_reset = true; } } go |= pangolin::GuiVarHasChanged(); // if(go) { // if(subpix) { // CostVolMinimumSubpix(disp[0],vol[0], maxdisp,-1); // if(leftrightcheck) CostVolMinimumSubpix(disp[1],vol[1], maxdisp,+1); // }else{ // CostVolMinimum<float,float>(disp[0],vol[0], maxdisp); // if(leftrightcheck) CostVolMinimum<float,float>(disp[1],vol[1], maxdisp); // } // } if(go) { for(int di=0; di<(leftrightcheck?2:1); ++di) { for(int i=0; i < domedits; ++i ) { if(domed9x9) MedianFilterRejectNegative9x9(disp[di],disp[di], medi); if(domed7x7) MedianFilterRejectNegative7x7(disp[di],disp[di], medi); if(domed5x5) MedianFilterRejectNegative5x5(disp[di],disp[di], medi); } } if(leftrightcheck ) { LeftRightCheck(disp[1], disp[0], +1, maxdispdiff); LeftRightCheck(disp[0], disp[1], -1, maxdispdiff); } if(filtgradthresh > 0) { FilterDispGrad(disp[0], disp[0], filtgradthresh); } } // if(go) { // Generate point cloud from disparity image DisparityImageToVbo(d3d, disp[0], baseline, Kl(0,0), Kl(1,1), Kl(0,2), Kl(1,2) ); // if(container[3].IsShown()) { // Copy point cloud into VBO { pangolin::CudaScopedMappedPtr var(vbo); roo::Image<float4> dVbo((float4*)*var,lw,lh); dVbo.CopyFrom(d3d); } // Generate CBO { pangolin::CudaScopedMappedPtr var(cbo); roo::Image<uchar4> dCbo((uchar4*)*var,lw,lh); roo::ConvertImage<uchar4,unsigned char>(dCbo, img_pyr[0][level]); } } // Update texture views adisp.SetImageScale(1.0f/maxdisp); // adleft.SetLevel(show_level); // adright.SetLevel(show_level); adVol.SetImage(vol[0].ImageXY(show_slice)); } ///////////////////////////////////////////////////////////// // Draw glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1,1,1); pangolin::FinishFrame(); } }
int main( void ) { crap::audiodevice audio_device; /* openalcode */ //setup window crap::window_setup win_setup; win_setup.title = "Funny Window"; win_setup.width = 1024; win_setup.height = 768; win_setup.multisampling_count = 8; win_setup.opengl_version = 3.3f; win_setup.opengl_profile = crap::compat; //create window crap::window window( win_setup ); window.open(); //get keyboard and mouse crap::keyboard keyboard; crap::mouse mouse; // temporary crap::opengl::enable(crap::opengl::depth_test); crap::opengl::setDepthComparison(crap::opengl::less); crap::opengl::enable(crap::opengl::cull_face); //camera setup camera cam; cam.setPosition( glm::vec3( 0.0f, 0.0f, 5.0f ) ); mouse_pos = mouse.position(); //create contentmanager content_manager cm; cm.init( "spg.ini" ); //create vertex array crap::vertex_array vert_array; vert_array.bind(); //test: load vbo onto GPU vbo cube_vbo( "cube", &cm, vbo::static_draw ); vbo ape_vbo("ape", &cm, vbo::static_draw ); vbo cube_big_vbo( "cube", &cm, vbo::static_draw ); //vbo people_vbo("people", &cm, vbo::static_draw ); ////////////////////////// // Read our .obj file std::vector<glm::vec3> vertices; std::vector<glm::vec2> uvs; std::vector<glm::vec3> normals; bool res = loadOBJ("../../../data/geometry/dupercube.obj", vertices, uvs, normals); std::vector<glm::vec3> tangents; std::vector<glm::vec3> bitangents; computeTangentBasis( vertices, uvs, normals, // input tangents, bitangents // output ); std::vector<unsigned short> indices; std::vector<glm::vec3> indexed_vertices; std::vector<glm::vec2> indexed_uvs; std::vector<glm::vec3> indexed_normals; std::vector<glm::vec3> indexed_tangents; std::vector<glm::vec3> indexed_bitangents; indexVBO_TBN( vertices, uvs, normals, tangents, bitangents, indices, indexed_vertices, indexed_uvs, indexed_normals, indexed_tangents, indexed_bitangents ); GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW); GLuint uvbuffer; glGenBuffers(1, &uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW); GLuint normalbuffer; glGenBuffers(1, &normalbuffer); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW); GLuint tangentbuffer; glGenBuffers(1, &tangentbuffer); glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_tangents.size() * sizeof(glm::vec3), &indexed_tangents[0], GL_STATIC_DRAW); GLuint bitangentbuffer; glGenBuffers(1, &bitangentbuffer); glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_bitangents.size() * sizeof(glm::vec3), &indexed_bitangents[0], GL_STATIC_DRAW); // Generate a buffer for the indices as well GLuint elementbuffer; glGenBuffers(1, &elementbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW); ///////////////////////// geometry_content ig; cm.create_content( "cube" , &ig, type_name::geometry ); //test: load texture onto GPU tbo diffuse_tbo( "stone_diff", &cm, tbo::tga ); tbo normal_tbo( "stone_norm", &cm, tbo::tga ); tbo height_tbo( "stone_height", &cm, tbo::tga ); //shadow stuff crap::frame_buffer frame_buffer; frame_buffer.bind(); tbo depthmap( "", &cm, tbo::depth ); frame_buffer.unbind(); //shadow stuff crap::quad_buffer quad_buffer; //test: load linked shader progam onto GPU shader_manager sm(&cm); sm.add("epr_vert", "epr_frag"); sm.add("shadow_vert", "shadow_frag"); //get stuff from shader program //shadow shader sm.set_current("shadow_vert", "shadow_frag"); crap::uniform DepthBiasMVPID = sm.current()->uniform_location("depthMVP"); //vertex shader sm.set_current("epr_vert", "epr_frag"); crap::uniform WorldMatrixID = sm.current()->uniform_location("world_matrix4x4"); crap::uniform ViewMatrixID = sm.current()->uniform_location("view_matrix4x4"); crap::uniform ModelMatrixID = sm.current()->uniform_location("model_matrix4x4"); crap::uniform ModelView3x3MatrixID = sm.current()->uniform_location("model_view_matrix3x3"); //fragment shader crap::uniform DiffuseTextureID = sm.current()->uniform_location("diffuse_texture"); crap::uniform NormalTextureID = sm.current()->uniform_location("normal_texture"); crap::uniform HeightTextureID = sm.current()->uniform_location("height_texture"); crap::uniform LightAmbientPowerID = sm.current()->uniform_location("ambient_power"); crap::uniform LightPowerArrayID = sm.current()->uniform_location("light_power"); crap::uniform LightSpecularTypeArrayID = sm.current()->uniform_location("light_specular_type"); crap::uniform LightSpecularLobeArrayID = sm.current()->uniform_location("light_specular_lobe"); crap::uniform LightColorArrayID = sm.current()->uniform_location("light_color"); crap::uniform LightSelfShadowingOnID = sm.current()->uniform_location("selfshadowing_on"); crap::uniform DisplacementOnID = sm.current()->uniform_location("displacement_on"); crap::uniform DisplacementStepsID = sm.current()->uniform_location("displacement_steps"); crap::uniform DisplacementRefinementStepsID = sm.current()->uniform_location("displacement_refinement_steps"); crap::uniform DisplacementUVFactorID = sm.current()->uniform_location("displacement_uv_factor"); //both shaders crap::uniform LightPositionArrayID = sm.current()->uniform_location("light_position"); crap::uniform LightDirectionArrayID = sm.current()->uniform_location("light_direction"); crap::uniform LightTypeArrayID = sm.current()->uniform_location("light_type"); crap::uniform LightStateArrayID = sm.current()->uniform_location("light_state"); crap::uniform LightNormalMappingOnID = sm.current()->uniform_location("normal_mapping_on"); //shadow stuff crap::uniform ShadowMapID = sm.current()->uniform_location("shadow_map"); crap::uniform ShadowMappingOnID = sm.current()->uniform_location("shadow_mapping_on"); crap::uniform ShadowDepthBiasMVPID = sm.current()->uniform_location("depth_bias_mvp"); //SHADER DATA // Projection matrix : 60° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units float display_field_of_view = 60.f; //60° float display_ratio_horizontal = 4.f; float display_ratio_vertical = 3.f; float display_range_near = 0.1f; float display_range_far = 100.f; glm::mat4 projection_matrix = glm::perspective( display_field_of_view, display_ratio_horizontal / display_ratio_vertical, display_range_near, display_range_far); glm::mat4 model_matrix(1.0f); glm::mat4 model_view_matrix(1.0f); glm::mat4 view_matrix = cam.view(); glm::mat4 world_matrix(1.0f); glm::mat3 model_view_matrix3x3(1.0f); //light stuff float light_ambient_power = 0.5f; float light_power_array[MAX_LIGHTS] = { 1.f, 1.f, 1.f }; int light_specular_type_array[MAX_LIGHTS] = { 1, 1, 1 }; float light_specular_lobe_array[MAX_LIGHTS] = { 100.f, 100.f, 100.f }; glm::vec3 light_color_array[MAX_LIGHTS] = { glm::vec3(1.f), glm::vec3(1.f), glm::vec3(1.f) }; int light_self_shadowing_on = 1; glm::vec3 light_position_array[MAX_LIGHTS] = { glm::vec3(4,0,0), glm::vec3(0,0,-4), glm::vec3(4,4,4) }; glm::vec3 light_direction_array[MAX_LIGHTS] = { glm::vec3(-4,0,0), glm::vec3(0,0,4), glm::vec3(-4,-4,-4) }; int light_type_array[MAX_LIGHTS] = { 0, 0, 0 }; int light_state_array[MAX_LIGHTS] = { 1, 0, 0 }; int light_normal_mapping_on = 1; //shadowstuff int shadow_mapping_on = 1; //displacement stuff int displacement_on = 1; float displacement_steps = 20; float displacement_refinement_steps = 20; float displacmenet_uv_factor = 20; //GUI TwInit(TW_OPENGL, NULL); TwWindowSize(1024, 768); TwBar * GeneralGUI = TwNewBar("General settings"); TwBar * LightGUI = TwNewBar("Light Settings"); TwBar * DisplacementGUI = TwNewBar("Displacement Settings"); TwSetParam(GeneralGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); TwSetParam(LightGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); TwSetParam(DisplacementGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); //general gui TwAddSeparator(GeneralGUI, "Funny seperator", NULL); TwAddVarRW(GeneralGUI, "Field of View", TW_TYPE_FLOAT , &display_field_of_view, "help='Field of View value'"); TwAddVarRW(GeneralGUI, "Ratio Horizontal", TW_TYPE_FLOAT , &display_ratio_horizontal, "help='Ratio Horizontal'"); TwAddVarRW(GeneralGUI, "Ratio Vertical", TW_TYPE_FLOAT , &display_ratio_vertical, "help='Ratio Vertical'"); TwAddVarRW(GeneralGUI, "Range Near", TW_TYPE_FLOAT , &display_range_near, "help='Range near'"); TwAddVarRW(GeneralGUI, "Range far", TW_TYPE_FLOAT , &display_range_far, "help='Range far'"); //light gui TwAddVarRW(LightGUI, "Ambient light", TW_TYPE_FLOAT , &light_ambient_power, "help='Ambient power'"); TwAddVarRW(LightGUI, "Self Shadowing", TW_TYPE_BOOL32, &light_self_shadowing_on, NULL); TwAddVarRW(LightGUI, "Normal Mapping", TW_TYPE_BOOL32, &light_normal_mapping_on, NULL); TwType gui_light_type = TwDefineEnumFromString("LightType", "Directionallight,Pointlight"); TwType gui_light_specular_type = TwDefineEnumFromString("LightSpecularType", "Blinn,Phong"); //shadow TwAddVarRW(LightGUI, "Cast Shadows", TW_TYPE_BOOL32, &shadow_mapping_on, NULL); //light1 TwAddVarRW(LightGUI, "Light 1", TW_TYPE_BOOL32, light_state_array, NULL); TwAddVarRW(LightGUI, "Light Type 1", gui_light_type, light_type_array, NULL); TwAddVarRW(LightGUI, "Light Specular Type 1", gui_light_specular_type, light_specular_type_array, NULL); TwAddVarRW(LightGUI, "Light Power 1", TW_TYPE_FLOAT , light_power_array, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 1", TW_TYPE_FLOAT , light_specular_lobe_array, NULL); TwAddVarRW(LightGUI, "Light Color 1", TW_TYPE_COLOR3F , light_color_array, NULL); TwAddVarRW(LightGUI, "Light Position 1", TW_TYPE_DIR3F , light_position_array, NULL); TwAddVarRW(LightGUI, "Light Direction 1", TW_TYPE_DIR3F , light_direction_array, NULL); //light2 TwAddVarRW(LightGUI, "Light 2", TW_TYPE_BOOL32, light_state_array+1, NULL); TwAddVarRW(LightGUI, "Light Type 2", gui_light_type, light_type_array+1, NULL); TwAddVarRW(LightGUI, "Light Specular Type 2", gui_light_specular_type, light_specular_type_array+1, NULL); TwAddVarRW(LightGUI, "Light Power 2", TW_TYPE_FLOAT , light_power_array+1, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 2", TW_TYPE_FLOAT , light_specular_lobe_array+1, NULL); TwAddVarRW(LightGUI, "Light Color 2", TW_TYPE_COLOR3F , light_color_array+1, NULL); TwAddVarRW(LightGUI, "Light Position 2", TW_TYPE_DIR3F , light_position_array+1, NULL); TwAddVarRW(LightGUI, "Light Direction 2", TW_TYPE_DIR3F , light_direction_array+1, NULL); //light3 TwAddVarRW(LightGUI, "Light 3", TW_TYPE_BOOL32, light_state_array+2, NULL); TwAddVarRW(LightGUI, "Light Type 3", gui_light_type, light_type_array+2, NULL); TwAddVarRW(LightGUI, "Light Specular Type 3", gui_light_specular_type, light_specular_type_array+2, NULL); TwAddVarRW(LightGUI, "Light Power 3", TW_TYPE_FLOAT , light_power_array+2, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 3", TW_TYPE_FLOAT , light_specular_lobe_array+2, NULL); TwAddVarRW(LightGUI, "Light Color 3", TW_TYPE_COLOR3F , light_color_array+2, NULL); TwAddVarRW(LightGUI, "Light Position 3", TW_TYPE_DIR3F , light_position_array+2, NULL); TwAddVarRW(LightGUI, "Light Direction 3", TW_TYPE_DIR3F , light_direction_array+2, NULL); //displacement gui TwAddVarRW(DisplacementGUI, "Displacement ON/OFF", TW_TYPE_BOOL32, &displacement_on, NULL); TwAddVarRW(DisplacementGUI, "Displacment steps", TW_TYPE_FLOAT , &displacement_steps, NULL); TwAddVarRW(DisplacementGUI, "Displacement refinement", TW_TYPE_FLOAT , &displacement_refinement_steps, NULL); TwAddVarRW(DisplacementGUI, "Displacement UV factor", TW_TYPE_FLOAT , &displacmenet_uv_factor, NULL); //gui mouse setup mouse.set_on_pressed_function( (crap::mouse::user_button_callback_function)gui_mouse_down ); mouse.set_on_release_function( (crap::mouse::user_button_callback_function)gui_mouse_up ); mouse.set_on_move_function( (crap::mouse::user_move_callback_function)TwEventMousePosGLFW ); mouse.set_on_wheel_function( (crap::mouse::user_wheel_callback_function)TwEventMouseWheelGLFW ); keyboard.set_on_pressed_function( (crap::keyboard::user_callback_function)TwEventKeyGLFW ); //todo set char input // temporary crap::opengl::clearColor(1.0f, 1.0f, 1.0f, 0.0f); while( !keyboard.is_pressed( crap::keyboard::key_escape ) && window.is_open() ) { // update positions handleInput(keyboard, mouse, cam); crap::opengl::clear(crap::opengl::color_depth_buffer); frame_buffer.bind(); glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right sm.set_current("shadow_vert", "shadow_frag"); sm.activate(); glm::vec3 lightInvDir = light_direction_array[0]; //glm::vec3(0.5f,2,2); // Compute the MVP matrix from the light's point of view glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0)); glm::mat4 depthModelMatrix = glm::mat4(1.0); glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix; sm.current()->uniform_matrix4f_value( DepthBiasMVPID, 1, &depthMVP[0][0]); sm.current()->vertex_attribute_array.enable(0); cube_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); cube_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); sm.current()->vertex_attribute_array.disable(0); frame_buffer.unbind(); glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right crap::opengl::clear(crap::opengl::color_depth_buffer); sm.set_current("epr_vert", "epr_frag"); sm.activate(); /////////////////////////////////////// ////////////////////////////////////// projection_matrix = glm::perspective( display_field_of_view, display_ratio_horizontal / display_ratio_vertical, display_range_near, display_range_far); view_matrix = cam.view(); model_view_matrix = view_matrix * world_matrix; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix; glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasMVP = biasMatrix*depthMVP; sm.current()->uniform_matrix4f_value( ShadowDepthBiasMVPID, 1, &depthBiasMVP[0][0]); sm.current()->uniform_1i(ShadowMappingOnID, shadow_mapping_on); //activate shader porgram and connect data //sm.activate(); //default stuff sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix[0][0]); sm.current()->uniform_matrix4f_value( ViewMatrixID, 1, &view_matrix[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //light sm.activate(); sm.current()->uniform_1f(LightAmbientPowerID, light_ambient_power); sm.current()->uniform_1i(LightSelfShadowingOnID, light_self_shadowing_on); sm.current()->uniform_1i(LightNormalMappingOnID, light_normal_mapping_on); sm.current()->uniform_1f_value( LightPowerArrayID, 3, light_power_array ); sm.current()->uniform_1i_value( LightSpecularTypeArrayID, 3, light_specular_type_array ); sm.current()->uniform_1f_value( LightSpecularLobeArrayID, 3, light_specular_lobe_array ); sm.current()->uniform_3f_value( LightColorArrayID, 3, (f32*)light_color_array ); sm.current()->uniform_3f_value( LightPositionArrayID, 3, (f32*)light_position_array ); sm.current()->uniform_3f_value( LightDirectionArrayID, 3, (f32*)light_direction_array ); sm.current()->uniform_1i_value( LightTypeArrayID, 3, light_type_array ); sm.current()->uniform_1i_value( LightStateArrayID, 3, light_state_array ); //displacement sm.current()->uniform_1i( DisplacementOnID, displacement_on ); sm.current()->uniform_1f( DisplacementStepsID, displacement_steps); sm.current()->uniform_1f( DisplacementRefinementStepsID, displacement_refinement_steps); sm.current()->uniform_1f( DisplacementUVFactorID, displacmenet_uv_factor); //activate texture buffer and connect data diffuse_tbo.activate(); diffuse_tbo.bind_buffer(); sm.current()->uniform_1i( DiffuseTextureID, 0); normal_tbo.activate(); normal_tbo.bind_buffer(); sm.current()->uniform_1i( NormalTextureID, 1); height_tbo.activate(); height_tbo.bind_buffer(); sm.current()->uniform_1i( HeightTextureID, 2 ); depthmap.activate(); depthmap.bind_buffer(); sm.current()->uniform_1i( ShadowMapID, 4); //define data of buffers sm.current()->vertex_attribute_array.enable(0); //cube_vbo.bind_buffer( vbo::verticies ); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); //cube_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); //cube_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer); //cube_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer( 3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer); //cube_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); ////draw the f**k cube_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); //next object glm::mat4 model_matrix_2 = model_matrix * glm::translate(3.f,0.f,0.f); model_view_matrix = view_matrix * model_matrix_2; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix_2; //activate shader porgram and connect data //sm.activate(); sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_2[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //attempt //define data of buffers sm.current()->vertex_attribute_array.enable(0); ape_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); ape_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); ape_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); ape_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); ape_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); //draw the f**k ape_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode ape_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); //disable data define stuff sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); //next object glm::mat4 model_matrix_3 = model_matrix * glm::translate(0.f,-2.f,0.f); model_view_matrix = view_matrix * model_matrix_2; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix_3; //activate shader porgram and connect data //sm.activate(); sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_3[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //attempt //define data of buffers sm.current()->vertex_attribute_array.enable(0); cube_big_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); cube_big_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); cube_big_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); cube_big_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); cube_big_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); //draw the f**k cube_big_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_big_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); //disable data define stuff sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); glMatrixMode(GL_PROJECTION); glLoadMatrixf((const GLfloat*)&projection_matrix[0]); glMatrixMode(GL_MODELVIEW); glm::mat4 MV = view_matrix * model_matrix; glLoadMatrixf((const GLfloat*)&MV[0]); sm.activate(); // normals glColor3f(0,0,1); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.normals[ig.indices[i]].x, ig.normals[ig.indices[i]].y, ig.normals[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); // tangents glColor3f(1,0,0); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.tangents[ig.indices[i]].x, ig.tangents[ig.indices[i]].y, ig.tangents[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); // bitangents glColor3f(0,1,0); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.binormals[ig.indices[i]].x, ig.binormals[ig.indices[i]].y, ig.binormals[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); glm::vec3 debug_light; // light pos 1 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[0]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // light pos 2 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[1]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // light pos3 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[2]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // Draw GUI TwDraw(); //poll and swap window.swap(); window.poll_events(); } TwTerminate(); //geometry_content ig; //cm.create_content( "ape" , &ig, type_name::geometry ); //texture_content tc; //cm.create_content( "color", &tc, type_name::texture ); //shader_content sc; //cm.create_content( "fragment_texture_only", &sc, type_name::shader ); //cm.save_content( "fragment_texture_only", &sc, type_name::shader ); return 0; }