Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/simple_instancing/SimpleInstancing.cpp
1694 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 "common/vector_utils.h"
19
#include "texture_utils.h"
20
#include "util/shader_utils.h"
21
22
#include <cstring>
23
#include <iostream>
24
#include <vector>
25
26
using namespace angle;
27
28
class SimpleInstancingSample : public SampleApplication
29
{
30
public:
31
SimpleInstancingSample(int argc, char **argv)
32
: SampleApplication("SimpleInstancing", argc, argv)
33
{}
34
35
bool initialize() override
36
{
37
// init instancing functions
38
char *extensionString = (char *)glGetString(GL_EXTENSIONS);
39
if (strstr(extensionString, "GL_ANGLE_instanced_arrays"))
40
{
41
mVertexAttribDivisorANGLE =
42
(PFNGLVERTEXATTRIBDIVISORANGLEPROC)eglGetProcAddress("glVertexAttribDivisorANGLE");
43
mDrawArraysInstancedANGLE =
44
(PFNGLDRAWARRAYSINSTANCEDANGLEPROC)eglGetProcAddress("glDrawArraysInstancedANGLE");
45
mDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)eglGetProcAddress(
46
"glDrawElementsInstancedANGLE");
47
}
48
49
if (!mVertexAttribDivisorANGLE || !mDrawArraysInstancedANGLE ||
50
!mDrawElementsInstancedANGLE)
51
{
52
std::cerr << "Unable to load GL_ANGLE_instanced_arrays entry points.";
53
return false;
54
}
55
56
constexpr char kVS[] = R"(attribute vec3 a_position;
57
attribute vec2 a_texCoord;
58
attribute vec3 a_instancePos;
59
varying vec2 v_texCoord;
60
void main()
61
{
62
gl_Position = vec4(a_position.xyz + a_instancePos.xyz, 1.0);
63
v_texCoord = a_texCoord;
64
})";
65
66
constexpr char kFS[] = R"(precision mediump float;
67
varying vec2 v_texCoord;
68
uniform sampler2D s_texture;
69
void main()
70
{
71
gl_FragColor = texture2D(s_texture, v_texCoord);
72
})";
73
74
mProgram = CompileProgram(kVS, kFS);
75
if (!mProgram)
76
{
77
return false;
78
}
79
80
// Get the attribute locations
81
mPositionLoc = glGetAttribLocation(mProgram, "a_position");
82
mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
83
mInstancePosLoc = glGetAttribLocation(mProgram, "a_instancePos");
84
85
// Get the sampler location
86
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
87
88
// Load the texture
89
mTextureID = CreateSimpleTexture2D();
90
91
// Initialize the vertex and index vectors
92
const GLfloat quadRadius = 0.01f;
93
94
mVertices.push_back(Vector3(-quadRadius, quadRadius, 0.0f));
95
mVertices.push_back(Vector3(-quadRadius, -quadRadius, 0.0f));
96
mVertices.push_back(Vector3(quadRadius, -quadRadius, 0.0f));
97
mVertices.push_back(Vector3(quadRadius, quadRadius, 0.0f));
98
99
mTexcoords.push_back(Vector2(0.0f, 0.0f));
100
mTexcoords.push_back(Vector2(0.0f, 1.0f));
101
mTexcoords.push_back(Vector2(1.0f, 1.0f));
102
mTexcoords.push_back(Vector2(1.0f, 0.0f));
103
104
mIndices.push_back(0);
105
mIndices.push_back(1);
106
mIndices.push_back(2);
107
mIndices.push_back(0);
108
mIndices.push_back(2);
109
mIndices.push_back(3);
110
111
// Tile thousands of quad instances
112
for (float y = -1.0f + quadRadius; y < 1.0f - quadRadius; y += quadRadius * 3)
113
{
114
for (float x = -1.0f + quadRadius; x < 1.0f - quadRadius; x += quadRadius * 3)
115
{
116
mInstances.push_back(Vector3(x, y, 0.0f));
117
}
118
}
119
120
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
121
122
return true;
123
}
124
125
void destroy() override
126
{
127
glDeleteProgram(mProgram);
128
glDeleteTextures(1, &mTextureID);
129
}
130
131
void draw() override
132
{
133
// Set the viewport
134
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
135
136
// Clear the color buffer
137
glClear(GL_COLOR_BUFFER_BIT);
138
139
// Use the program object
140
glUseProgram(mProgram);
141
142
// Load the vertex position
143
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mVertices.data());
144
glEnableVertexAttribArray(mPositionLoc);
145
146
// Load the texture coordinate
147
glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mTexcoords.data());
148
glEnableVertexAttribArray(mTexCoordLoc);
149
150
// Load the instance position
151
glVertexAttribPointer(mInstancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, mInstances.data());
152
glEnableVertexAttribArray(mInstancePosLoc);
153
154
// Enable instancing
155
mVertexAttribDivisorANGLE(mInstancePosLoc, 1);
156
157
// Bind the texture
158
glActiveTexture(GL_TEXTURE0);
159
glBindTexture(GL_TEXTURE_2D, mTextureID);
160
161
// Set the sampler texture unit to 0
162
glUniform1i(mSamplerLoc, 0);
163
164
// Do the instanced draw
165
mDrawElementsInstancedANGLE(GL_TRIANGLES, static_cast<GLsizei>(mIndices.size()),
166
GL_UNSIGNED_SHORT, mIndices.data(),
167
static_cast<GLsizei>(mInstances.size()));
168
}
169
170
private:
171
// Handle to a program object
172
GLuint mProgram;
173
174
// Attribute locations
175
GLint mPositionLoc;
176
GLint mTexCoordLoc;
177
178
// Sampler location
179
GLint mSamplerLoc;
180
181
// Texture handle
182
GLuint mTextureID;
183
184
// Instance VBO
185
GLint mInstancePosLoc;
186
187
// Loaded entry points
188
PFNGLVERTEXATTRIBDIVISORANGLEPROC mVertexAttribDivisorANGLE;
189
PFNGLDRAWARRAYSINSTANCEDANGLEPROC mDrawArraysInstancedANGLE;
190
PFNGLDRAWELEMENTSINSTANCEDANGLEPROC mDrawElementsInstancedANGLE;
191
192
// Vertex data
193
std::vector<Vector3> mVertices;
194
std::vector<Vector2> mTexcoords;
195
std::vector<Vector3> mInstances;
196
std::vector<GLushort> mIndices;
197
};
198
199
int main(int argc, char **argv)
200
{
201
SimpleInstancingSample app(argc, argv);
202
return app.run();
203
}
204
205