aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Graphics/Canvas.cpp
blob: d34731a0f6e285c815f73ede0f8960c1b11f5422 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "../jin_configuration.h"
#if LIBJIN_MODULES_RENDER

#include "../utils/macros.h"
#include "canvas.h" 
#include "window.h"

namespace jin
{
namespace graphics
{

    /*class member*/ const Canvas* Canvas::current = nullptr;
    /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0);

    /*class member*/ Canvas* Canvas::createCanvas(int w, int h)
    {
        return new Canvas(w, h);
    }

    Canvas::Canvas(GLuint n) 
        : fbo(n)
    {
    }

    Canvas::Canvas(int w, int h) 
        : Drawable(w, h)
    {
        GLint current_fbo;
        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);

        /* generate a new render buffer object */
		fbo = gl.genFrameBuffer();
		gl.bindFrameBuffer(fbo);

        /* generate texture save target */
		texture = gl.genTexture();
        gl.bindTexture(texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        gl.bindTexture(0);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

        /* unbind framebuffer */
		gl.bindFrameBuffer(current_fbo);
    }

    Canvas::~Canvas()
    {
    }

    /*class member*/ bool Canvas::isBinded(const Canvas* cvs)
    {
        return current == cvs;
    }

    /**
    * bind to canvas 
    */
    /*class member*/ void Canvas::bind(Canvas* canvas)
    {
        if (isBinded(canvas)) return;
        current = canvas;
        gl.bindFrameBuffer(canvas->fbo);
        int w = canvas->size.w; 
        int h = canvas->size.h;
        /* set view port to canvas */
        glViewport(0, 0, w, h);
        gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1);
    }

    /**
    * bind to default screen render buffer. 
    * do some coordinates transform work
    * https://blog.csdn.net/liji_digital/article/details/79370841
    * https://blog.csdn.net/lyx2007825/article/details/8792475
    */
    /*class member*/ void Canvas::unbind()
    {
        if (isBinded(DEFAULT_CANVAS)) return;
        current = DEFAULT_CANVAS;
        /* get window size as viewport */
        Window* wnd = Window::get();
        int w = wnd->getW();
        int h = wnd->getH();

        glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo);

        /* set viewport on screen */
        glViewport(0, 0, w, h);

        gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1);

    }

} // render
} // jin

#endif // LIBJIN_MODULES_RENDER