理解OpenGLSuperbible7-窗口和GLContext

来源:互联网 发布:优酷mac下的视频在哪里 编辑:程序博客网 时间:2024/06/06 08:50
#pragma once

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <cmath>

#include <GL/glew.h>
#include <GL/glxew.h>
#include <GLFW/glfw3.h>

#include <GL/gl.h>
#include <GL/glext.h>
class GLApplication
{
public:
    GLApplication();
    virtual ~GLApplication();
    virtual void run(GLApplication* app);
    virtual void init();
    virtual void startup();
    virtual void render(double currentTime);
    virtual void shutdown();
    virtual void onResize(int w, int h);
    virtual void onKey(int key, int action);
    virtual void onMouseButton(int button, int action);
    virtual void onMouseMove(int x, int y);
    virtual void onMouseWheel(int pos);
    virtual void onDebugMessage(GLenum source,
                                GLenum type,
                                GLuint id,
                                GLenum severity,
                                GLsizei length,
                                const GLchar* message);
    void getMousePosition(int& x, int& y);
    void setWindowTitle(const char * title);
public:
    struct APPINFO
    {
        char title[128];
        int windowWidth;
        int windowHeight;
        int majorVersion;
        int minorVersion;
        int samples;
        union
        {
            struct
            {
                unsigned int    fullscreen  : 1;
                unsigned int    vsync       : 1;
                unsigned int    cursor      : 1;
                unsigned int    stereo      : 1;
                unsigned int    debug       : 1;
                unsigned int    robust      : 1;
            };
            unsigned int        all;
        } flags;
    };

protected:
    APPINFO     mInfo;
    static      GLApplication * mApp;
    GLFWwindow* mWindow;

    static void glfwOnResize(GLFWwindow* window, int w, int h);
    static void glfwOnKey(GLFWwindow* window, int key, int scancode, int action, int mods);
    static void glfwOnMouseButton(GLFWwindow* window, int button, int action, int mods);
    static void glfwOnMouseMove(GLFWwindow* window, double x, double y);
    static void glfwOnMouseWheel(GLFWwindow* window, double xoffset, double yoffset);
    void setVsync(bool enable);
};


#define DECLARE_MAIN(a)                             \
int main(int argc, const char ** argv)              \
{                                                   \
    a *app = new a;                                 \
    app->run(app);                                  \
    delete app;                                     \
    return 0;                                       \
}


#include "GLContext.h"

GLApplication* GLApplication::mApp = NULL;

GLApplication::GLApplication()
{
}

GLApplication::~GLApplication()
{
}

void GLApplication::run(GLApplication* app)
{
    bool running = true;
    mApp = app;

    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW\n");
        return;
    }

    init();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, mInfo.majorVersion);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, mInfo.minorVersion);

#ifndef _DEBUG
    if (mInfo.flags.debug)
#endif
    {
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
    }
    if (mInfo.flags.robust)
    {
        glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, GLFW_LOSE_CONTEXT_ON_RESET);
    }
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_SAMPLES, mInfo.samples);
    glfwWindowHint(GLFW_STEREO, mInfo.flags.stereo ? GL_TRUE : GL_FALSE);

    if (mInfo.flags.fullscreen)
    {
        if (mInfo.windowWidth == 0 || mInfo.windowHeight == 0)
        {
            GLFWmonitor* monitor = glfwGetPrimaryMonitor();
            if (monitor)
            {
                const GLFWvidmode* mode = glfwGetVideoMode(monitor);
                mInfo.windowWidth = mode->width;
                mInfo.windowHeight = mode->height;
            }
        }
    }
    mWindow = glfwCreateWindow(mInfo.windowWidth, mInfo.windowHeight, mInfo.title, mInfo.flags.fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL);
    if (!mWindow)
    {
        fprintf(stderr, "Failed to open window\n");
        return;
    }

    glfwMakeContextCurrent(mWindow);

    if (glewInit() != GLEW_OK)
    {
        fprintf(stderr, "Failed to initialize GLEW\n");
        getchar();
        glfwTerminate();
        return;
    }

    glfwSetWindowSizeCallback(mWindow, glfwOnResize);
    glfwSetKeyCallback(mWindow, glfwOnKey);
    glfwSetMouseButtonCallback(mWindow, glfwOnMouseButton);
    glfwSetCursorPosCallback(mWindow, glfwOnMouseMove);
    glfwSetScrollCallback(mWindow, glfwOnMouseWheel);

    if (!mInfo.flags.cursor)
    {
        glfwSetInputMode(mWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
    }

    // mInfo.flags.stereo = (glfwGetWindowParam(GLFW_STEREO) ? 1 : 0);

#ifdef _DEBUG
    fprintf(stderr, "VENDOR: %s\n", (char *)glGetString(GL_VENDOR));
    fprintf(stderr, "VERSION: %s\n", (char *)glGetString(GL_VERSION));
    fprintf(stderr, "RENDERER: %s\n", (char *)glGetString(GL_RENDERER));
#endif

//    if (mInfo.flags.debug)
//    {
//        if (gl3wIsSupported(4, 3))
//        {
//            glDebugMessageCallback((GLDEBUGPROC)debug_callback, this);
//            glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
//        }
//        else if (sb6IsExtensionSupported("GL_ARB_debug_output"))
//        {
//            glDebugMessageCallbackARB((GLDEBUGPROC)debug_callback, this);
//            glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
//        }
//    }

    startup();
    do
    {
         render(glfwGetTime());

         glfwSwapBuffers(mWindow);
         glfwPollEvents();

         running &= (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_RELEASE);
         running &= (glfwWindowShouldClose(mWindow) != GL_TRUE);
     } while (running);

     shutdown();

     glfwDestroyWindow(mWindow);
     glfwTerminate();
}

void GLApplication::init()
{
    strcpy(mInfo.title, "OpenGL Example");
    mInfo.windowWidth = 800;
    mInfo.windowHeight = 600;
#ifdef __APPLE__
    mInfo.majorVersion = 3;
    mInfo.minorVersion = 2;
#else
    mInfo.majorVersion = 4;
    mInfo.minorVersion = 3;
#endif
    mInfo.samples = 0;
    mInfo.flags.all = 0;
    mInfo.flags.cursor = 1;
#ifdef _DEBUG
    mInfo.flags.debug = 1;
#endif
}

void GLApplication::startup()
{
}

void GLApplication::render(double currentTime)
{
}

void GLApplication::shutdown()
{
}

void GLApplication::setWindowTitle(const char * title)
{
    glfwSetWindowTitle(mWindow, title);
}

void GLApplication::onResize(int w, int h)
{
    mInfo.windowWidth = w;
    mInfo.windowHeight = h;
}

void GLApplication::onKey(int key, int action)
{
}

void GLApplication::onMouseButton(int button, int action)
{
}

void GLApplication::onMouseMove(int x, int y)
{
}

void GLApplication::onMouseWheel(int pos)
{
}

void GLApplication::onDebugMessage(GLenum source,
                            GLenum type,
                            GLuint id,
                            GLenum severity,
                            GLsizei length,
                            const GLchar* message)
{
#ifdef _WIN32
    OutputDebugStringA(message);
    OutputDebugStringA("\n");
#endif
}

void GLApplication::getMousePosition(int& x, int& y)
{
    double dx, dy;
    glfwGetCursorPos(mWindow, &dx, &dy);

    x = static_cast<int>(floor(dx));
    y = static_cast<int>(floor(dy));
}

void GLApplication::glfwOnResize(GLFWwindow* window, int w, int h)
{
    mApp->onResize(w, h);
}

void GLApplication::glfwOnKey(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    mApp->onKey(key, action);
}

void GLApplication::glfwOnMouseButton(GLFWwindow* window, int button, int action, int mods)
{
    mApp->onMouseButton(button, action);
}

void GLApplication::glfwOnMouseMove(GLFWwindow* window, double x, double y)
{
    mApp->onMouseMove(static_cast<int>(x), static_cast<int>(y));
}

void GLApplication::glfwOnMouseWheel(GLFWwindow* window, double xoffset, double yoffset)
{
    mApp->onMouseWheel(static_cast<int>(yoffset));
}

void GLApplication::setVsync(bool enable)
{
    mInfo.flags.vsync = enable ? 1 : 0;
    glfwSwapInterval((int)mInfo.flags.vsync);
}



//#if defined _WIN32
//#define DECLARE_MAIN(a)                             \
//sb7::application *app = 0;                          \
//int CALLBACK WinMain(HINSTANCE hInstance,           \
//                     HINSTANCE hPrevInstance,       \
//                     LPSTR lpCmdLine,               \
//                     int nCmdShow)                  \
//{                                                   \
//    a *app = new a;                                 \
//    app->run(app);                                  \
//    delete app;                                     \
//    return 0;                                       \
//}
//#elif defined _LINUX || defined __APPLE__
//#define DECLARE_MAIN(a)                             \
//int main(int argc, const char ** argv)              \
//{                                                   \
//    a *app = new a;                                 \
//    app->run(app);                                  \
//    delete app;                                     \
//    return 0;                                       \
//}
//#else
//#error Undefined platform!
//#endif

//#endif








0 0
原创粉丝点击