Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/multiview/Multiview.cpp
1693 views
1
//
2
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
// This sample shows basic usage of the GL_OVR_multiview2 extension.
7
8
#include "SampleApplication.h"
9
10
#include "util/geometry_utils.h"
11
#include "util/shader_utils.h"
12
13
#include <iostream>
14
15
namespace
16
{
17
18
void FillTranslationMatrix(float xOffset, float yOffset, float zOffset, float *matrix)
19
{
20
matrix[0] = 1.0f;
21
matrix[1] = 0.0f;
22
matrix[2] = 0.0f;
23
matrix[3] = xOffset;
24
25
matrix[4] = 0.0f;
26
matrix[5] = 1.0f;
27
matrix[6] = 0.0f;
28
matrix[7] = yOffset;
29
30
matrix[8] = 0.0f;
31
matrix[9] = 0.0f;
32
matrix[10] = 1.0f;
33
matrix[11] = zOffset;
34
35
matrix[12] = 0.0f;
36
matrix[13] = 0.0f;
37
matrix[14] = 0.0f;
38
matrix[15] = 1.0f;
39
}
40
41
} // namespace
42
43
class MultiviewSample : public SampleApplication
44
{
45
public:
46
MultiviewSample(int argc, char **argv)
47
: SampleApplication("Multiview", argc, argv, 3, 0),
48
mMultiviewProgram(0),
49
mMultiviewPersperiveUniformLoc(-1),
50
mMultiviewLeftEyeCameraUniformLoc(-1),
51
mMultiviewRightEyeCameraUniformLoc(-1),
52
mMultiviewTranslationUniformLoc(-1),
53
mMultiviewFBO(0),
54
mColorTexture(0),
55
mDepthTexture(0),
56
mQuadVAO(0),
57
mQuadVBO(0),
58
mCubeVAO(0),
59
mCubePosVBO(0),
60
mCubeNormalVBO(0),
61
mCubeIBO(0),
62
mCombineProgram(0)
63
{}
64
65
bool initialize() override
66
{
67
// Check whether the GL_OVR_multiview(2) extension is supported. If not, abort
68
// initialization.
69
const char *allExtensions = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
70
const std::string paddedExtensions = std::string(" ") + allExtensions + std::string(" ");
71
if ((paddedExtensions.find(std::string(" GL_OVR_multiview2 ")) == std::string::npos) &&
72
(paddedExtensions.find(std::string(" GL_OVR_multiview ")) == std::string::npos))
73
{
74
std::cout << "GL_OVR_multiview(2) is not available." << std::endl;
75
return false;
76
}
77
78
// A view covers horizontally half of the screen.
79
int viewWidth = getWindow()->getWidth() / 2;
80
int viewHeight = getWindow()->getHeight();
81
82
// Create color and depth texture arrays with two layers to which we render each view.
83
glGenTextures(1, &mColorTexture);
84
glBindTexture(GL_TEXTURE_2D_ARRAY, mColorTexture);
85
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, viewWidth, viewHeight, 2, 0, GL_RGBA,
86
GL_UNSIGNED_BYTE, nullptr);
87
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
88
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
89
90
glGenTextures(1, &mDepthTexture);
91
glBindTexture(GL_TEXTURE_2D_ARRAY, mDepthTexture);
92
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, viewWidth, viewHeight, 2, 0,
93
GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
94
95
// Generate multiview framebuffer for layered rendering.
96
glGenFramebuffers(1, &mMultiviewFBO);
97
glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
98
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0, 0,
99
2);
100
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0, 0,
101
2);
102
GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
103
glDrawBuffers(1, &drawBuffer);
104
105
// Check that the framebuffer is complete. Abort initialization otherwise.
106
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
107
{
108
return false;
109
}
110
111
// Create multiview program and query the uniform locations.
112
// The program has two code paths based on the gl_ViewID_OVR attribute which tells us which
113
// view is currently being rendered to. Based on it we decide which eye's camera matrix to
114
// use.
115
constexpr char kMultiviewVS[] =
116
"#version 300 es\n"
117
"#extension GL_OVR_multiview2 : require\n"
118
"layout(num_views = 2) in;\n"
119
"layout(location=0) in vec3 posIn;\n"
120
"layout(location=1) in vec3 normalIn;\n"
121
"uniform mat4 uPerspective;\n"
122
"uniform mat4 uCameraLeftEye;\n"
123
"uniform mat4 uCameraRightEye;\n"
124
"uniform mat4 uTranslation;\n"
125
"out vec3 oNormal;\n"
126
"void main()\n"
127
"{\n"
128
" vec4 p = uTranslation * vec4(posIn,1.);\n"
129
" if (gl_ViewID_OVR == 0u) {\n"
130
" p = uCameraLeftEye * p;\n"
131
" } else {\n"
132
" p = uCameraRightEye * p;\n"
133
" }\n"
134
" oNormal = normalIn;\n"
135
" gl_Position = uPerspective * p;\n"
136
"}\n";
137
138
constexpr char kMultiviewFS[] =
139
"#version 300 es\n"
140
"#extension GL_OVR_multiview2 : require\n"
141
"precision mediump float;\n"
142
"out vec4 color;\n"
143
"in vec3 oNormal;\n"
144
"void main()\n"
145
"{\n"
146
" vec3 col = 0.5 * oNormal + vec3(0.5);\n"
147
" color = vec4(col, 1.);\n"
148
"}\n";
149
150
mMultiviewProgram = CompileProgram(kMultiviewVS, kMultiviewFS);
151
if (!mMultiviewProgram)
152
{
153
return false;
154
}
155
mMultiviewPersperiveUniformLoc = glGetUniformLocation(mMultiviewProgram, "uPerspective");
156
mMultiviewLeftEyeCameraUniformLoc =
157
glGetUniformLocation(mMultiviewProgram, "uCameraLeftEye");
158
mMultiviewRightEyeCameraUniformLoc =
159
glGetUniformLocation(mMultiviewProgram, "uCameraRightEye");
160
mMultiviewTranslationUniformLoc = glGetUniformLocation(mMultiviewProgram, "uTranslation");
161
162
// Create a normal program to combine both layers of the color array texture.
163
constexpr char kCombineVS[] =
164
"#version 300 es\n"
165
"in vec2 vIn;\n"
166
"out vec2 uv;\n"
167
"void main()\n"
168
"{\n"
169
" gl_Position = vec4(vIn, 0., 1.);\n"
170
" uv = vIn * .5 + vec2(.5);\n"
171
"}\n";
172
173
constexpr char kCombineFS[] =
174
"#version 300 es\n"
175
"precision mediump float;\n"
176
"precision mediump sampler2DArray;\n"
177
"uniform sampler2DArray uMultiviewTex;\n"
178
"in vec2 uv;\n"
179
"out vec4 color;\n"
180
"void main()\n"
181
"{\n"
182
" float scaledX = 2.0 * uv.x;\n"
183
" float layer = floor(scaledX);\n"
184
" vec2 adjustedUV = vec2(fract(scaledX), uv.y);\n"
185
" vec3 texColor = texture(uMultiviewTex, vec3(adjustedUV, layer)).rgb;\n"
186
" color = vec4(texColor, 1.);\n"
187
"}\n";
188
189
mCombineProgram = CompileProgram(kCombineVS, kCombineFS);
190
if (!mCombineProgram)
191
{
192
return false;
193
}
194
195
// Generate a quad which covers the whole screen.
196
glGenVertexArrays(1, &mQuadVAO);
197
glBindVertexArray(mQuadVAO);
198
199
glGenBuffers(1, &mQuadVBO);
200
glBindBuffer(GL_ARRAY_BUFFER, mQuadVBO);
201
const float kQuadPositionData[] = {1.f, -1.f, 1.f, 1.f, -1.f, -1.f, -1.f, 1.f};
202
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, kQuadPositionData, GL_STATIC_DRAW);
203
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
204
glEnableVertexAttribArray(0);
205
glBindVertexArray(0);
206
207
// Generate a cube.
208
GenerateCubeGeometry(1.0f, &mCube);
209
glGenVertexArrays(1, &mCubeVAO);
210
glBindVertexArray(mCubeVAO);
211
212
glGenBuffers(1, &mCubePosVBO);
213
glBindBuffer(GL_ARRAY_BUFFER, mCubePosVBO);
214
glBufferData(GL_ARRAY_BUFFER, sizeof(angle::Vector3) * mCube.positions.size(),
215
mCube.positions.data(), GL_STATIC_DRAW);
216
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
217
glEnableVertexAttribArray(0);
218
219
glGenBuffers(1, &mCubeNormalVBO);
220
glBindBuffer(GL_ARRAY_BUFFER, mCubeNormalVBO);
221
glBufferData(GL_ARRAY_BUFFER, sizeof(angle::Vector3) * mCube.normals.size(),
222
mCube.normals.data(), GL_STATIC_DRAW);
223
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
224
glEnableVertexAttribArray(1);
225
226
glGenBuffers(1, &mCubeIBO);
227
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mCubeIBO);
228
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mCube.indices.size(),
229
mCube.indices.data(), GL_STATIC_DRAW);
230
231
glBindVertexArray(0);
232
233
glEnable(GL_DEPTH_TEST);
234
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
235
236
return true;
237
}
238
239
void destroy() override
240
{
241
glDeleteProgram(mMultiviewProgram);
242
glDeleteFramebuffers(1, &mMultiviewFBO);
243
glDeleteTextures(1, &mColorTexture);
244
glDeleteTextures(1, &mDepthTexture);
245
glDeleteVertexArrays(1, &mQuadVAO);
246
glDeleteBuffers(1, &mQuadVBO);
247
glDeleteVertexArrays(1, &mCubeVAO);
248
glDeleteBuffers(1, &mQuadVBO);
249
glDeleteBuffers(1, &mCubePosVBO);
250
glDeleteBuffers(1, &mCubeNormalVBO);
251
glDeleteBuffers(1, &mCubeIBO);
252
glDeleteProgram(mCombineProgram);
253
}
254
255
void draw() override
256
{
257
// Draw to multiview fbo.
258
{
259
// Generate the perspective projection matrix.
260
const int viewWidth = getWindow()->getWidth() / 2;
261
const int viewHeight = getWindow()->getHeight();
262
const float kFOV = 90.f;
263
const float kNear = 1.0f;
264
const float kFar = 100.0f;
265
const float kPlaneDifference = kFar - kNear;
266
const float kXYScale = 1.f / (tanf(kFOV / 2.0f));
267
const float kAspectRatio = static_cast<float>(viewWidth) / viewHeight;
268
float kPerspectiveProjectionMatrix[16];
269
kPerspectiveProjectionMatrix[0] = kXYScale / kAspectRatio;
270
kPerspectiveProjectionMatrix[1] = .0f;
271
kPerspectiveProjectionMatrix[2] = .0f;
272
kPerspectiveProjectionMatrix[3] = .0f;
273
274
kPerspectiveProjectionMatrix[4] = .0f;
275
kPerspectiveProjectionMatrix[5] = kXYScale;
276
kPerspectiveProjectionMatrix[6] = .0f;
277
kPerspectiveProjectionMatrix[7] = .0f;
278
279
kPerspectiveProjectionMatrix[8] = .0f;
280
kPerspectiveProjectionMatrix[9] = .0;
281
kPerspectiveProjectionMatrix[10] = -kFar / kPlaneDifference;
282
kPerspectiveProjectionMatrix[11] = -1.f;
283
284
kPerspectiveProjectionMatrix[12] = .0f;
285
kPerspectiveProjectionMatrix[13] = .0;
286
kPerspectiveProjectionMatrix[14] = -kFar * kNear / kPlaneDifference;
287
kPerspectiveProjectionMatrix[15] = .0;
288
289
// Generate the camera matrices for the left and right eye.
290
const float kXOffset = 1.5f;
291
const float kYOffset = 1.5f;
292
const float kZOffset = 5.0f;
293
float kLeftCameraMatrix[16];
294
FillTranslationMatrix(kXOffset, -kYOffset, -kZOffset, kLeftCameraMatrix);
295
float kRightCameraMatrix[16];
296
FillTranslationMatrix(-kXOffset, -kYOffset, -kZOffset, kRightCameraMatrix);
297
298
// Bind and clear the multiview framebuffer.
299
glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
300
glClearColor(0, 0, 0, 1);
301
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
302
303
// Set the viewport to be the size as one of the views.
304
glViewport(0, 0, viewWidth, viewHeight);
305
306
// Bind multiview program and set matrices.
307
glUseProgram(mMultiviewProgram);
308
glUniformMatrix4fv(mMultiviewPersperiveUniformLoc, 1, GL_TRUE,
309
kPerspectiveProjectionMatrix);
310
glUniformMatrix4fv(mMultiviewLeftEyeCameraUniformLoc, 1, GL_TRUE, kLeftCameraMatrix);
311
glUniformMatrix4fv(mMultiviewRightEyeCameraUniformLoc, 1, GL_TRUE, kRightCameraMatrix);
312
313
glBindVertexArray(mCubeVAO);
314
315
// Draw first cube.
316
float kTranslationMatrix[16];
317
FillTranslationMatrix(0.0f, 0.0f, 0.0f, kTranslationMatrix);
318
glUniformMatrix4fv(mMultiviewTranslationUniformLoc, 1, GL_TRUE, kTranslationMatrix);
319
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCube.indices.size()),
320
GL_UNSIGNED_SHORT, nullptr);
321
322
// Draw second cube.
323
FillTranslationMatrix(1.0f, 1.0f, -2.0f, kTranslationMatrix);
324
glUniformMatrix4fv(mMultiviewTranslationUniformLoc, 1, GL_TRUE, kTranslationMatrix);
325
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCube.indices.size()),
326
GL_UNSIGNED_SHORT, nullptr);
327
328
glBindVertexArray(0);
329
}
330
331
// Combine both views.
332
{
333
// Bind the default framebuffer object and clear.
334
glBindFramebuffer(GL_FRAMEBUFFER, 0);
335
336
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
337
338
// Set the viewport to cover the whole screen.
339
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
340
341
glUseProgram(mCombineProgram);
342
343
// Bind the 2D array texture to be used as a sampler.
344
glUniform1i(glGetUniformLocation(mCombineProgram, "uMultiviewTex"), 0);
345
glBindTexture(GL_TEXTURE_2D_ARRAY, mMultiviewFBO);
346
glActiveTexture(GL_TEXTURE0);
347
348
// Draw a quad which covers the whole screen. Layer and texture coordinates are
349
// calculated in the vertex shader based on the UV coordinates of the quad.
350
glBindVertexArray(mQuadVAO);
351
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
352
glBindVertexArray(0);
353
}
354
}
355
356
private:
357
GLuint mMultiviewProgram;
358
GLint mMultiviewPersperiveUniformLoc;
359
GLint mMultiviewLeftEyeCameraUniformLoc;
360
GLint mMultiviewRightEyeCameraUniformLoc;
361
GLint mMultiviewTranslationUniformLoc;
362
363
GLuint mMultiviewFBO;
364
GLuint mColorTexture;
365
GLuint mDepthTexture;
366
367
GLuint mQuadVAO;
368
GLuint mQuadVBO;
369
370
CubeGeometry mCube;
371
GLuint mCubeVAO;
372
GLuint mCubePosVBO;
373
GLuint mCubeNormalVBO;
374
GLuint mCubeIBO;
375
376
GLuint mCombineProgram;
377
};
378
379
int main(int argc, char **argv)
380
{
381
MultiviewSample app(argc, argv);
382
return app.run();
383
}
384
385