Path: blob/main_old/samples/simple_instancing/SimpleInstancing.cpp
1694 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// Based on Simple_Texture2D.c from7// Book: OpenGL(R) ES 2.0 Programming Guide8// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner9// ISBN-10: 032150279510// ISBN-13: 978032150279711// Publisher: Addison-Wesley Professional12// URLs: http://safari.informit.com/978032156383513// http://www.opengles-book.com1415#include "SampleApplication.h"1617#include "common/vector_utils.h"18#include "texture_utils.h"19#include "util/shader_utils.h"2021#include <cstring>22#include <iostream>23#include <vector>2425using namespace angle;2627class SimpleInstancingSample : public SampleApplication28{29public:30SimpleInstancingSample(int argc, char **argv)31: SampleApplication("SimpleInstancing", argc, argv)32{}3334bool initialize() override35{36// init instancing functions37char *extensionString = (char *)glGetString(GL_EXTENSIONS);38if (strstr(extensionString, "GL_ANGLE_instanced_arrays"))39{40mVertexAttribDivisorANGLE =41(PFNGLVERTEXATTRIBDIVISORANGLEPROC)eglGetProcAddress("glVertexAttribDivisorANGLE");42mDrawArraysInstancedANGLE =43(PFNGLDRAWARRAYSINSTANCEDANGLEPROC)eglGetProcAddress("glDrawArraysInstancedANGLE");44mDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)eglGetProcAddress(45"glDrawElementsInstancedANGLE");46}4748if (!mVertexAttribDivisorANGLE || !mDrawArraysInstancedANGLE ||49!mDrawElementsInstancedANGLE)50{51std::cerr << "Unable to load GL_ANGLE_instanced_arrays entry points.";52return false;53}5455constexpr char kVS[] = R"(attribute vec3 a_position;56attribute vec2 a_texCoord;57attribute vec3 a_instancePos;58varying vec2 v_texCoord;59void main()60{61gl_Position = vec4(a_position.xyz + a_instancePos.xyz, 1.0);62v_texCoord = a_texCoord;63})";6465constexpr char kFS[] = R"(precision mediump float;66varying vec2 v_texCoord;67uniform sampler2D s_texture;68void main()69{70gl_FragColor = texture2D(s_texture, v_texCoord);71})";7273mProgram = CompileProgram(kVS, kFS);74if (!mProgram)75{76return false;77}7879// Get the attribute locations80mPositionLoc = glGetAttribLocation(mProgram, "a_position");81mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");82mInstancePosLoc = glGetAttribLocation(mProgram, "a_instancePos");8384// Get the sampler location85mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");8687// Load the texture88mTextureID = CreateSimpleTexture2D();8990// Initialize the vertex and index vectors91const GLfloat quadRadius = 0.01f;9293mVertices.push_back(Vector3(-quadRadius, quadRadius, 0.0f));94mVertices.push_back(Vector3(-quadRadius, -quadRadius, 0.0f));95mVertices.push_back(Vector3(quadRadius, -quadRadius, 0.0f));96mVertices.push_back(Vector3(quadRadius, quadRadius, 0.0f));9798mTexcoords.push_back(Vector2(0.0f, 0.0f));99mTexcoords.push_back(Vector2(0.0f, 1.0f));100mTexcoords.push_back(Vector2(1.0f, 1.0f));101mTexcoords.push_back(Vector2(1.0f, 0.0f));102103mIndices.push_back(0);104mIndices.push_back(1);105mIndices.push_back(2);106mIndices.push_back(0);107mIndices.push_back(2);108mIndices.push_back(3);109110// Tile thousands of quad instances111for (float y = -1.0f + quadRadius; y < 1.0f - quadRadius; y += quadRadius * 3)112{113for (float x = -1.0f + quadRadius; x < 1.0f - quadRadius; x += quadRadius * 3)114{115mInstances.push_back(Vector3(x, y, 0.0f));116}117}118119glClearColor(0.0f, 0.0f, 0.0f, 0.0f);120121return true;122}123124void destroy() override125{126glDeleteProgram(mProgram);127glDeleteTextures(1, &mTextureID);128}129130void draw() override131{132// Set the viewport133glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());134135// Clear the color buffer136glClear(GL_COLOR_BUFFER_BIT);137138// Use the program object139glUseProgram(mProgram);140141// Load the vertex position142glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mVertices.data());143glEnableVertexAttribArray(mPositionLoc);144145// Load the texture coordinate146glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mTexcoords.data());147glEnableVertexAttribArray(mTexCoordLoc);148149// Load the instance position150glVertexAttribPointer(mInstancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, mInstances.data());151glEnableVertexAttribArray(mInstancePosLoc);152153// Enable instancing154mVertexAttribDivisorANGLE(mInstancePosLoc, 1);155156// Bind the texture157glActiveTexture(GL_TEXTURE0);158glBindTexture(GL_TEXTURE_2D, mTextureID);159160// Set the sampler texture unit to 0161glUniform1i(mSamplerLoc, 0);162163// Do the instanced draw164mDrawElementsInstancedANGLE(GL_TRIANGLES, static_cast<GLsizei>(mIndices.size()),165GL_UNSIGNED_SHORT, mIndices.data(),166static_cast<GLsizei>(mInstances.size()));167}168169private:170// Handle to a program object171GLuint mProgram;172173// Attribute locations174GLint mPositionLoc;175GLint mTexCoordLoc;176177// Sampler location178GLint mSamplerLoc;179180// Texture handle181GLuint mTextureID;182183// Instance VBO184GLint mInstancePosLoc;185186// Loaded entry points187PFNGLVERTEXATTRIBDIVISORANGLEPROC mVertexAttribDivisorANGLE;188PFNGLDRAWARRAYSINSTANCEDANGLEPROC mDrawArraysInstancedANGLE;189PFNGLDRAWELEMENTSINSTANCEDANGLEPROC mDrawElementsInstancedANGLE;190191// Vertex data192std::vector<Vector3> mVertices;193std::vector<Vector2> mTexcoords;194std::vector<Vector3> mInstances;195std::vector<GLushort> mIndices;196};197198int main(int argc, char **argv)199{200SimpleInstancingSample app(argc, argv);201return app.run();202}203204205