// // Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #include // Needs to be included before gl_interop #include #include #include #include //#include #include #include "sampleConfig.h" #include "mywhitted.h" #include "Light.h" #include "Camera.h" #include "Trackball.h" #include "CUDAOutputBuffer.h" #include "Exception.h" #include "GLDisplay.h" #include "Matrix.h" #include "Scene.h" #include "Model.h" #include "sutil.h" #include "vec_math.h" #include "myWorkDistribution.h" //#include "optixScene.h" #include #include #include #include #include #include #include #include #include #include #include #include //#define USE_IAS // WAR for broken direct intersection of GAS on non-RTX cards #define pi 3.14156 #define SIZE 500 #define N 35 #define MAX_CHAR 128 bool resize_dirty = false; bool minimized = false; // Camera state bool camera_changed = true; sutil::Camera temp_camera; sutil::Trackball trackball; // Mouse state int32_t mouse_button = -1; int32_t samples_per_launch = 16; int32_t width = 768; int32_t height = 768; extern "C" void fillSamplesCUDA( int32_t num_samples, cudaStream_t stream, int32_t gpu_idx, int32_t num_gpus, int32_t width, int32_t height, int2 * samples); //const whitted::Parallelogram g_floor( // make_float3(128.0f, 0.0f, 0.0f), // v1 // make_float3(0.0f, 0.0f, 128.0f), // v2 // make_float3(-64.0f, 0.01f, -64.0f) // anchor //); const whitted::BasicLight g_light = { //make_float3(-5.0f, 50.0f, -16.0f), // pos make_float3(-1.38275,1.17938,-0.912869), make_float3(1.0f, 1.0f, 1.0f) // color }; //自建全局变量 static int SceneID = 0, GpuNum = 0; int MainWindow = 0, SubWindow = 0; static int GpuID[4] = {0}; //------------------------------------------------------------------------------ // // GLFW callbacks // //------------------------------------------------------------------------------ static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) { double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); if (action == GLFW_PRESS) { mouse_button = button; trackball.startTracking(static_cast(xpos), static_cast(ypos)); } else { mouse_button = -1; } } static void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { if (mouse_button == GLFW_MOUSE_BUTTON_LEFT) { trackball.setViewMode(sutil::Trackball::LookAtFixed); trackball.updateTracking(static_cast(xpos), static_cast(ypos), width, height); camera_changed = true; } else if (mouse_button == GLFW_MOUSE_BUTTON_RIGHT) { trackball.setViewMode(sutil::Trackball::EyeFixed); trackball.updateTracking(static_cast(xpos), static_cast(ypos), width, height); camera_changed = true; } } static void windowSizeCallback(GLFWwindow* window, int32_t res_x, int32_t res_y) { // Keep rendering at the current resolution when the window is minimized. if (minimized) return; // Output dimensions must be at least 1 in both x and y. sutil::ensureMinimumSize(res_x, res_y); width = res_x; height = res_y; camera_changed = true; resize_dirty = true; } static void windowIconifyCallback(GLFWwindow* window, int32_t iconified) { minimized = (iconified > 0); } static void keyCallback(GLFWwindow* window, int32_t key, int32_t /*scancode*/, int32_t action, int32_t /*mods*/) { if (action == GLFW_PRESS) { if (key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE) { glfwSetWindowShouldClose(window, true); } } else if (key == GLFW_KEY_G) { // toggle UI draw std::cout << "x的位置" << temp_camera.eye().x << "y的位置" << temp_camera.eye().y << "z的位置" << temp_camera.eye().z << std::endl; std::cout << "lookat的x,y,z: " << temp_camera.lookat().x <<","<< temp_camera.lookat().y<<"," << temp_camera.lookat().z << std::endl; std::cout << "eye的x,y,z: " << temp_camera.eye().x << "," << temp_camera.eye().y << "," << temp_camera.eye().z << std::endl; } } static void scrollCallback(GLFWwindow* window, double xscroll, double yscroll) { if (trackball.wheelEvent((int)yscroll)) camera_changed = true; } //------------------------------------------------------------------------------ // // Helper functions // TODO: some of these should move to sutil or optix util header // //------------------------------------------------------------------------------ void printUsageAndExit(const char* argv0) { std::cerr << "Usage : " << argv0 << " [options]\n"; std::cerr << "Options: --file | -f File for image output\n"; std::cerr << " --dim=x Set image dimensions; defaults to 768x768\n"; std::cerr << " --launch-samples | -s Number of samples per pixel per launch (default 16)\n"; std::cerr << " --no-gl-interop Disable GL interop for display\n"; std::cerr << " --model Specify model to render (required)\n"; std::cerr << " --help | -h Print this usage message\n"; exit(0); } void initCameraState(const sutil::Scene& state) { temp_camera = state.cameras(); camera_changed = true; trackball.setCamera(&temp_camera); trackball.setMoveSpeed(10.0f); trackball.setReferenceFrame(make_float3(1.0f, 0.0f, 0.0f), make_float3(0.0f, 0.0f, 1.0f), make_float3(0.0f, 1.0f, 0.0f)); trackball.setGimbalLock(true); } void initLaunchParams(sutil::Scene& state) { state.params.subframe_index = 0u; state.params.width = width; state.params.height = height; state.params.device_idx = state.device_idx; state.params.max_depth = 5; state.params.scene_epsilon = 1.e-3f; state.params.r = 0.7; state.params.R = 37; state.params.Nr = height; state.params.Nc = width; state.params.PI = 3.141592653; state.params.light = g_light; state.params.ambient_light_color = make_float3(0.7f, 0.75f, 0.6f); //const float loffset = state.aabb().maxExtent(); // // //TODO: add light support to sutil::Scene //std::vector lights(2); //lights[0].type = Light::Type::POINT; //lights[0].point.color = { 1.0f, 1.0f, 0.8f }; //lights[0].point.intensity = 5.0f; //lights[0].point.position = state.aabb().center() + make_float3(loffset); //lights[0].point.falloff = Light::Falloff::QUADRATIC; //lights[1].type = Light::Type::POINT; //lights[1].point.color = { 0.8f, 0.8f, 1.0f }; //lights[1].point.intensity = 3.0f; //lights[1].point.position = state.aabb().center() + make_float3(-loffset, 0.5f * loffset, -0.5f * loffset); //lights[1].point.falloff = Light::Falloff::QUADRATIC; //state.params.lights.count = static_cast(lights.size()); //CUDA_CHECK(cudaMalloc( // reinterpret_cast(&state.params.lights.data), // lights.size() * sizeof(Light) //)); //CUDA_CHECK(cudaMemcpy( // reinterpret_cast(state.params.lights.data), // lights.data(), // lights.size() * sizeof(Light), // cudaMemcpyHostToDevice //)); state.params.miss_color = make_float3(0.35f, 0.55f, 0.85f); //CUDA_CHECK( cudaStreamCreate( &stream ) ); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_params), sizeof(whitted::LaunchParams))); state.params.handle = state.traversableHandle(); } void handleCameraUpdate(std::vector& scene) { if (!camera_changed) return; camera_changed = false; temp_camera.setAspectRatio(static_cast(width) / static_cast(height)); float3 u, v, w; temp_camera.UVWFrame(u, v, w); for (auto& state : scene) { state.params.eye = temp_camera.eye(); state.params.U = u; state.params.V = v; state.params.W = w; } /* std::cerr << "Updating camera:\n" << "\tU: " << params.U.x << ", " << params.U.y << ", " << params.U.z << std::endl << "\tV: " << params.V.x << ", " << params.V.y << ", " << params.V.z << std::endl << "\tW: " << params.W.x << ", " << params.W.y << ", " << params.W.z << std::endl; */ } void allocIOBuffers(sutil::Scene& state, int num_gpus) { StaticWorkDistribution wd; wd.setRasterSize(width, height); wd.setNumGPUs(num_gpus); state.num_samples = wd.numSamples(state.device_idx); state.params.numPerRow = wd.numPerRows(state.device_idx); state.numPerRow = wd.numPerRows(state.device_idx); state.numPerCol = wd.numPerCols(state.device_idx); CUDA_CHECK(cudaSetDevice(state.device_idx)); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_sample_indices))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_accum_buffer))); // CUDA_CHECK(cudaFree(reinterpret_cast(state.d_visibility))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_visibility_ind))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_direct_illum))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_indirect_illum))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_depth))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_direct_buffer))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_sample_indices), state.num_samples * sizeof(int2))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_accum_buffer), state.num_samples * sizeof(float4))); //可见性图 CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_visibility), state.num_samples * sizeof(float))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_visibility_ind), state.num_samples * sizeof(float))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_direct_illum), state.num_samples * sizeof(float3))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_indirect_illum), state.num_samples * sizeof(float3))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_depth), state.num_samples * sizeof(float))); CUDA_CHECK(cudaMalloc(reinterpret_cast(&state.d_direct_buffer), state.num_samples * sizeof(float3))); //sample_index_buffer存储的是对应id的全局索引 state.params.sample_index_buffer = state.d_sample_indices; state.params.accum_buffer = state.d_accum_buffer; state.params.frame_buffer = 0; // Will be set when output buffer is mapped state.params.visibility = state.d_visibility; state.params.visibility_ind = state.d_visibility_ind; state.params.direct_illum = state.d_direct_illum; state.params.indirect_illum = state.d_indirect_illum; state.params.depth = state.d_depth; state.params.direct_buffer = state.d_direct_buffer; std::cout <<"GPU设备号:"<< state.device_idx << std::endl; fillSamplesCUDA( state.num_samples, state.stream, state.device_idx, num_gpus, width, height, state.d_sample_indices ); } void handleResize(sutil::CUDAOutputBuffer& output_buffer, std::vector& scene) { if (!resize_dirty) return; resize_dirty = false; CUDA_CHECK(cudaSetDevice(scene.front().device_idx)); output_buffer.resize(width, height); for (auto& state : scene) { state.params.width = width; state.params.height = height; allocIOBuffers(state, static_cast(scene.size())); } // Realloc accumulation buffer } void updateState(sutil::CUDAOutputBuffer& output_buffer, std::vector& scene) { // Update params on device if (camera_changed || resize_dirty) for (auto& state : scene) state.params.subframe_index = 0; handleCameraUpdate(scene); handleResize(output_buffer, scene); } void launchSubframe(sutil::CUDAOutputBuffer& output_buffer, std::vector& scene) { uchar4* result_buffer_data = output_buffer.map(); for (auto& state : scene) { // Launch state.params.frame_buffer = result_buffer_data; CUDA_CHECK(cudaMemcpyAsync(reinterpret_cast(state.d_params), &state.params, sizeof(whitted::LaunchParams), cudaMemcpyHostToDevice, state.stream // stream )); OPTIX_CHECK(optixLaunch( state.pipeline(), state.stream, // stream reinterpret_cast(state.d_params), sizeof(whitted::LaunchParams), state.sbt(), state.num_samples, // launch width 1, // launch height 1 // launch depth )); //OPTIX_CHECK(optixLaunch( // state.pipeline(), // state.stream, // stream // reinterpret_cast(state.d_params), // sizeof(whitted::LaunchParams), // state.sbt2(), // state.num_samples, // launch width // 1, // launch height // 1 // launch depth //)); //OPTIX_CHECK(optixLaunch( // state.pipeline2(), // state.stream, // stream // reinterpret_cast(state.d_params), // sizeof(whitted::LaunchParams), // state.sbt2(), // state.num_samples, // launch width // 1, // launch height // 1 // launch depth //)); } output_buffer.unmap(); for (auto& state : scene) { CUDA_CHECK(cudaSetDevice(state.device_idx)); CUDA_SYNC_CHECK(); } } void displaySubframe( sutil::CUDAOutputBuffer& output_buffer, sutil::GLDisplay& gl_display, GLFWwindow* window) { // Display int framebuf_res_x = 0; // The display's resolution (could be HDPI res) int framebuf_res_y = 0; // glfwGetFramebufferSize(window, &framebuf_res_x, &framebuf_res_y); gl_display.display( width, height, framebuf_res_x, framebuf_res_y, output_buffer.getPBO() ); } void cleanup(std::vector& scene) { for (auto& state : scene) { CUDA_CHECK(cudaFree(reinterpret_cast(state.params.accum_buffer))); //CUDA_CHECK(cudaFree(reinterpret_cast(state.params.light.data))); CUDA_CHECK(cudaFree(reinterpret_cast(state.d_params))); //CUDA_CHECK(cudaFree(reinterpret_cast(state.gas_handle))); //CUDA_CHECK(cudaFree(reinterpret_cast(state.d_gas_output_buffer))); } } static void context_log_cb(unsigned int level, const char* tag, const char* message, void* /*cbdata */) { std::cerr << "[" << std::setw(2) << level << "][" << std::setw(12) << tag << "]: " << message << "\n"; } void createContext(sutil::Scene& state) { // Initialize CUDA on this device CUDA_CHECK(cudaFree(0)); OptixDeviceContext context; CUcontext cuCtx = 0; // zero means take the current context OptixDeviceContextOptions options = {}; options.logCallbackFunction = &context_log_cb; options.logCallbackLevel = 4; OPTIX_CHECK(optixDeviceContextCreate(cuCtx, &options, &context)); state.m_context = context; CUDA_CHECK(cudaStreamCreate(&state.stream)); } void createContexts(std::vector& scene) { OPTIX_CHECK(optixInit()); int32_t device_count = 0;//该变量用于设置使用的GPU数目,后期可将其改为GpuNum CUDA_CHECK(cudaGetDeviceCount(&device_count));//获得显卡数目 //device_count = 1; scene.resize(device_count); std::cout << "Total GPUs visible: " << device_count << std::endl; cudaDeviceProp prop; for (int i = 0,j=0; j < device_count; ++j)//后期将device_count改为GpuNum { if (GpuID[j]!=0) { scene[i].device_idx = j; CUDA_CHECK(cudaGetDeviceProperties(&prop, j)); CUDA_CHECK(cudaSetDevice(j)); std::cout << "\t[" << i << "]: " << prop.name << std::endl; createContext(scene[i]); i++; } } } #pragma region 测试 static int hit_x, hit_y; int menu1 = 0, menu2 = 0; int testwindow; static int i=0; void glutInitalize4(); void huizong() { std::string outfile; try { std::vector model_name; switch (SceneID) { case 1: //model_name.push_back(sutil::sampleDataFilePath("smokingroom/scene.gltf")); //model_name.push_back(sutil::sampleDataFilePath("WaterBottle/WaterBottle.gltf")); break; case 2: model_name.push_back(sutil::sampleDataFilePath("gallery/plane.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene2.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene3.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene4.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene5.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene6.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene7.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene8.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene9.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene10.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene11.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene12.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene13.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene14.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene15.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene16.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene17.gltf")); model_name.push_back(sutil::sampleDataFilePath("gallery/scene18.gltf")); break; case 3: model_name.push_back(sutil::sampleDataFilePath("scene2.gltf")); //model_name.push_back(sutil::sampleDataFilePath("readRoom/scene.gltf")); break; case 4: model_name.push_back(sutil::sampleDataFilePath("kingHall/scene.gltf")); break; default: break; } //model_name.push_back(sutil::sampleDataFilePath("Duck/Duck.gltf")); //model_name.push_back(sutil::sampleDataFilePath("WaterBottle/WaterBottle.gltf")); //model_name.push_back(sutil::sampleDataFilePath("test-blender-gltf/source/Atrium.gltf")); //model_name.push_back(sutil::sampleDataFilePath("substance_wood_floor_material_pbr/scene.gltf")); //model_name.push_back(sutil::sampleDataFilePath("scene/tree.gltf")); //model_name.push_back(sutil::sampleDataFilePath("scene/butterfly.gltf")); //model_name.push_back(sutil::sampleDataFilePath("scene/scene_empty.gltf")); //model_name.push_back(sutil::sampleDataFilePath("rainbow_morph_animation/scene.gltf")); std::vector scene; createContexts(scene); for (auto& state : scene) { CUDA_CHECK(cudaSetDevice(state.device_idx)); //sutil::loadScene(infile.c_str(), state); sutil::loadScene(model_name, state); state.finalize(); initCameraState(state); allocIOBuffers(state, static_cast(scene.size())); } for (auto& state : scene) { initLaunchParams(state); } //OPTIX_CHECK(optixInit()); // Need to initialize function table if (outfile.empty()) { GLFWwindow* window = sutil::initUI("optixMeshViewer", width, height); glfwSetMouseButtonCallback(window, mouseButtonCallback); glfwSetCursorPosCallback(window, cursorPosCallback); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwSetWindowIconifyCallback(window, windowIconifyCallback); glfwSetKeyCallback(window, keyCallback); glfwSetScrollCallback(window, scrollCallback); //glfwSetWindowUserPointer(window, &scene[0].params);s // // Render loop // { sutil::CUDAOutputBuffer output_buffer(sutil::CUDAOutputBufferType::ZERO_COPY, width, height); output_buffer.setDevice(0); sutil::GLDisplay gl_display; std::chrono::duration state_update_time(0.0); std::chrono::duration render_time(0.0); std::chrono::duration display_time(0.0); do { auto t0 = std::chrono::steady_clock::now(); glfwPollEvents(); updateState(output_buffer, scene); auto t1 = std::chrono::steady_clock::now(); state_update_time += t1 - t0; t0 = t1; launchSubframe(output_buffer, scene); t1 = std::chrono::steady_clock::now(); render_time += t1 - t0; t0 = t1; displaySubframe(output_buffer, gl_display, window); t1 = std::chrono::steady_clock::now(); display_time += t1 - t0; sutil::displayStats(state_update_time, render_time, display_time); glfwSwapBuffers(window); for (auto& state : scene) ++state.params.subframe_index; } while (!glfwWindowShouldClose(window)); for (auto& state : scene) { CUDA_CHECK(cudaSetDevice(state.device_idx)); CUDA_SYNC_CHECK(); } } sutil::cleanupUI(window); } else { /* sutil::CUDAOutputBuffer output_buffer(sutil::CUDAOutputBufferType::ZERO_COPY, width, height); output_buffer.setDevice(0); handleCameraUpdate(scene); handleResize(output_buffer,scene); launchSubframe(output_buffer, scene); sutil::ImageBuffer buffer; buffer.data = output_buffer.getHostPointer(); buffer.width = output_buffer.width(); buffer.height = output_buffer.height(); buffer.pixel_format = sutil::BufferImageFormat::UNSIGNED_BYTE4; sutil::saveImage(outfile.c_str(), buffer, false);*/ } cleanup(scene); } catch (std::exception& e) { std::cerr << "Caught exception: " << e.what() << "\n"; } } //选择场景菜单 void submenufunc1(int data) { switch (data) { case 1: SceneID = 1; break; case 2: SceneID = 2; break; case 3: SceneID = 3; break; case 4: SceneID = 4; break; default: break; } } //选择GPU菜单 void submenufunc2(int data) { switch (data) { case 1: GpuNum = 1; break; case 2: GpuNum = 2; break; case 3: GpuNum = 3; break; case 4: GpuNum = 4; break; default: break; } } //创建场景菜单 void createScenemenu() { menu1 = glutCreateMenu(submenufunc1); glutAddMenuEntry("Scene 1", 1); glutAddMenuEntry("Scene 2", 2); glutAddMenuEntry("Scene 3", 3); glutAddMenuEntry("Scene 4", 4); glutAttachMenu(GLUT_LEFT_BUTTON); } //创建GPU菜单 void createGpumenu() { menu2 = glutCreateMenu(submenufunc2); glutAddMenuEntry("One", 1); glutAddMenuEntry("Two", 2); glutAddMenuEntry("Three",3); glutAddMenuEntry("Four", 4); glutAttachMenu(GLUT_LEFT_BUTTON); } //绘制文本 void DrawString(char* s) { GLuint TextFont; //申请MAX_CHAR个连续的显示列表编号 TextFont = glGenLists(MAX_CHAR); //把每个字符的绘制命令装到对应的显示列表中 wglUseFontBitmaps(wglGetCurrentDC(), 0, MAX_CHAR, TextFont); glPushAttrib(GL_LIST_BIT); //调用每个字符对应的显示列表,绘制每个字符 for (; *s != '\0'; ++s) glCallList(TextFont + *s); glPopAttrib(); } void display() { glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(0, 1, 1); glRectf(20, 110, 90, 140); glRectf(210, 110, 280, 140); glColor3f(0, 0, 0); glRasterPos2f(10, 265); DrawString("Choose Scene"); glRasterPos2f(10, 190); DrawString("Choose Gpu Num"); glRasterPos2f(40, 120); DrawString("Sure"); glRasterPos2f(225, 120); DrawString("Cancel"); glutSwapBuffers(); } void display3() { glClear(GL_COLOR_BUFFER_BIT); //场景输入参数 glColor3f(1.0, 1.0, 1.0); glRectf(0, 0, 110, 30); //场景文本框文字 glColor3f(0.0f, 0.0f, 0.0f); glRasterPos2f(30, 12); if (GpuNum == 1) DrawString("One"); else if (GpuNum == 2) DrawString("Two"); else if (GpuNum == 3) DrawString("Three"); else if (GpuNum == 4) DrawString("Four"); glutSwapBuffers(); } void display2() { glClear(GL_COLOR_BUFFER_BIT); //场景输入参数 glColor3f(1.0, 1.0, 1.0); glRectf(0, 0, 110, 30); //场景文本框文字 glColor3f(0.0f, 0.0f, 0.0f); glRasterPos2f(27, 12); if (SceneID == 1) DrawString("Scene 1"); else if (SceneID == 2) DrawString("Scene 2"); else if (SceneID == 3) DrawString("Scene 3"); else if (SceneID == 4) DrawString("Scene 4"); glutSwapBuffers(); } void display4() { glClearColor(1, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glColor3f(0,1,1); glRectf(60,100,130,130); glRectf(200,100,270,130); glColor3f(0, 0, 0); glRasterPos2f(150, 323); DrawString("GPU 1"); glRasterPos2f(150, 270); DrawString("GPU 2"); glRasterPos2f(150, 217); DrawString("GPU 3"); glRasterPos2f(150, 164); DrawString("GPU 4"); glRasterPos2f(80, 110); DrawString("Sure"); glRasterPos2f(209, 110); DrawString("Cancel"); glutSwapBuffers(); } void display5() { glClearColor(1, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); glutSwapBuffers(); } void Mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { hit_x = x; hit_y = fabs(300 - y); printf("x=%d,y=%d,hit_x=%d,hit_y=%d\n", x, y, hit_x, hit_y); if ((SceneID != 0) && (GpuNum != 0)) { if ((hit_x >= 20) && (hit_x <= 90) && (hit_y >= 110) && (hit_y <= 140)) { i = 0; memset(GpuID, 0, sizeof(GpuID)); glutInitalize4(); } if ((hit_x >= 210) && (hit_x <= 280) && (hit_y >= 110) && (hit_y <= 140)) { glutDestroyWindow(MainWindow); } } } } void window4Mouse(int button, int state, int x, int y) { hit_x = x; hit_y = fabs(400 - y); if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { printf("测试窗口:x=%d,y=%d,hit_x=%d,hit_y=%d\n", x, y,hit_x,hit_y); if ((hit_x >= 55) && (hit_x <= 130) && (hit_y >= 100) && (hit_y <= 150)) { huizong(); glutDestroyWindow(testwindow); printf("%d,%d,%d,%d\n", GpuID[0], GpuID[1], GpuID[2], GpuID[3]); } if((hit_x >= 190) && (hit_x <= 270) && (hit_y >= 100) && (hit_y <= 150)) { glutDestroyWindow(testwindow); i = 0; } } } void window5Mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (i < GpuNum*2) { GpuID[0] = 1; i++; glPointSize(60.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex2f(x, 30 - y); glEnd(); glutSwapBuffers(); } } } void window6Mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (i < GpuNum * 2) { GpuID[1] = 2; i++; glPointSize(60.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex2f(x, 30 - y); glEnd(); glutSwapBuffers(); } } } void window7Mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (i < GpuNum * 2) { GpuID[2] = 3; i++; glPointSize(60.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex2f(x, 30 - y); glEnd(); glutSwapBuffers(); } } } void window8Mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (i < GpuNum * 2) { GpuID[3] = 4; i++; glPointSize(60.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex2f(x, 30 - y); glEnd(); glutSwapBuffers(); } } } void glutInitalize5() { //GPU的选择窗口框 glutCreateSubWindow(testwindow, 80,50, 30, 30); gluOrtho2D(0, 30, 0, 30); glutDisplayFunc(display5); glutMouseFunc(window5Mouse); glutCreateSubWindow(testwindow, 80, 100, 30, 30); gluOrtho2D(0, 30, 0, 30); glutDisplayFunc(display5); glutMouseFunc(window6Mouse); glutCreateSubWindow(testwindow, 80, 150, 30, 30); gluOrtho2D(0, 30, 0, 30); glutDisplayFunc(display5); glutMouseFunc(window7Mouse); glutCreateSubWindow(testwindow, 80, 200, 30, 30); gluOrtho2D(0, 30, 0, 30); glutDisplayFunc(display5); glutMouseFunc(window8Mouse); } void glutInitalize4() { glutInitWindowSize(400, 400); testwindow = glutCreateWindow("选择GPU"); glutPositionWindow(500, 20); gluOrtho2D(0, 400, 0, 400); glutDisplayFunc(display4); glutMouseFunc(window4Mouse); glutInitalize5(); } void glutInitalize2() { //菜单栏的两个子窗口创建 glutCreateSubWindow(MainWindow, 130, 13, 110, 30); glClearColor(1, 0, 1, 1); gluOrtho2D(0, 110, 0, 30); glutDisplayFunc(display2); createScenemenu(); glutCreateSubWindow(MainWindow, 130, 80, 110, 30); glClearColor(1, 0, 1, 1); gluOrtho2D(0, 110, 0, 30); glutDisplayFunc(display3); createGpumenu(); } void glutInitalize() { glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(300, 300); MainWindow = glutCreateWindow("主窗口"); //define a window position for second window glutPositionWindow(520, 20); gluOrtho2D(0, 300, 0, 300); if (!gladLoadGL()) { std::cout << "Failed to initialize GLAD" << std::endl; } // register callbacks for second window, which is now current glutDisplayFunc(display); glutMouseFunc(Mouse); glutInitalize2(); glutMainLoop(); } #pragma endregion int main(int argc, char* argv[]) { //std::string infile =sutil::sampleDataFilePath("WaterBottle/box.gltf"); //std::string infile1 = sutil::sampleDataFilePath("/test-blender-gltf/source/Atrium.gltf"); //std::string infile = "E:\\chung\\obj2gltf-master\\scene_floor.gltf"; //std::string infile1 = "D:\\下载\\test-blender-gltf\\source\\Atrium.gltf"; glutInit(&argc, argv); glutInitalize(); //huizong(); return 0; }