2017-03-14 4 views
1

Ich erstelle gerade ein leichtgewichtiges Programm zum Betrachten und Bearbeiten von 3D-Objekten ähnlich dem Programm Blender oder 3DS max.Probleme mit dem Callback von GLFW glfwSetDropCallback auf Debian

Ich verwende C++, GLFW und OpenGL. Während ich plane, es plattformübergreifend zu haben, arbeite ich zur Zeit nur an einem Computer, auf dem Debian 9.0 (stretch) mit der XFCE-Desktop-Umgebung läuft.

Momentan scheint der Callback glfwSetDropCallback nie aufgerufen zu werden, egal was ich versuche. Ich habe Breakpoints gesetzt und behaupte aber nichts. Alle anderen Rückrufe, die ich ausprobiert habe, funktionieren gut. Ich habe meine GLFW cpp von meinem Projekt aufgenommen. Wenn etwas anderes benötigt wird, zögern Sie nicht zu fragen.

Auch als letzte Anmerkung verwende ich nur GLFW, weil alles andere zu schwer für meine Bedürfnisse scheint. Auch die Verwendung von X11 scheint für sehr wenig Gewinn eine Menge Arbeit zu sein, zumal ich für jedes Betriebssystem, das ich anvisiere, eine andere Lösung benötigen würde. Am Ende möchte ich nur Elemente in mein Programmfenster ziehen und ablegen können und dann meinen Code etwas mit dem/den Pfad (en) machen lassen.

#include "GLFWindow.h" 

#include <cassert> 
#include <iostream> 

// Variables for callback. 
static bool keys[1024]; 
static std::vector<std::string> dragAndDrop; 
static Camera* _camera; 
static GLdouble* _lastX; 
static GLdouble* _lastY; 

GLFWindow::GLFWindow() 
:m_window(nullptr), m_lastX(0.0), m_lastY(0.0) 
{ 
    glfwInit(); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GLFW_VERSION_MAJOR); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GLFW_VERSION_MINOR); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // For OSX 
    glfwWindowHint(GLFW_FOCUSED, GL_TRUE); 

    std::cout << glfwGetVersionString() << std::endl; 

    m_window = glfwCreateWindow(1920, 1080, "Model Viewer", /*glfwGetPrimaryMonitor()*/nullptr, nullptr); 
    if(m_window == nullptr) 
    { 
     std::cout << "Failed to create GLFW window" << std::endl; 
     glfwTerminate(); 
     assert(m_window != nullptr); 
    } 

    glfwMakeContextCurrent(m_window); 
    glfwSetWindowPos(m_window, 1920 - 1920/2, 1080 - 1080/2); 

    glfwSetKeyCallback(m_window, 
    [](GLFWwindow* window, int key, int, int action, int) 
    { 
     if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
      glfwSetWindowShouldClose(window, GL_TRUE); 

     if(action == GLFW_PRESS) 
      keys[key] = true; 
     else if(action == GLFW_RELEASE) 
      keys[key] = false; 
    }); 

    glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); 

    glfwSetCursorEnterCallback(m_window, 
    [](GLFWwindow* window, int entered) 
    { 
     if(entered) 
     { 
      double xPos, yPos; 
      glfwGetCursorPos(window, &xPos, &yPos); 

      *_lastX = xPos; 
      *_lastY = yPos; 
     } 
    }); 

    glfwSetDropCallback(m_window, 
    [](GLFWwindow*, int count, const char** paths) 
    { 
     std::cout << "Drag and Drop count - " << count << std::endl; 
     for(unsigned int i = 0; i < count; ++i) 
     { 
      std::cout << std::string(paths[i]) << std::endl; 
      dragAndDrop.push_back(std::string(paths[i])); 
     } 
    }); 
} 

GLFWindow::~GLFWindow() 
{ 
    glfwTerminate(); 
} 

GLint GLFWindow::GetWidth() 
{ 
    GLint width = 0; 
    glfwGetFramebufferSize(m_window, &width, nullptr); 
    return width; 
} 

GLint GLFWindow::GetHeight() 
{ 
    GLint height = 0; 
    glfwGetFramebufferSize(m_window, nullptr, &height); 
    return height; 
} 

std::string GLFWindow::GetDragAndDrop() 
{ 
    if(dragAndDrop.empty()) 
     return "END"; 

    std::string item = dragAndDrop[dragAndDrop.size()-1]; 
    dragAndDrop.pop_back(); 

    if(item.find(".obj") == std::string::npos && item.find(".fbx") == std::string::npos 
    && item.find(".OBJ") == std::string::npos && item.find(".FBX") == std::string::npos) 
     return "INVALID"; 

    return item; 
} 

bool GLFWindow::ShouldClose() 
{ 
    return glfwWindowShouldClose(m_window); 
} 

void GLFWindow::AddCamera(Camera* camera) 
{ 
    m_camera = camera; 

    _camera = m_camera; 
    _lastX = &m_lastX; 
    _lastY = &m_lastY; 

    glfwSetScrollCallback(m_window, 
    [](GLFWwindow*, double, double yoffset) 
    { 
     _camera->ProcessMouseScroll(yoffset); 
    }); 

    glfwSetCursorPosCallback(m_window, 
    [](GLFWwindow*, double xPos, double yPos) 
    { 
     GLfloat xOffset = xPos - *_lastX; 
     GLfloat yOffset = *_lastY - yPos; 

     *_lastX = xPos; 
     *_lastY = yPos; 
     _camera->ProcessMouseMovement(xOffset, yOffset); 
    }); 
} 

void GLFWindow::PollEvents(const GLfloat deltaTime) 
{ 
    glfwPollEvents(); 

    if(keys[GLFW_KEY_W]) 
     m_camera->ProcessKeyboard(0, deltaTime); 
    if(keys[GLFW_KEY_S]) 
     m_camera->ProcessKeyboard(1, deltaTime); 
    if(keys[GLFW_KEY_A]) 
     m_camera->ProcessKeyboard(2, deltaTime); 
    if(keys[GLFW_KEY_D]) 
     m_camera->ProcessKeyboard(3, deltaTime); 
    if(keys[GLFW_KEY_Q]) 
     m_camera->ProcessKeyboard(4, deltaTime); 
    if(keys[GLFW_KEY_E]) 
     m_camera->ProcessKeyboard(5, deltaTime); 
} 

GLfloat GLFWindow::GetElapsedTime() 
{ 
    return glfwGetTime(); 
} 

void GLFWindow::SwapBuffers() 
{ 
    glfwSwapBuffers(m_window); 
} 

Vielen Dank für Ihre Zeit, Brandon

Edit:

ich in einige X11-Code hinzugefügt, einige Dinge zu testen.

#include <X11/Xlib.h> 
#include <X11/Xutil.h> 
#include <X11/Xos.h> 

Display *display =XOpenDisplay((char *)0); 
if(XInternAtom(display, "XdndAware", False)) 
    std::cout << "Supported" << std::endl; 

Dieser Code gibt immer Unterstützung zurück. Ich glaube jetzt, dass es ein Fehler mit GLFW ist.

Final Edit: Dies war ein Fehler mit GLFW. Fehler ist wegen Thunar Bereitstellung von Text/URI-Liste während GLFW angenommen UTF8_STRING wurde unterstützt. Einfügung korrigieren Wenn jemand anderes dieses Problem hier hat, ist die Lösung. https://github.com/glfw/glfw/commit/6a65341e14bc7745c52fe86fe53be08dbd682dd9

Antwort

0

Edit:This was indeed a bug and has been resolved.

Zuerst stellen Sie sicher, dass Sie die neueste stabile Version GLFW (heute bekannt, dass 3.2.1 ist) verwenden.

Der naheliegendste Grund könnte sein, dass Sie niemals GLFWindow::PollEvents() anrufen und somit niemals glfwPollEvents() anrufen. Ich bezweifle jedoch, dass dies die Ursache ist, da Sie nie irgendwelche anderen Eingabeprobleme erwähnen.

Um zu überprüfen, ob es wirklich der Rückruf ist nie genannt zu werden, versuchen Sie dieses minimal Beispiel:

glfwInit(); 

// You might need some of the window hints 

GLFWwindow *window = glfwCreateWindow(600, 400, "Test glfwSetDropCallback", NULL, NULL); 

glfwSetDropCallback(window, [](GLFWwindow*, int count, const char **paths) 
{ 
    std::cout << "Drag and Drop count - " << count << std::endl; 

    for (unsigned int i = 0; i < count; ++i) 
     std::cout << "- " << paths[i] << std::endl; 
}); 

while (!glfwWindowShouldClose(window)) 
{ 
    glfwSwapBuffers(window); 
    glfwPollEvents(); 
} 

glfwDestroyWindow(window); 

glfwTerminate(); 

Getestet habe ich nur den obigen Code auf Windows und es funktionierte. Also wenn dieser Code nicht funktioniert. Dann könnte es ein X11-spezifischer Fehler sein und sollte unter GLFW's issue tracker gemeldet werden.

Wenn es immer noch nicht funktioniert. Bevor Sie einen Fehler feststellen, sollten Sie testen, ob Ihr Display sogar das Löschen von Dateien unterstützt. Das ist zwar X11-spezifisch. Sie würden es nur verwenden, um die Unterstützung zu überprüfen.

Beachten Sie, dass sich GLFW nicht beschwert, wenn das Ablegen von Dateien nicht unterstützt wird.

Es ist eine lange Zeit seit ich X11 berührt habe.Aber wenn ich mich richtig erinnere, würde die Überprüfung der Unterstützung für das Löschen von Dateien in etwa so aussehen:

Display *display = ... 
if (XInternAtom(display, "XdndAware", False)) 
    std::cout << "Supported" << std::endl; 
+0

Danke für die Antwort. Ich habe eine Weile (Fenster nicht geschlossen) in meinem Haupt, das für Ereignisse ähnlich Ihrem Beispiel abfragt. Sie haben also Recht, es ist nicht meine Ereignisabfrage. Ich habe ein neues Projekt erstellt und Ihren einfachen Codetest ausgeführt, ich sehe die gleichen Probleme wie zuvor. So klingt es wie es ist, was ich vermutete, entweder ein Fehler mit GLFW und X11 oder mein X11 ist nicht dafür konfiguriert. Ich habe sehr wenig Erfahrung direkt mit X11 Schnittstelle. Ich werde versuchen, Ihren zweiten Vorschlag zu testen, wenn ich einen Moment habe. – brantrap

+0

Auch ich rufe std :: cout << glfwGetVersionString() << std :: endl; zu Beginn meines Programms. Hier ist die Zeichenkette, die es druckt. 3.2.1 X11 GLX EGL clock_gettime/dev/js Xf86vm geteilt. – brantrap

+0

Okay, ich denke es ist ein Fehler und ich werde es an GLFW melden. Ich habe gerade den X11-Code ausgeführt, den Sie erwähnt haben, und er wurde unterstützt gemeldet. – brantrap