Path: blob/main_old/samples/multiple_draw_buffers/MultipleDrawBuffers.cpp
2580 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 "texture_utils.h"18#include "util/shader_utils.h"19#include "util/test_utils.h"2021#include <cstring>22#include <iostream>2324class MultipleDrawBuffersSample : public SampleApplication25{26public:27MultipleDrawBuffersSample(int argc, char **argv)28: SampleApplication("MultipleDrawBuffers", argc, argv)29{}3031bool initialize() override32{33// Check EXT_draw_buffers is supported34char *extensionString = (char *)glGetString(GL_EXTENSIONS);35if (strstr(extensionString, "GL_EXT_draw_buffers") != nullptr)36{37// Retrieve the address of glDrawBuffersEXT from EGL38mDrawBuffers = (PFNGLDRAWBUFFERSEXTPROC)eglGetProcAddress("glDrawBuffersEXT");39}40else41{42mDrawBuffers = glDrawBuffers;43}4445if (!mDrawBuffers)46{47std::cerr << "Unable to load glDrawBuffers[EXT] entry point.";48return false;49}5051std::stringstream vsStream;52vsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_vs.glsl";5354std::stringstream fsStream;55fsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_fs.glsl";5657std::stringstream copyFsStream;58copyFsStream << angle::GetExecutableDirectory() << "/multiple_draw_buffers_copy_fs.glsl";5960mMRTProgram = CompileProgramFromFiles(vsStream.str(), fsStream.str());61if (!mMRTProgram)62{63return false;64}6566mCopyProgram = CompileProgramFromFiles(vsStream.str(), copyFsStream.str());67if (!mCopyProgram)68{69return false;70}7172// Get the attribute locations73mPositionLoc = glGetAttribLocation(mCopyProgram, "a_position");74mTexCoordLoc = glGetAttribLocation(mCopyProgram, "a_texCoord");7576// Get the sampler location77mSamplerLoc = glGetUniformLocation(mCopyProgram, "s_texture");7879// Load the texture80mTexture = CreateSimpleTexture2D();8182// Initialize the user framebuffer83glGenFramebuffers(1, &mFramebuffer);84glGenTextures(mFramebufferAttachmentCount, mFramebufferTextures);8586glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);87for (size_t i = 0; i < mFramebufferAttachmentCount; i++)88{89// Create textures for the four color attachments90glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[i]);91glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindow()->getWidth(),92getWindow()->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);93glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);94glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);95glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);96glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);97glFramebufferTexture2D(GL_FRAMEBUFFER,98static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT + i), GL_TEXTURE_2D,99mFramebufferTextures[i], 0);100}101102glBindTexture(GL_TEXTURE_2D, 0);103104glClearColor(0.0f, 0.0f, 0.0f, 0.0f);105106return true;107}108109void destroy() override110{111glDeleteProgram(mCopyProgram);112glDeleteProgram(mMRTProgram);113glDeleteTextures(1, &mTexture);114glDeleteTextures(mFramebufferAttachmentCount, mFramebufferTextures);115glDeleteFramebuffers(1, &mFramebuffer);116}117118void draw() override119{120GLfloat vertices[] = {121-0.8f, 0.8f, 0.0f, // Position 01220.0f, 0.0f, // TexCoord 0123-0.8f, -0.8f, 0.0f, // Position 11240.0f, 1.0f, // TexCoord 11250.8f, -0.8f, 0.0f, // Position 21261.0f, 1.0f, // TexCoord 21270.8f, 0.8f, 0.0f, // Position 31281.0f, 0.0f // TexCoord 3129};130GLushort indices[] = {0, 1, 2, 0, 2, 3};131GLenum drawBuffers[mFramebufferAttachmentCount] = {132GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT,133GL_COLOR_ATTACHMENT3_EXT};134135// Enable drawing to the four color attachments of the user framebuffer136glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);137mDrawBuffers(mFramebufferAttachmentCount, drawBuffers);138139// Set the viewport140GLint width = static_cast<GLint>(getWindow()->getWidth());141GLint height = static_cast<GLint>(getWindow()->getHeight());142glViewport(0, 0, width, height);143144// Clear the color buffer145glClear(GL_COLOR_BUFFER_BIT);146147// Use the program object148glUseProgram(mMRTProgram);149150// Load the vertex position151glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);152glEnableVertexAttribArray(mPositionLoc);153154// Load the texture coordinate155glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),156vertices + 3);157glEnableVertexAttribArray(mTexCoordLoc);158159// Bind the texture160glActiveTexture(GL_TEXTURE0);161glBindTexture(GL_TEXTURE_2D, mTexture);162163// Set the sampler texture unit to 0164glUniform1i(mSamplerLoc, 0);165166// Draw the textured quad to the four render targets167glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);168169// Enable the default framebuffer and single textured drawing170glBindFramebuffer(GL_FRAMEBUFFER, 0);171glUseProgram(mCopyProgram);172173// Draw the four textured quads to a separate region in the viewport174glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[0]);175glViewport(0, 0, width / 2, height / 2);176glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);177178glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[1]);179glViewport(width / 2, 0, width / 2, height / 2);180glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);181182glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[2]);183glViewport(0, height / 2, width / 2, height / 2);184glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);185186glBindTexture(GL_TEXTURE_2D, mFramebufferTextures[3]);187glViewport(width / 2, height / 2, width / 2, height / 2);188glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);189}190191private:192// Handle to a program object193GLuint mMRTProgram;194GLuint mCopyProgram;195196// Attribute locations197GLint mPositionLoc;198GLint mTexCoordLoc;199200// Sampler location201GLint mSamplerLoc;202203// Texture handle204GLuint mTexture;205206// Framebuffer object handle207GLuint mFramebuffer;208209// Framebuffer color attachments210static const size_t mFramebufferAttachmentCount = 4;211GLuint mFramebufferTextures[mFramebufferAttachmentCount];212213// Loaded draw buffer entry points214PFNGLDRAWBUFFERSEXTPROC mDrawBuffers;215};216217int main(int argc, char **argv)218{219MultipleDrawBuffersSample app(argc, argv);220return app.run();221}222223224