[英]GLFW (opengl) window closes when hovering mouse over the white window top handle
每當我使用 C++ 的 GLFW 庫為 opengl 中的測試光線追蹤器渲染 window 時,window 可以正常工作,如果我只是 hover,而不是在 8823470391978 之外,但它是否可以處理白色移動 window 或最小化它,window 和整個程序崩潰,沒有錯誤 output,即使我沒有在整個程序中使用任何 try-catch 塊或任何 noexcept 關鍵字,我正在使用std::shared_ptr
進行指針管理.
這是主要的 function(不是來自 glfw 或 opengl 的大寫變量在另一個文件中定義,但未初始化):
int main() {
if (!glfwInit()) ErrorExec("Couldn't init GLFW Engine");
glfwWindowHint(GLFW_RESIZABLE,GLFW_FALSE);
MAIN_WINDOW = glfwCreateWindow(WIDTH,HEIGHT,"Raytracer test" , NULL , NULL);
if (!MAIN_WINDOW) ErrorExec("Couldn't init Window");
glfwMakeContextCurrent(MAIN_WINDOW);
_InitGlobalVars();
_SetupMainPixels();
_SetupSkyboxPixels();
_SetupScene();
glfwSetCursorPosCallback(MAIN_WINDOW,mousePositionCallback);
while(!glfwWindowShouldClose(MAIN_WINDOW)) {
_UpdateKeyboardInput();
glClear(GL_COLOR_BUFFER_BIT);
RenderScene(MAIN_SCENE,RAY_BOUNCE_COUNT);
glDrawPixels(WIDTH,HEIGHT,GL_RGB,GL_UNSIGNED_BYTE,MAIN_PIXELS);
glfwSwapBuffers(MAIN_WINDOW);
glfwPollEvents();
};
glfwTerminate();
std::cout << "Exited ok!" << std::endl;
return 1;
};
這是光線追蹤算法:
#pragma once
#include <vector>
#include <iostream>
#include <thread>
#include <memory>
#include "./Settings.hpp"
#include "./Vec3.hpp"
#include "./MathFunctions.hpp"
#include "./Pixels.hpp"
#include "./ErrorHandler.hpp"
#include "./Abstract.hpp"
#include "./Objects.hpp"
#include "./Scene.hpp"
#include "./GlobalVars.hpp"
struct ClosestReturn {
Object* obj = nullptr;
float dist = -1;
int obj_index = -1;
};
//SCOPE
ClosestReturn findNearestObject(Ray& ray , Scene* scene);
Color colorAtScene(Ray& ray , Object& objHit , Vec3& hitPos , Scene* scene);
Color colorAtSkybox(Vec3& dir);
Color raytraceScene(Ray& ray , Scene* scene , float depth);
void renderScenePart(Scene* scene , unsigned int maxD , unsigned int minx , unsigned int miny , unsigned int maxx , unsigned int maxy , float AR);
void RenderScene(Scene* scene , int maxD);
//SCOPE
ClosestReturn findNearestObject(Ray& ray , Scene* scene) {
Object* objHit = nullptr;
float distMin = -1;
int k = 0 , index = 0;
for (Object* obj : scene->objects) {
float dist = obj->getIntersection(ray);
if (obj->isHittable() && dist>SURF_DIST && (objHit==nullptr || dist < distMin)) {
distMin = dist;
objHit = obj;
index = k;
};
k++;
};
return {objHit , distMin , index};
};
Color colorAtScene(Ray& ray , Object* objHit , Vec3& hitPos , Scene* scene) {
Material mat = objHit->getMaterial();
hitPos = hitPos + (objHit->getNormal(hitPos,ray.dir) * (-abs(SURF_DIST)));
Vec3 col = mat.col * mat.amb;
for (Light* light : scene->lights) {
Ray toLight = Ray(hitPos , (light->pos - hitPos).normalize());
Vec3 normal = objHit->getNormal(hitPos,toLight.dir);
ClosestReturn nearest = findNearestObject(toLight , scene);
if (nearest.dist<0 && nearest.obj==nullptr) {
//Light equation
col = (col + (light->col * mat.diff * std::max(normal * toLight.dir,0.0f * static_cast<float>((float)1/LIGHT_SOFTNESS)) * static_cast<float>((float)1/(hitPos.distVec(light->pos)*LIGHT_DIST)))).constrainVec(0.0f,255.0f);
};
};
return col.constrainVec(0.0f,255.0f);
};
Color colorAtSkybox(Vec3& dir) {
// AUX => return (Color(mapVal(dir.x,-1,1,0,255),mapVal(dir.y,-1,1,0,255),mapVal(dir.z,-2,2,0,255)).constrainVec(0.0f,255.0f));
int v = static_cast<int>(mapVal(static_cast<float>(0.5f + (atan2f(dir.z , dir.x) / (float)(2.0f * PI))),1,0,0,SKYBOX_WIDTH));
int u = static_cast<int>(mapVal(static_cast<float>(0.5f - (asinf(dir.y) / (float)PI)),1,0,0,SKYBOX_HEIGHT));
return (Color)GetSkyboxPixel(u,v);
};
Color raytraceScene(Ray& ray , Scene* scene , float depth) {
depth = constrainVal(depth,0,10);
Vec3 col = Vec3(0,0,0);
ClosestReturn nearest = findNearestObject(ray,scene);
if (nearest.obj==nullptr || nearest.obj_index < 0 || nearest.dist <= 0) return colorAtSkybox(ray.dir);
float distHit = nearest.dist;
Object* objHit = nearest.obj;
Vec3 hitPos = ray.atLength(distHit);
Vec3 hitNormal = objHit->getNormal(hitPos,ray.dir).normalize();
col = col + (colorAtScene(ray,objHit,hitPos,scene));
if (depth > 0) {
Vec3 new_pos = hitPos + (hitNormal * (abs(SURF_DIST)));
Vec3 new_dir = ray.dir.normalize().reflect(hitNormal);
Ray new_ray = Ray(new_pos,new_dir);
col = col + (raytraceScene(new_ray,scene,(depth-1)) * objHit->getMaterial().ref);
};
return ((col + (PIXEL_SKIP * 10)).constrainVec(0.0f,255.0f));
};
void renderScenePart(Scene* scene , unsigned int maxD , unsigned int minx , unsigned int miny , unsigned int maxx , unsigned int maxy , float AR) {
for (unsigned int wy = miny ; wy < maxy ; wy+=PIXEL_SKIP) {
float ry = static_cast<float>(mapVal(wy,0,HEIGHT,-1,1));
for (unsigned int wx = minx ; wx < maxx ; wx+=PIXEL_SKIP) {
float rx = static_cast<float>(mapVal(wx,0,WIDTH,-1-AR,1+AR));
Ray shootRay = Ray(scene->camera.pos , Vec3(rx,ry,CAMERA_FOV).normalize().rotate(scene->camera.dir.x , scene->camera.dir.y));
SetMainPixel(wx,wy,(raytraceScene(shootRay,scene,maxD)).constrainVec(0.0f,255.0f));
};
};
};
void RenderScene(Scene* scene , unsigned int maxD) {
unsigned int partWidth = (unsigned int)WIDTH/THREAD_COUNT_SQ;
unsigned int partHeight = (unsigned int)HEIGHT/THREAD_COUNT_SQ;
float ar = (float)WIDTH/HEIGHT;
std::thread threads[THREAD_COUNT];
int k = 0;
for (unsigned int y = 0 ; y < THREAD_COUNT_SQ ; y++) {
for (unsigned int x = 0 ; x < THREAD_COUNT_SQ ; x++) {
threads[k] = std::thread(renderScenePart,std::ref(scene),maxD,x*partWidth,y*partHeight,x*partWidth + partWidth , y*partHeight + partHeight , ar);
//threads[k].join();
k++;
};
};
for (std::thread& t : threads) {
t.join();
};
};
最后一個是導致問題的那個。 我正在使用g++ Main.cpp -o main.exe -lgdi32 -lopengl32 -lglfw3dll -lglu32 -pthread -Wall -Wextra
使用 MinGW 編譯器編譯主文件。 提前致謝!
感謝評論部分的 Retired Ninja,我想我已經找到了問題所在。 我將代碼減少到幾行,忘記了網格系統和所有其他東西。 顯然,當我抓取 window 時,主線程似乎在我完成移動它之前處於睡眠狀態,並且在光線跟蹤算法中我正在實例化新線程,因此當主線程睡眠時,大多數時候它不會等待(又名“join()”),因為我將指針傳遞給那些線程,這些線程似乎填滿了 memory 並崩潰。 我已經添加了一個系統,在主線程運行時也讓工作線程休眠,它工作得很好。現在我要看看如何在 cuda XD 中做到這一點,不過,謝謝大家!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.