Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/multiple_draw_buffers/MultipleDrawBuffers.cpp
2580 views
1
//
2
// Copyright 2014 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
7
// Based on Simple_Texture2D.c from
8
// Book: OpenGL(R) ES 2.0 Programming Guide
9
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10
// ISBN-10: 0321502795
11
// ISBN-13: 9780321502797
12
// Publisher: Addison-Wesley Professional
13
// URLs: http://safari.informit.com/9780321563835
14
// http://www.opengles-book.com
15
16
#include "SampleApplication.h"
17
18
#include "texture_utils.h"
19
#include "util/shader_utils.h"
20
#include "util/test_utils.h"
21
22
#include <cstring>
23
#include <iostream>
24
25
class MultipleDrawBuffersSample : public SampleApplication
26
{
27
public:
28
MultipleDrawBuffersSample(int argc, char **argv)
29
: SampleApplication("MultipleDrawBuffers", argc, argv)
30
{}
31
32
bool initialize() override
33
{
34
// Check EXT_draw_buffers is supported
35
char *extensionString = (char *)glGetString(GL_EXTENSIONS);
36
if (strstr(extensionString, "GL_EXT_draw_buffers") != nullptr)
37
{
38
// Retrieve the address of glDrawBuffersEXT from EGL
39
mDrawBuffers = (PFNGLDRAWBUFFERSEXTPROC)eglGetProcAddress("glDrawBuffersEXT");
40
}
41
else
42
{
43
mDrawBuffers = glDrawBuffers;
44
}
45
46
if (!mDrawBuffers)
47
{
48
std::cerr << "Unable to load glDrawBuffers[EXT] entry point.";
49
return false;
50
}
51
52
std::stringstream vsStream;
53
vsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_vs.glsl";
54
55
std::stringstream fsStream;
56
fsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_fs.glsl";
57
58
std::stringstream copyFsStream;
59
copyFsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_copy_fs.glsl";
60
61
mMRTProgram = CompileProgramFromFiles(vsStream.str(), fsStream.str());
62
if (!mMRTProgram)
63
{
64
return false;
65
}
66
67
mCopyProgram = CompileProgramFromFiles(vsStream.str(), copyFsStream.str());
68
if (!mCopyProgram)
69
{
70
return false;
71
}
72
73
// Get the attribute locations
74
mPositionLoc = glGetAttribLocation(mCopyProgram, "a_position");
75
mTexCoordLoc = glGetAttribLocation(mCopyProgram, "a_texCoord");
76
77
// Get the sampler location
78
mSamplerLoc = glGetUniformLocation(mCopyProgram, "s_texture");
79
80
// Load the texture
81
mTexture = CreateSimpleTexture2D();
82
83
// Initialize the user framebuffer
84
glGenFramebuffers(1, &mFramebuffer);
85
glGenTextures(mFramebufferAttachmentCount, mFramebufferTextures);
86
87
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
88
for (size_t i = 0; i < mFramebufferAttachmentCount; i++)
89
{
90
// Create textures for the four color attachments
91
glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[i]);
92
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindow()->getWidth(),
93
getWindow()->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
94
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
95
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
96
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
97
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
98
glFramebufferTexture2D(GL_FRAMEBUFFER,
99
static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT + i), GL_TEXTURE_2D,
100
mFramebufferTextures[i], 0);
101
}
102
103
glBindTexture(GL_TEXTURE_2D, 0);
104
105
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
106
107
return true;
108
}
109
110
void destroy() override
111
{
112
glDeleteProgram(mCopyProgram);
113
glDeleteProgram(mMRTProgram);
114
glDeleteTextures(1, &mTexture);
115
glDeleteTextures(mFramebufferAttachmentCount, mFramebufferTextures);
116
glDeleteFramebuffers(1, &mFramebuffer);
117
}
118
119
void draw() override
120
{
121
GLfloat vertices[] = {
122
-0.8f, 0.8f, 0.0f, // Position 0
123
0.0f, 0.0f, // TexCoord 0
124
-0.8f, -0.8f, 0.0f, // Position 1
125
0.0f, 1.0f, // TexCoord 1
126
0.8f, -0.8f, 0.0f, // Position 2
127
1.0f, 1.0f, // TexCoord 2
128
0.8f, 0.8f, 0.0f, // Position 3
129
1.0f, 0.0f // TexCoord 3
130
};
131
GLushort indices[] = {0, 1, 2, 0, 2, 3};
132
GLenum drawBuffers[mFramebufferAttachmentCount] = {
133
GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT,
134
GL_COLOR_ATTACHMENT3_EXT};
135
136
// Enable drawing to the four color attachments of the user framebuffer
137
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
138
mDrawBuffers(mFramebufferAttachmentCount, drawBuffers);
139
140
// Set the viewport
141
GLint width = static_cast<GLint>(getWindow()->getWidth());
142
GLint height = static_cast<GLint>(getWindow()->getHeight());
143
glViewport(0, 0, width, height);
144
145
// Clear the color buffer
146
glClear(GL_COLOR_BUFFER_BIT);
147
148
// Use the program object
149
glUseProgram(mMRTProgram);
150
151
// Load the vertex position
152
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
153
glEnableVertexAttribArray(mPositionLoc);
154
155
// Load the texture coordinate
156
glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
157
vertices + 3);
158
glEnableVertexAttribArray(mTexCoordLoc);
159
160
// Bind the texture
161
glActiveTexture(GL_TEXTURE0);
162
glBindTexture(GL_TEXTURE_2D, mTexture);
163
164
// Set the sampler texture unit to 0
165
glUniform1i(mSamplerLoc, 0);
166
167
// Draw the textured quad to the four render targets
168
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
169
170
// Enable the default framebuffer and single textured drawing
171
glBindFramebuffer(GL_FRAMEBUFFER, 0);
172
glUseProgram(mCopyProgram);
173
174
// Draw the four textured quads to a separate region in the viewport
175
glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[0]);
176
glViewport(0, 0, width / 2, height / 2);
177
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
178
179
glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[1]);
180
glViewport(width / 2, 0, width / 2, height / 2);
181
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
182
183
glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[2]);
184
glViewport(0, height / 2, width / 2, height / 2);
185
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
186
187
glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[3]);
188
glViewport(width / 2, height / 2, width / 2, height / 2);
189
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
190
}
191
192
private:
193
// Handle to a program object
194
GLuint mMRTProgram;
195
GLuint mCopyProgram;
196
197
// Attribute locations
198
GLint mPositionLoc;
199
GLint mTexCoordLoc;
200
201
// Sampler location
202
GLint mSamplerLoc;
203
204
// Texture handle
205
GLuint mTexture;
206
207
// Framebuffer object handle
208
GLuint mFramebuffer;
209
210
// Framebuffer color attachments
211
static const size_t mFramebufferAttachmentCount = 4;
212
GLuint mFramebufferTextures[mFramebufferAttachmentCount];
213
214
// Loaded draw buffer entry points
215
PFNGLDRAWBUFFERSEXTPROC mDrawBuffers;
216
};
217
218
int main(int argc, char **argv)
219
{
220
MultipleDrawBuffersSample app(argc, argv);
221
return app.run();
222
}
223
224