【问题标题】:Function was not declared in scope (GLFW, OpenGL, Slackware)函数未在范围内声明(GLFW、OpenGL、Slackware)
【发布时间】:2018-06-07 16:34:09
【问题描述】:

我正在尝试在 Linux 上使用 g++ 编译我的第一个 GL 简单程序:

-lxcb-dri2 -lxcb-lm -ldl -lXrender -ldrm -lXdamage -lX11-xcb -lxcb-glx -dri3 -lL/usr/local/lib -lrt -lXrandr -lXinerama -lXi -lXcursor -lGL - lm xcb-present -lglfw -lxcb-sync -lxshmfence -lXxf86vm -lXfixes -lXext -lX11 -lpthread -lxcb -lXau -lXdmcp -lGLEW

我遇到了这个错误:

graphics/window.cpp: In member function 'bool je::graphics::Window::init()':
graphics/window.cpp:55:32: error: 'key_callback' was not declared in this scope glfwSetKeyCallback(m_Window, key_callback);

我的代码在三个文件中。

main.cpp:

#include "graphics/window.h"

int main()
{
    using namespace je;
    using namespace graphics;

    Window window("just engine", 800, 600);
    glClearColor(0.2f, 0.3f, 0.8f, 1.0f);

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    while (!window.closed())
    {
        window.clear();
        if (window.isKeyPressed(GLFW_KEY_A))
        {
            std::cout << "PRESSED!" << std::endl;
        }

        glDrawArrays(GL_ARRAY_BUFFER, 0, 6);
        window.update();
    }
    return 0;
}

window.h:

#pragma once
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

namespace je{ namespace graphics{

#define MAX_KEYS    1024
#define MAX_BUTTONS     32

    class Window
    {
    private:

        const char *m_Title;
        int m_Width, m_Height;
        GLFWwindow *m_Window;
        bool m_Closed;
                static bool m_Keys[MAX_KEYS];
                static bool m_MouseButtons[MAX_BUTTONS];
                static double mx, my;
    public:
        Window(const char *name, int width, int height);
        ~Window();
                void clear() const;
        void update();
                bool closed() const;

        inline int getWidth() const {return m_Width; }
        int getHeight() const {return m_Height; }

        static bool isKeyPressed(unsigned int keycode);
        //friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
    private:
        bool init();
        friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
    };
}}

window.cpp:

#include "window.h"
#include <GLFW/glfw3.h>

namespace je{ namespace graphics {


    bool Window::m_Keys[MAX_KEYS];
    bool Window::m_MouseButtons[MAX_BUTTONS];
    double Window::mx;
    double Window::my;
    void window_resize(GLFWwindow *window, int width, int height);
    Window::Window(const char *title, int width, int height)
    {
        m_Title = title;
        m_Width = width;
        m_Height = height;
        if (!init())
            glfwTerminate();


        for (int i = 0; i < MAX_KEYS; i++)
        {
            m_Keys[i] = false;
        }
        for (int i = 0; i < MAX_BUTTONS; i++)
        {
            m_MouseButtons[i] = false;
        }
    }

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

    bool Window::init()
    {

            if(!glfwInit())
            {
                std::cout << "Failed to initialize GLFW" << std::endl;
            return false;
        }
        m_Window = glfwCreateWindow(m_Width, m_Height, m_Title, NULL, NULL);
        if (!m_Window)
        {
            glfwTerminate();
            std::cout << "Creating window failed." << std::endl;
            return false;
        }

        glfwMakeContextCurrent(m_Window);
        glfwSetWindowUserPointer(m_Window, this);
        glfwSetWindowSizeCallback(m_Window, window_resize);
        glfwSetKeyCallback(m_Window, key_callback);

        if (glewInit() != GLEW_OK)
        {
            std::cout << "Could not initialize GLEW!" << std::endl;
            return false;
        }

                std::cout << "OpenGL " << glGetString(GL_VERSION) << std::endl;

        return true;
    }

        bool Window::isKeyPressed(unsigned int keycode)
    {
        if (keycode >= MAX_KEYS)
            return false;
        return m_Keys[keycode];
    }


    void Window::clear() const
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }

    void Window::update()
    {
        glfwPollEvents();
        glfwGetFramebufferSize(m_Window, &m_Width, &m_Height);
        glfwSwapBuffers(m_Window);
    }

        bool Window::closed() const
        {
                return glfwWindowShouldClose(m_Window) == 1;
        }

    void window_resize(GLFWwindow *window, int width, int height)
    {
        glViewport(0, 0, width, height);
    }

        void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    {
        Window* win = (Window*) glfwGetWindowUserPointer(window);
        win->m_Keys[key] = action != GLFW_RELEASE;
    }
} }

我真的是初学者,我迷路了......你能帮我找到方法吗?谢谢。

【问题讨论】:

  • 你 key_callback(...) 是一个成员函数,你不能用它作为参数。您应该创建一个包装器或将其定义为静态或简单地在类之外定义它。
  • 请始终缩进代码。缩进时不要混合制表符和空格。为了便于阅读,在函数之间放置 2 或 3 个(保持一致)空行。
  • 看起来您是在使用 C++ 而不是 C 进行编程。C 语言没有类、构造函数或析构函数。我建议你调整标签。

标签: c++


【解决方案1】:

要使用 C++ 成员函数 void key_callback(),作为 C 实现的库函数 glfwSetKeyCallback() 的参数,您应该将其声明为 static,但首先要在类声明之外。因此,请为您的 window.h 尝试类似的操作。

class Window;
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);

class Window {
    private:
        // fields here

    public:
        // other member functions here

    private:
        friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
};

然后在window.cpp中:

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    Window* win = (Window*) glfwGetWindowUserPointer(window);
    win->m_Keys[key] = action != GLFW_RELEASE;
}

我没有写过这个 glfw 库,所以我的回答可能不足以满足您的目的。看看这些问题:Pointing to a function that is a class memberIs it possible to declare a friend function as static?

【讨论】:

  • 非常感谢!仅编辑 window.h 对我有用。
猜你喜欢
  • 2014-03-13
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-29
相关资源
最近更新 更多