-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFBOScene.h
192 lines (155 loc) · 5.86 KB
/
FBOScene.h
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#ifndef FBO_SCENE_H
#define FBO_SCENE_H
#include "Scene.h"
#include "Shader.h"
#include "Model.h"
#include "OBJImporter.h"
#include <iostream>
#include <vector>
class FBOScene : public Scene
{
public:
FBOScene(GLFWwindow* window, unsigned int width, unsigned int height)
: Scene(window, width, height)
{
// Light position
lightPos = glm::vec3(1.2f, 1.0f, 2.0f);
// configure global opengl state
glEnable(GL_DEPTH_TEST);
// build and compile our shader zprogram
modelShader = new Shader("res/shaders/basic/basic.vs", "res/shaders/basic/basic.fs");
lampShader = new Shader("res/shaders/basic/lamp.vs", "res/shaders/basic/lamp.fs");
screenShader = new Shader("screen.vs", "screen.fs");
// Load models
cube = new Model("res/models/crate.obj");
lamp = new Model("res/models/cube.obj");
// Generate and bind to FBO
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// generate texture
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// attach it to currently bound framebuffer object
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
// Generate and bind render buffer for depth and stencil tests
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Attach rbo to fbo
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
// Check attachments and unbind fbo
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Create quad VAO
float quadVertices[] = {
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
}
void Draw()
{
Scene::Draw();
// render
// ------
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// view/projection transformations
projection = glm::perspective(glm::radians(camera.Zoom), (float)s_WindowWidth / (float)s_WindowHeight, 0.1f, 100.0f);
view = camera.GetViewMatrix();
// First pass - bind fbo
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // we're not using the stencil buffer now
glEnable(GL_DEPTH_TEST);
// Draw model
DrawModel();
// Draw lamp
DrawLamp();
// Second pass - unbind fbo
glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
screenShader->use();
screenShader->setInt("screenTexture", 0);
glBindVertexArray(quadVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
// Sandbox functions
void DrawModel()
{
// Bind textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);
// Set shader uniforms
modelShader->use();
modelShader->setMat4("projection", projection);
modelShader->setMat4("view", view);
modelShader->setInt("material.diffuse", 0);
modelShader->setInt("material.specular", 1);
modelShader->setFloat("material.shininess", 64.0f);
modelShader->setVec3("light.position", lightPos);
modelShader->setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
modelShader->setVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
modelShader->setVec3("light.specular", 1.0f, 1.0f, 1.0f);
modelShader->setVec3("viewPos", camera.Position);
glm::mat4 model;
modelShader->setMat4("model", model);
// render the model
cube->Draw(*modelShader);
}
void DrawLamp()
{
// also draw the lamp object
lampShader->use();
lampShader->setMat4("projection", projection);
lampShader->setMat4("view", view);
glm::mat4 model = glm::mat4();
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
lampShader->setMat4("model", model);
lamp->Draw(*lampShader);
}
private:
unsigned int framebuffer;
unsigned int rbo;
unsigned int texColorBuffer;
unsigned int quadVBO;
unsigned int quadVAO;
Shader* modelShader;
Shader* lampShader;
Shader* screenShader;
Model* cube;
Model* lamp;
unsigned int diffuseMap;
unsigned int specularMap;
// Matrices
glm::mat4 view;
glm::mat4 projection;
// lighting
glm::vec3 lightPos;
};
#endif