WoW Model Viewer
Your premiere tool for viewing, equipping and animating World of Warcraft models.
Loading...
Searching...
No Matches
Renderer.cpp
Go to the documentation of this file.
1#include "Renderer.h"
2#include "OrbitCamera.h"
3#include "ViewportFBO.h"
4
5#include <glad/gl.h>
6#include <glm/gtc/type_ptr.hpp>
7#include <glm/gtc/matrix_transform.hpp>
8
13
14// ---- Lifecycle -------------------------------------------------------------
15
17{
18 const unsigned char pixels[2 * 2 * 4] = {
19 56, 56, 56, 255, 46, 46, 46, 255,
20 46, 46, 46, 255, 56, 56, 56, 255,
21 };
22 glGenTextures(1, &m_checkerTex);
23 glBindTexture(GL_TEXTURE_2D, m_checkerTex);
24 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0,
25 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
28 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
30 glBindTexture(GL_TEXTURE_2D, 0);
31}
32
34{
35 if (m_checkerTex)
36 {
37 glDeleteTextures(1, &m_checkerTex);
38 m_checkerTex = 0;
39 }
40}
41
42// ---- Lighting --------------------------------------------------------------
43
45{
46 if (!L.enabled)
47 {
48 glDisable(GL_LIGHTING);
49 return;
50 }
51
52 glEnable(GL_LIGHTING);
53
55 {
56 glDisable(GL_LIGHT0);
57 GLfloat modelAmb[] = { L.ambient[0], L.ambient[1], L.ambient[2], 1.0f };
58 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
59 return;
60 }
61
62 glEnable(GL_LIGHT0);
63
64 GLfloat pos[4];
66 {
67 pos[0] = L.direction[0];
68 pos[1] = L.direction[1];
69 pos[2] = L.direction[2];
70 pos[3] = 0.0f;
71 }
72 else
73 {
74 pos[0] = L.position[0];
75 pos[1] = L.position[1];
76 pos[2] = L.position[2];
77 pos[3] = 1.0f;
78 }
79
80 float i = L.intensity;
81 GLfloat diffuse[] = { L.diffuse[0] * i, L.diffuse[1] * i,
82 L.diffuse[2] * i, 1.0f };
83 GLfloat ambient[] = { L.ambient[0], L.ambient[1], L.ambient[2], 1.0f };
84 GLfloat specular[] = { L.specular[0] * i, L.specular[1] * i,
85 L.specular[2] * i, 1.0f };
86
87 glLightfv(GL_LIGHT0, GL_POSITION, pos);
88 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
89 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
90 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
91
92 if (L.type == LightType::Spot)
93 {
94 GLfloat spotDir[] = { L.direction[0], L.direction[1], L.direction[2] };
95 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);
96 glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, L.spotCutoff);
97 glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, L.spotExponent);
98 }
99 else
100 {
101 glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f);
102 }
103
104 GLfloat modelAmb[] = { L.ambient[0], L.ambient[1], L.ambient[2], 1.0f };
105 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
106}
107
108// ---- Checkerboard background -----------------------------------------------
109
111{
112 glMatrixMode(GL_PROJECTION);
113 glPushMatrix();
114 glLoadIdentity();
115 glOrtho(0, w, 0, h, -1, 1);
116
117 glMatrixMode(GL_MODELVIEW);
118 glPushMatrix();
119 glLoadIdentity();
120
121 glDisable(GL_DEPTH_TEST);
122 glDisable(GL_LIGHTING);
123 glEnable(GL_TEXTURE_2D);
124
125 glBindTexture(GL_TEXTURE_2D, m_checkerTex);
126 glColor3f(1.0f, 1.0f, 1.0f);
127
128 const float tileSize = 16.0f;
129 float u = static_cast<float>(w) / (tileSize * 2.0f);
130 float v = static_cast<float>(h) / (tileSize * 2.0f);
131
132 glBegin(GL_QUADS);
133 glTexCoord2f(0, 0); glVertex2f(0, 0);
134 glTexCoord2f(u, 0); glVertex2f(static_cast<float>(w), 0);
135 glTexCoord2f(u, v); glVertex2f(static_cast<float>(w), static_cast<float>(h));
136 glTexCoord2f(0, v); glVertex2f(0, static_cast<float>(h));
137 glEnd();
138
139 glBindTexture(GL_TEXTURE_2D, 0);
140 glDisable(GL_TEXTURE_2D);
141 glEnable(GL_DEPTH_TEST);
142
143 glMatrixMode(GL_PROJECTION);
144 glPopMatrix();
145 glMatrixMode(GL_MODELVIEW);
146 glPopMatrix();
147}
148
149// ---- Gradient background ---------------------------------------------------
150
151void Renderer::drawGradient(int w, int h,
152 const glm::vec3& top, const glm::vec3& bottom)
153{
154 glMatrixMode(GL_PROJECTION);
155 glPushMatrix();
156 glLoadIdentity();
157 glOrtho(0, w, 0, h, -1, 1);
158
159 glMatrixMode(GL_MODELVIEW);
160 glPushMatrix();
161 glLoadIdentity();
162
163 glDisable(GL_DEPTH_TEST);
164 glDisable(GL_LIGHTING);
165 glDisable(GL_TEXTURE_2D);
166
167 glBegin(GL_QUADS);
168 glColor3f(bottom.x, bottom.y, bottom.z);
169 glVertex2f(0, 0);
170 glVertex2f(static_cast<float>(w), 0);
171 glColor3f(top.x, top.y, top.z);
172 glVertex2f(static_cast<float>(w), static_cast<float>(h));
173 glVertex2f(0, static_cast<float>(h));
174 glEnd();
175
176 glEnable(GL_DEPTH_TEST);
177
178 glMatrixMode(GL_PROJECTION);
179 glPopMatrix();
180 glMatrixMode(GL_MODELVIEW);
181 glPopMatrix();
182}
183
184// ---- Ground grid -----------------------------------------------------------
185
186void Renderer::drawGrid(float gridSize, float step)
187{
188 glDisable(GL_TEXTURE_2D);
189 glDisable(GL_LIGHTING);
190
191 glLineWidth(1.0f);
192 glColor4f(0.55f, 0.55f, 0.55f, 0.6f);
193 glEnable(GL_BLEND);
194 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
195
196 glBegin(GL_LINES);
197 for (float i = -gridSize; i <= gridSize; i += step)
198 {
199 if (i == 0.0f) continue;
200 glVertex3f(-gridSize, i, 0.0f);
201 glVertex3f( gridSize, i, 0.0f);
202 glVertex3f(i, -gridSize, 0.0f);
203 glVertex3f(i, gridSize, 0.0f);
204 }
205 glEnd();
206
207 glLineWidth(2.0f);
208 glColor3f(0.2f, 0.5f, 1.0f);
209 glBegin(GL_LINES);
210 glVertex3f(-gridSize, 0.0f, 0.0f);
211 glVertex3f( gridSize, 0.0f, 0.0f);
212 glVertex3f(0.0f, -gridSize, 0.0f);
213 glVertex3f(0.0f, gridSize, 0.0f);
214 glEnd();
215
216 glLineWidth(1.0f);
217 glDisable(GL_BLEND);
218 glEnable(GL_LIGHTING);
219 glEnable(GL_TEXTURE_2D);
220}
221
222// ---- Projection & view -----------------------------------------------------
223
224void Renderer::applyProjection(int w, int h, float fov,
225 float nearPlane, float farPlane)
226{
227 glMatrixMode(GL_PROJECTION);
228 glLoadIdentity();
229 glm::mat4 proj = glm::perspective(
230 fov, static_cast<float>(w) / static_cast<float>(h),
231 nearPlane, farPlane);
232 glMultMatrixf(glm::value_ptr(proj));
233}
234
235void Renderer::applyView(const glm::mat4& viewMatrix)
236{
237 glMatrixMode(GL_MODELVIEW);
238 glLoadIdentity();
239 glMultMatrixf(glm::value_ptr(viewMatrix));
240}
241
242// ---- FBO pass management ---------------------------------------------------
243
244void Renderer::beginPass(ViewportFBO& fbo, int w, int h,
245 const glm::vec3& clearColor)
246{
247 fbo.resize(w, h);
248 fbo.bind();
249 glViewport(0, 0, w, h);
250 glClearColor(clearColor.x, clearColor.y, clearColor.z, 1.0f);
251 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
252}
253
255{
256 fbo.unbind();
257}
258
259// ---- Convenience helpers ---------------------------------------------------
260
265
266void Renderer::drawBackground(int w, int h)
267{
269 {
271 }
273 {
274 drawCheckerboard(w, h);
275 }
276}
277
278// ---- Composite render pass -------------------------------------------------
279
280void Renderer::renderScene(ViewportFBO& fbo, int w, int h,
281 const OrbitCamera& camera, float fov,
282 const glm::vec3& clearColor, bool drawGridFlag,
283 const std::function<void()>& drawObjects)
284{
285 if (w <= 0 || h <= 0)
286 return;
287
288 beginPass(fbo, w, h, clearColor);
289
290 drawBackground(w, h);
291 glClear(GL_DEPTH_BUFFER_BIT);
292
293 applyProjection(w, h, fov);
294 applyView(camera.getViewMatrix());
295
297
298 if (drawGridFlag)
299 drawGrid();
300
301 if (drawObjects)
302 {
303 glEnable(GL_NORMALIZE);
304 drawObjects();
305 glDisable(GL_NORMALIZE);
306 }
307
308 endPass(fbo);
309}
Orbit camera that revolves around a target point.
Definition OrbitCamera.h:10
glm::mat4 getViewMatrix() const
Compute the current view matrix from yaw, pitch, and radius.
RenderState m_state
Definition Renderer.h:122
void renderScene(ViewportFBO &fbo, int w, int h, const OrbitCamera &camera, float fov, const glm::vec3 &clearColor, bool drawGrid, const std::function< void()> &drawObjects)
Definition Renderer.cpp:280
void applyProjection(int w, int h, float fov, float nearPlane=0.1f, float farPlane=6400.0f)
Load a perspective projection matrix.
Definition Renderer.cpp:224
void beginPass(ViewportFBO &fbo, int w, int h, const glm::vec3 &clearColor)
Begin an off-screen FBO render pass (resize, bind, clear).
Definition Renderer.cpp:244
void init()
Create GPU resources. Call once after the OpenGL context is current.
Definition Renderer.cpp:16
void applyLighting()
Configure OpenGL fixed-function lighting from the current state.
Definition Renderer.cpp:261
void drawGrid(float size=40.0f, float step=1.0f)
Draw a ground grid with highlighted centre axes.
Definition Renderer.cpp:186
void drawBackground(int w, int h)
Draw the background (checker or gradient) based on current state.
Definition Renderer.cpp:266
void drawCheckerboard(int w, int h)
Draw a tiled checkerboard pattern in screen space.
Definition Renderer.cpp:110
GLuint m_checkerTex
Definition Renderer.h:121
void shutdown()
Release GPU resources.
Definition Renderer.cpp:33
void applyView(const glm::mat4 &viewMatrix)
Load a view (camera) matrix.
Definition Renderer.cpp:235
void endPass(ViewportFBO &fbo)
End the current FBO render pass (unbind).
Definition Renderer.cpp:254
void drawGradient(int w, int h, const glm::vec3 &top, const glm::vec3 &bottom)
Draw a vertical gradient quad in screen space.
Definition Renderer.cpp:151
~Renderer()
Definition Renderer.cpp:9
Plain-data description of a single light source.
Definition Renderer.h:32
glm::vec3 gradientBottom
Definition Renderer.h:52
glm::vec3 gradientTop
Definition Renderer.h:51
LightSettings light
Definition Renderer.h:48
Simple OpenGL framebuffer object wrapper for off-screen rendering.
Definition ViewportFBO.h:10
void bind() const
Bind this FBO as the current render target.
Definition ViewportFBO.h:53
void resize(int w, int h)
Resize the FBO; destroys and recreates if dimensions changed.
Definition ViewportFBO.h:43
void unbind() const
Unbind (revert to the default framebuffer).
Definition ViewportFBO.h:56