#include "../../HEADERS/EFFECTS/TexMerger.h" #include "../../HEADERS/UTILS/ShaderMaker.h" #include #include #include extern "C" { #include "../../GLES_3_1_compatibility.h" } TexMerger::TexMerger(GLuint texCount, unsigned int texWidth, unsigned int texHeight) { glGenVertexArrays(1, &quadVAO); glBindVertexArray(quadVAO); glGenBuffers(1, &vertVBO); glBindBuffer(GL_ARRAY_BUFFER, vertVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVerts), quadVerts, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float)/**/, (void*)0); glEnableVertexAttribArray(0); std::string root = "C:\\Users\\BoBoBoat\\Desktop\\SCUOLA\\CGI\\GL_STUFF\\GL_STUFF\\SOURCES\\EFFECTS\\TEX_MERGER"; std::string vertSh = root + "\\vertexShader_merger.glsl"; std::string fragSh = root + "\\fragmentShader_merger.glsl"; program = ShaderMaker::createProgram(&vertSh[0], &fragSh[0]); shaderTex1Id = glGetUniformLocation(program, "inTex1"); shaderTex2Id = glGetUniformLocation(program, "inTex2"); bufCount = ceil(log2((float)texCount)); mergeBuffers = (GLuint*) malloc(bufCount * sizeof(GLuint)); glGenFramebuffers(1, &FBO); glGenTextures(bufCount, mergeBuffers); for (unsigned int i = 0; i < bufCount; i++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, mergeBuffers[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); //RGB o RGBA? usageMap.push_back(false); } } GLuint TexMerger::reserveBuffer() { unsigned int index = 0; while (index < bufCount && usageMap[index]) { index++; } if (index >= bufCount) throw "TexMerger::reserveBuffer : free buffer not found"; return mergeBuffers[index]; } bool TexMerger::isBuffer(GLuint number) { bool found = false; int index = -1; while (!found && (++index < bufCount)) if (mergeBuffers[index] == number) found = true; return found; } void TexMerger::freeBuffer(GLuint number) { bool found = false; int index = -1; while (!found && (++index < bufCount)) if (mergeBuffers[index] == number) found = true; if (found) usageMap[index] = false; else throw "TexMerger::freeBuffer : index not found"; } /*(BUFFER è in realtà un indice) * MERGE (START,END) * if (END - START) == 0 * leggi la texture * ritorna texture * else * MID = (START + END) / 2 * B1 = MERGE(START, MID) * B2 = MERGE(MID + 1, END ) * scegli un BUFFER libero (bloccante) * somma B1, B2 nel BUFFER * sblocca tra B1 e B2 quelli che sono BUFFER * ritorna BUFFER */ GLuint TexMerger::merge(std::vector inTextures, int startIndex, int endIndex) { if ((endIndex - startIndex) == 0) { return inTextures[startIndex]; } else { int mid = (startIndex + endIndex) / 2; GLuint buf1; GLuint buf2; GLuint result; try{ buf1 = merge(inTextures, startIndex, mid); buf2 = merge(inTextures, mid + 1, endIndex); result = reserveBuffer(); } catch( std::string ex){ std::cout << ex; } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, result, 0); GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; /* commented and not available glDrawBuffers(1, DrawBuffers); */ //glClearColor(0, 0, 0, 0); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, buf1); glUniform1i(shaderTex1Id, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, buf2); glUniform1i(shaderTex2Id, 1); glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); if (isBuffer(buf1)) freeBuffer(buf1); if (isBuffer(buf2)) freeBuffer(buf2); return result; } }