void draw() { fbo1.draw(render_tri); fbo2.draw(render_quad); // render to screen prep_ortho(); //render(); switch(mode) { case 1: render_tri(); break; case 2: render_quad(); break; case 3: render_from_texture(); break; } glfwSwapBuffers(window); glfwPollEvents(); }
bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context) { LOGWEBGL("paintCompositedResultsToCanvas()"); ImageBuffer* imageBuffer = context->canvas()->buffer(); const SkBitmap& canvasBitmap = imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false); SkCanvas canvas(canvasBitmap); MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (!fbo) return false; SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height, fbo->bytesPerRow()); unsigned char* bits = NULL; if (fbo->lockGraphicBuffer((void**)&bits)) { bitmap.setPixels(bits); SkRect dstRect; dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height()); canvas.save(); canvas.translate(0, SkIntToScalar(imageBuffer->size().height())); canvas.scale(SK_Scalar1, -SK_Scalar1); canvas.drawBitmapRect(bitmap, 0, dstRect); canvas.restore(); bitmap.setPixels(0); fbo->unlockGraphicBuffer(); } return true; }
PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData() { LOGWEBGL("paintRenderingResultsToImageData()"); // Reading premultiplied alpha would involve unpremultiplying, which is lossy. if (m_attrs.premultipliedAlpha) return 0; RefPtr<ImageData> imageData = ImageData::create(IntSize(m_width, m_height)); unsigned char* pixels = imageData->data()->data()->data(); //[CAPPFIX_WEB_WEBGL] - better performance if (m_canvasDirty) { glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } else { LOGWEBGL("paintRenderingResultsToImageData() >>> from clean canvas, so read the back buffer >>> m_canvasDirty:%d", m_canvasDirty); unsigned char* bits; MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (!fbo) return NULL; if (fbo->lockGraphicBuffer((void**)&bits)) { memcpy(pixels, bits, (m_width * m_height * 4)); fbo->unlockGraphicBuffer(); } } LOGWEBGL("-paintRenderingResultsToImageData()"); // [CAPPFIX_WEB_WEBGL_END] return imageData; }
bool GraphicsContext3DInternal::lockFrontBuffer(T& image, SkRect& rect) { LOGWEBGL("GraphicsContext3DInternal::lockFrontBuffer()"); MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (!fbo || !fbo->image()) { LOGWEBGL("-GraphicsContext3DInternal::lockFrontBuffer(), fbo = %p", fbo); return false; } fbo->setLocked(true); image = (T)(fbo->image()); RenderObject* renderer = m_canvas->renderer(); if (renderer && renderer->isBox()) { RenderBox* box = (RenderBox*)renderer; rect.setXYWH(box->borderLeft() + box->paddingLeft(), box->borderTop() + box->paddingTop(), box->contentWidth(), box->contentHeight()); } return true; }
int LuaFBOs::DeleteFBO(lua_State* L) { if (lua_isnil(L, 1)) { return 0; } FBO* fbo = (FBO*)luaL_checkudata(L, 1, "FBO"); fbo->Free(L); return 0; }
int LuaFBOs::DeleteFBO(lua_State* L) { if (lua_isnil(L, 1)) { return 0; } FBO* fbo = static_cast<FBO*>(luaL_checkudata(L, 1, "FBO")); fbo->Free(L); return 0; }
void Renderer::renderDeferredShading() { if (!m_shaderDSLighting || !m_shaderDSCompositing) init(m_windowWidth, m_windowHeight); if (!m_dsLightColor || !m_dsLightRootNode) throw std::string("Error in renderDeferredShading - Light Color or Light Root Node was not set"); FBO *a = new FBO(m_windowWidth,m_windowHeight,3,false,false); a->bind(); glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderDSLighting->bind(); m_shaderDSLighting->sendMat4("viewMatrix", m_currentViewMatrix); m_shaderDSLighting->sendMat4("projectionMatrix", m_currentProjectionMatrix); m_shaderDSLighting->sendSampler2D("positionMap", m_gBuffer->getColorTexture(0), 0); m_shaderDSLighting->sendSampler2D("normalMap", m_gBuffer->getColorTexture(1), 1); m_shaderDSLighting->sendInt("windowWidth", m_windowWidth); m_shaderDSLighting->sendInt("windowHeight", m_windowHeight); m_shaderDSLighting->sendVec3("lightColor", *m_dsLightColor); m_dsLightRootNode->render(*m_shaderDSLighting); glDisable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glClearColor(1.0, 1.0, 1.0, 0.0); m_shaderDSLighting->unbind(); a->unbind(); //COMPOSITING TEIL =============================== bindFBO(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderDSCompositing->bind(); m_shaderDSCompositing->sendSampler2D("colorMap", getLastFBO()->getColorTexture(2), 0); m_shaderDSCompositing->sendSampler2D("lightMap", a->getColorTexture(2), 1); m_sfq.renderGeometry(); m_shaderDSCompositing->unbind(); unbindFBO(); delete a; }
void onFrame(){ model = glm::mat4(1.0); vec3 totals = rotateBehavior.tick(now()).totals(); model = glm::rotate(model, totals.x, vec3(1.0f,0.0f,0.0f)); model = glm::rotate(model, totals.y, vec3(0.0f,1.0f,0.0f)); model = glm::rotate(model, totals.z, vec3(0.0f,0.0f,1.0f)); //draw cube 1 into an offscreen texture fbo.bind(); { glViewport(0, 0, fbo.width, fbo.height); glClearColor(0.1,0.1,0.1,1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw(model, cubeMeshBuffer1, texture, textureProgram); } fbo.unbind(); //draw cube 2 with the offscreen texture using phong shading glViewport(0, 0, width, height); glClearColor(0.0,0.0,0.0,1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); model = glm::mat4(1.0); model = glm::translate(model, vec3(1.0,0.0,0.0)); model = glm::rotate(model, totals.x, vec3(1.0f,0.0f,0.0f)); model = glm::rotate(model, totals.y, vec3(0.0f,1.0f,0.0f)); model = glm::rotate(model, totals.z, vec3(0.0f,0.0f,1.0f)); draw(model, cubeMeshBuffer2, fbo.texture, phongProgram); //draw cube 3 - a colored cube model = mat4(1.0); model = glm::translate(model, vec3(-1.0,0.0,0.0)); model = glm::rotate(model, -totals.x, vec3(1.0f,0.0f,0.0f)); model = glm::rotate(model, -totals.y, vec3(0.0f,1.0f,0.0f)); model = glm::rotate(model, -totals.z, vec3(0.0f,0.0f,1.0f)); programColor.bind(); { glUniformMatrix4fv(programColor.uniform("model"), 1, 0, ptr(model)); glUniformMatrix4fv(programColor.uniform("view"), 1, 0, ptr(view)); glUniformMatrix4fv(programColor.uniform("proj"), 1, 0, ptr(proj)); cubeMeshBuffer3.draw(); } programColor.unbind(); }
void init() { // FBO fbo1.create(); fbo2.create(); }
FBO* FBO::createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attributes) { LOGWEBGL("createFBO()"); FBO* fbo = new FBO(dpy); if (!fbo->init(width, height, attributes)) { delete fbo; return 0; } return fbo; }
void GraphicsContext3DInternal::releaseFrontBuffer() { LOGWEBGL("GraphicsContext3DInternal::releaseFrontBuffer()"); MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (fbo) { fbo->setLocked(false); if (fbo->sync() != EGL_NO_SYNC_KHR) { eglDestroySyncKHR(m_dpy, fbo->sync()); } fbo->setSync(); } updateFrontBuffer(); }
void onDraw(Graphics& g){ // To render our scene to the FBO, we must first bind it fbo.bind(); // Clear FBO g.clear(Graphics::COLOR_BUFFER_BIT | Graphics::DEPTH_BUFFER_BIT); // Render our scene as we normally would g.draw(mesh); // When done rendering our scene to the FBO, we must unbind it fbo.unbind(); // To prove that this all worked, we render the FBO's color texture tex.quadViewport(g); }
bool GLResource::black( Frame *dst ) { int w = dst->profile.getVideoWidth(); int h = dst->profile.getVideoHeight(); FBO *fbo = getFBO( w, h, GL_RGBA ); if ( !fbo ) return false; glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo() ); glClear( GL_COLOR_BUFFER_BIT ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); dst->setFBO( fbo ); return true; }
void onResize(const ViewpointWindow& win, int w, int h){ // Note: all attachments (textures, RBOs, etc.) to the FBO must have the // same width and height. // Configure texture on GPU tex.format(Graphics::RGB); tex.type(Graphics::UBYTE); tex.resize(w,h); tex.submit(); // ensure texture gets configured on GPU // Configure render buffer object on GPU rbo.resize(w,h); // Finally, attach color texture and depth RBO to FBO fbo.attachTexture2D(tex.id()); fbo.attachRBO(rbo, FBO::DEPTH_ATTACHMENT); }
Texture* GraphicsEngine::GaussianBlur(Texture* input, float radius, bool halfRes) { FBO* blurFBO = GetFBO(BLUR); if (halfRes) blurFBO = GetFBO(HALF); blurFBO->BindForWriting(); blurFBO->SetDrawBuffer(0); GetShader("Gaussian")->Use(); GetShader("Gaussian")->SetUniform2f("blurSize", 1.0f / Screen.width * (1 + halfRes), 1.0f / Screen.height * (1 + halfRes)); GetShader("Gaussian")->SetUniform1f("radius", radius); //Horizontal Blur GetShader("Gaussian")->SetUniform1i("verticalBlur", false); input->Bind(); FBO::Render(); blurFBO->SetDrawBuffer(1); //Vertical Blur GetShader("Gaussian")->SetUniform1i("verticalBlur", true); blurFBO->GetTexture()->Bind(); FBO::Render(); return blurFBO->GetActiveTexture(); }
int main(void) { glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(900, 900, "Simple example", NULL, NULL); if(!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, key_callback); glfwSetWindowSizeCallback(window, size_callback); int err = glewInit(); if(err != GLEW_OK) { abort(); } glfwGetFramebufferSize(window, &width, &height); ratio = (float)width / (float)height; init(); init_shaders(); while (!glfwWindowShouldClose(window)) draw(); fbo1.cleanup(); fbo2.cleanup(); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }
void onCreate() { rh.loadTexture(texture, "resources/hubble.jpg"); texture.minFilter(GL_NEAREST); texture.maxFilter(GL_NEAREST); rh.loadProgram(textureProgram, "resources/texture", posLoc, -1, texCoordLoc, -1); rh.loadProgram(phongProgram, "resources/phong", posLoc, normalLoc, texCoordLoc, -1); rh.loadProgram(programColor, "resources/color", posLoc, normalLoc, -1, colorLoc); MeshData md1; addCube(md1, true, 0.95); MeshData md2; addCube(md2, true, 0.5); MeshData md3; addCube(md3, 0.33); //this version makes normals, texcoords, and colors each side with a different default color cubeMeshBuffer1.init(md1, posLoc, normalLoc, texCoordLoc, -1); cubeMeshBuffer2.init(md2, posLoc, normalLoc, texCoordLoc, -1); cubeMeshBuffer3.init(md3, posLoc, normalLoc, -1, colorLoc); fbo.create(32, 32); millisToNano(1000); rotateBehavior = Behavior(now()).delay(1000).length(5000).range(vec3(3.14, 3.14, 3.14)).reversing(true).repeats(-1).sine(); proj = glm::perspective(45.0, 1.0, 0.1, 100.0); view = glm::lookAt(vec3(0.0,0.0,5), vec3(0,0,0), vec3(0,1,0) ); model = glm::mat4(); glEnable(GL_DEPTH_TEST); glViewport(0, 0, width, height); }
void CGlobalRendering::PostInit() { supportNPOTs = GLEW_ARB_texture_non_power_of_two; haveARB = GLEW_ARB_vertex_program && GLEW_ARB_fragment_program; haveGLSL = (glGetString(GL_SHADING_LANGUAGE_VERSION) != NULL); haveGLSL &= GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader; haveGLSL &= !!GLEW_VERSION_2_0; // we want OpenGL 2.0 core functions { const char* glVendor = (const char*) glGetString(GL_VENDOR); const char* glRenderer = (const char*) glGetString(GL_RENDERER); const std::string vendor = (glVendor != NULL)? StringToLower(std::string(glVendor)): ""; const std::string renderer = (glRenderer != NULL)? StringToLower(std::string(glRenderer)): ""; haveATI = (vendor.find("ati ") != std::string::npos) || (vendor.find("amd ") != std::string::npos); haveMesa = (renderer.find("mesa ") != std::string::npos); haveIntel = (vendor.find("intel ") != std::string::npos); haveNvidia = (vendor.find("nvidia ") != std::string::npos); //FIXME Neither Intel's nor Mesa's GLSL implementation seem to be in a workable state atm (date: Nov. 2011) haveGLSL &= !haveIntel; haveGLSL &= !haveMesa; if (haveATI) { // x-series doesn't support NPOTs (but hd-series does) supportNPOTs = (renderer.find(" x") == std::string::npos && renderer.find(" 9") == std::string::npos); } } // use some ATI bugfixes? const int atiHacksCfg = configHandler->GetInt("AtiHacks"); atiHacks = haveATI && (atiHacksCfg < 0); // runtime detect atiHacks |= (atiHacksCfg > 0); // user override // Runtime compress textures? if (GLEW_ARB_texture_compression) { // we don't even need to check it, 'cos groundtextures must have that extension // default to off because it reduces quality (smallest mipmap level is bigger) compressTextures = configHandler->GetBool("CompressTextures"); } // maximum 2D texture size { glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); } // detect if GL_DEPTH_COMPONENT24 is supported (many ATIs don't do so) { // ATI seems to support GL_DEPTH_COMPONENT24 for static textures, but you can't render to them /* GLint state = 0; glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 16, 16, 0, GL_LUMINANCE, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &state); support24bitDepthBuffers = (state > 0); */ support24bitDepthBuffers = false; if (FBO::IsSupported() && !atiHacks) { const int fboSizeX = 16, fboSizeY = 16; FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, fboSizeX, fboSizeY); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT24, fboSizeX, fboSizeY); const GLenum status = fbo.GetStatus(); fbo.Unbind(); support24bitDepthBuffers = (status == GL_FRAMEBUFFER_COMPLETE_EXT); } } // print info LOG( "GL info:\n" "\thaveARB: %i, haveGLSL: %i, ATI hacks: %i\n" "\tFBO support: %i, NPOT-texture support: %i, 24bit Z-buffer support: %i\n" "\tmaximum texture size: %i, compress MIP-map textures: %i", haveARB, haveGLSL, atiHacks, FBO::IsSupported(), supportNPOTs, support24bitDepthBuffers, maxTextureSize, compressTextures ); }
int LuaFBOs::CreateFBO(lua_State* L) { FBO fbo; fbo.Init(L); const int table = 1; /* if (lua_istable(L, table)) { lua_getfield(L, table, "target"); if (lua_isnumber(L, -1)) { fbo.target = (GLenum)lua_toint(L, -1); } else { lua_pop(L, 1); } } */ const GLenum bindTarget = GetBindingEnum(fbo.target); if (bindTarget == 0) { return 0; } // maintain a lua table to hold RBO references lua_newtable(L); fbo.luaRef = luaL_ref(L, LUA_REGISTRYINDEX); if (fbo.luaRef == LUA_NOREF) { return 0; } GLint currentFBO; glGetIntegerv(bindTarget, ¤tFBO); glGenFramebuffersEXT(1, &fbo.id); glBindFramebufferEXT(fbo.target, fbo.id); FBO* fboPtr = static_cast<FBO*>(lua_newuserdata(L, sizeof(FBO))); *fboPtr = fbo; luaL_getmetatable(L, "FBO"); lua_setmetatable(L, -2); // parse the initialization table if (lua_istable(L, table)) { for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) { if (lua_israwstring(L, -2)) { const string key = lua_tostring(L, -2); const GLenum type = ParseAttachment(key); if (type != 0) { ApplyAttachment(L, -1, fboPtr, type); } else if (key == "drawbuffers") { ApplyDrawBuffers(L, -1); } } } } // revert to the old fbo glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, currentFBO); if (fboPtr->luaRef != LUA_NOREF) { CLuaHandle::GetActiveFBOs(L).fbos.insert(fboPtr); } return 1; }
int LuaFBOs::meta_gc(lua_State* L) { FBO* fbo = static_cast<FBO*>(luaL_checkudata(L, 1, "FBO")); fbo->Free(L); return 0; }
void CGrassDrawer::CreateFarTex() { //TODO create normalmap, too? const int sizeMod = 2; const int billboardSize = 256; const int numAngles = 16; const int texSizeX = billboardSize * numAngles; const int texSizeY = billboardSize; if (farTex == 0) { glGenTextures(1, &farTex); glBindTexture(GL_TEXTURE_2D, farTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGBA8, texSizeX, texSizeY); } FBO fboTex; fboTex.Bind(); fboTex.AttachTexture(farTex); fboTex.CheckStatus("GRASSDRAWER1"); FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CheckStatus("GRASSDRAWER2"); if (!fboTex.IsValid() || !fbo.IsValid()) { grassOff = true; return; } glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glDisable(GL_FOG); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glEnable(GL_TEXTURE_2D); glEnable(GL_CLIP_PLANE0); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glColor4f(1,1,1,1); glViewport(0,0,texSizeX*sizeMod, texSizeY*sizeMod); glClearColor(mapInfo->grass.color.r,mapInfo->grass.color.g,mapInfo->grass.color.b,0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f,0.f,0.f,0.f); static const GLdouble eq[4] = {0.f, 1.f, 0.f, 0.f}; // render turf from different vertical angles for (int a=0;a<numAngles;++a) { glViewport(a*billboardSize*sizeMod, 0, billboardSize*sizeMod, billboardSize*sizeMod); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(a*90.f/(numAngles-1),1,0,0); //glTranslatef(0,-0.5f,0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-partTurfSize, partTurfSize, partTurfSize, -partTurfSize, -turfSize, turfSize); // has to be applied after the matrix transformations, // cause it uses those an `compiles` them into the clip plane glClipPlane(GL_CLIP_PLANE0, &eq[0]); glCallList(grassDL); } glDisable(GL_CLIP_PLANE0); // scale down the rendered fartextures (MSAA) and write to the final texture glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo.fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, fboTex.fboId); glBlitFramebufferEXT(0, 0, texSizeX*sizeMod, texSizeY*sizeMod, 0, 0, texSizeX, texSizeY, GL_COLOR_BUFFER_BIT, GL_LINEAR); // compute mipmaps glBindTexture(GL_TEXTURE_2D, farTex); glGenerateMipmap(GL_TEXTURE_2D); // blur non-rendered areas, so in mipmaps color data isn't blurred with background color { const int mipLevels = std::ceil(std::log((float)(std::max(texSizeX, texSizeY) + 1))); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_DST_ALPHA); // copy each mipmap to its predecessor background // -> fill background with blurred color data fboTex.Bind(); for (int mipLevel = mipLevels - 2; mipLevel >= 0; --mipLevel) { fboTex.AttachTexture(farTex, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT, mipLevel); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, mipLevel + 1.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, mipLevel + 1.f); glViewport(0, 0, texSizeX>>mipLevel, texSizeY>>mipLevel); CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertexT(float3(-1.0f, 1.0f, 0.0f), 0.0f, 1.0f); va->AddVertexT(float3( 1.0f, 1.0f, 0.0f), 1.0f, 1.0f); va->AddVertexT(float3( 1.0f, -1.0f, 0.0f), 1.0f, 0.0f); va->AddVertexT(float3(-1.0f, -1.0f, 0.0f), 0.0f, 0.0f); va->DrawArrayT(GL_QUADS); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // recreate mipmaps from now blurred base level glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000.f); glGenerateMipmap(GL_TEXTURE_2D); } glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); FBO::Unbind(); //glSaveTexture(farTex, "grassfar.png"); }
FBO* GLResource::getFBO( int width, int height, GLint iformat ) { int i; for ( i = 0; i < fboList.count(); ++i ) { FBO *f = fboList.at(i); if ( f->isFree() && ( f->width() != width || f->height() != height || f->format() != iformat ) ) { delete fboList.takeAt( i-- ); } } for ( i = 0; i < fboList.count(); ++i ) { FBO *f = fboList.at(i); if ( f->isFree() && f->width() == width && f->height() == height && f->format() == iformat ) { f->setFree( false ); return f; } } FBO *f = new FBO( width, height, iformat ); if ( !f->isValid() ) { delete f; return NULL; } fboList.append( f ); f->setFree( false ); return f; }
void GraphicsContext3DInternal::swapBuffers() { if (s_loggingEnabled) m_webGLFPSTimer->tick(); LOGWEBGL("+swapBuffers()"); MutexLocker lock(m_fboMutex); FBO* fbo = m_currentFBO; if (fbo == 0) return; makeContextCurrent(); bool mustRestoreFBO = (m_boundFBO != fbo->fbo()); if (mustRestoreFBO) { glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo()); } // Create the fence sync and notify the sync thread fbo->setSync(); //[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin if (!m_needImproveUIResponseMode) //[CAPPFIX_WEB_WEBGL_END] #if USE(SHARED_TEXTURE_WEBGL) glFinish(); #else glFlush(); #endif m_queuedBuffers.append(fbo); m_threadCondition.broadcast(); #if USE(SHARED_TEXTURE_WEBGL) // Dequeue a new buffer fbo = dequeueBuffer(); #else //[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin int tick = 0; if (!m_needImproveUIResponseMode) tick = getTickCount(); //[CAPPFIX_WEB_WEBGL_END] // Dequeue a new buffer fbo = dequeueBuffer(); //[CAPPFIX_WEB_WEBGL] - Improve UI Response Begin if (!m_needImproveUIResponseMode && getTickCount() - tick > SWP_WebGL_IUR_Time) { m_needImproveUIResponseMode = true; LOGWEBGL("On needImproveUIResponseMode"); } //[CAPPFIX_WEB_WEBGL_END] #endif m_currentFBO = fbo; if (!mustRestoreFBO) { m_boundFBO = m_currentFBO->fbo(); } glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO); m_canvasDirty = false; m_layerComposited = true; LOGWEBGL("-swapBuffers()"); }
void Renderer::renderSSAO() { if (!m_shaderSSAOcalc || !m_shaderSSAOblur || !m_shaderSSAOfinal) init(m_windowWidth, m_windowHeight); FBO *a = new FBO(m_windowWidth, m_windowHeight, 3, false, false); FBO *b = new FBO(m_windowWidth, m_windowHeight, 3, false, false); a->bind(); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderSSAOcalc->bind(); m_shaderSSAOcalc->sendSampler2D("positionMap", m_gBuffer->getColorTexture(0), 0); m_shaderSSAOcalc->sendSampler2D("normalMap", m_gBuffer->getColorTexture(1), 1); m_shaderSSAOcalc->sendMat4("sceneProjectionMatrix", m_currentProjectionMatrix); m_shaderSSAOcalc->sendFloat("radius", *m_ssaoRadius); m_shaderSSAOcalc->sendFloat("quality", *m_ssaoQuality); m_sfq.renderGeometry(); m_shaderSSAOcalc->unbind(); a->unbind(); //Blur #1 SSAO calculation b->bind(); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderSSAOblur->bind(); m_shaderSSAOblur->sendSampler2D("colortexture", a->getColorTexture(2), 0); m_shaderSSAOblur->sendInt("secondPass", 0); m_sfq.renderGeometry(); m_shaderSSAOblur->unbind(); b->unbind(); //Blur #2 SSAO calculation a->bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderSSAOblur->bind(); m_shaderSSAOblur->sendSampler2D("colortexture", b->getColorTexture(2), 0); m_shaderSSAOblur->sendFloat("secondPass", 1); m_sfq.renderGeometry(); m_shaderSSAOblur->unbind(); a->unbind(); glClearColor(0, 0, 0, 0); //COLOR COMPOSITING bindFBO(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderSSAOfinal->bind(); m_shaderSSAOfinal->sendSampler2D("colorMap", getLastFBO()->getColorTexture(2), 0); m_shaderSSAOfinal->sendSampler2D("ssaoMap", a->getColorTexture(2), 1); m_sfq.renderGeometry(); m_shaderSSAOfinal->unbind(); unbindFBO(); delete a; delete b; }
void CGrassDrawer::CreateFarTex() { int sizeMod=2; glGenTextures(1, &farTex); glBindTexture(GL_TEXTURE_2D, farTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGBA8, 1024, 64); FBO fboTex; fboTex.Bind(); fboTex.AttachTexture(farTex); fboTex.CheckStatus("GRASSDRAWER1"); FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, 1024 * sizeMod, 64 * sizeMod); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, 1024 * sizeMod, 64 * sizeMod); fbo.CheckStatus("GRASSDRAWER2"); if (!fboTex.IsValid() || !fbo.IsValid()) { grassOff = true; return; } glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glDisable(GL_FOG); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glEnable(GL_TEXTURE_2D); glColor4f(1,1,1,1); glViewport(0,0,1024*sizeMod, 64*sizeMod); glClearColor(0.75f,0.9f,0.75f,0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f,0.f,0.f,0.f); // render turf from different vertical angles for (int a=0;a<16;++a) { glViewport(a*64*sizeMod, 0, 64*sizeMod, 64*sizeMod); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef((a-1)*90/15.0f,1,0,0); glTranslatef(0,-0.5f,0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-partTurfSize, partTurfSize, -partTurfSize, partTurfSize, -turfSize, turfSize); glCallList(grassDL); } glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); // scale down the rendered fartextures (MSAA) and write to the final texture glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo.fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, fboTex.fboId); glBlitFramebufferEXT(0, 0, 1024*sizeMod, 64*sizeMod, 0, 0, 1024, 64, GL_COLOR_BUFFER_BIT, GL_LINEAR); fbo.Unbind(); // compute mipmaps glBindTexture(GL_TEXTURE_2D, farTex); glGenerateMipmap(GL_TEXTURE_2D); }
void CGlobalRendering::PostInit() { supportNPOTs = GLEW_ARB_texture_non_power_of_two; haveARB = GLEW_ARB_vertex_program && GLEW_ARB_fragment_program; haveGLSL = (glGetString(GL_SHADING_LANGUAGE_VERSION) != NULL); haveGLSL &= GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader; haveGLSL &= !!GLEW_VERSION_2_0; // we want OpenGL 2.0 core functions { const char* glVendor = (const char*) glGetString(GL_VENDOR); const char* glRenderer = (const char*) glGetString(GL_RENDERER); const std::string vendor = (glVendor != NULL)? StringToLower(std::string(glVendor)): ""; const std::string renderer = (glRenderer != NULL)? StringToLower(std::string(glRenderer)): ""; haveATI = (vendor.find("ati ") != std::string::npos) || (vendor.find("amd ") != std::string::npos); haveMesa = (renderer.find("mesa ") != std::string::npos) || (renderer.find("gallium ") != std::string::npos); haveIntel = (vendor.find("intel") != std::string::npos); haveNvidia = (vendor.find("nvidia ") != std::string::npos); //FIXME Neither Intel's nor Mesa's GLSL implementation seem to be in a workable state atm (date: Nov. 2011) haveGLSL &= !haveIntel; haveGLSL &= !haveMesa; //FIXME add an user config to force enable it! if (haveATI) { // x-series doesn't support NPOTs (but hd-series does) supportNPOTs = (renderer.find(" x") == std::string::npos && renderer.find(" 9") == std::string::npos); } } // use some ATI bugfixes? const int atiHacksCfg = configHandler->GetInt("AtiHacks"); atiHacks = haveATI && (atiHacksCfg < 0); // runtime detect atiHacks |= (atiHacksCfg > 0); // user override // Runtime compress textures? if (GLEW_ARB_texture_compression) { // we don't even need to check it, 'cos groundtextures must have that extension // default to off because it reduces quality (smallest mipmap level is bigger) compressTextures = configHandler->GetBool("CompressTextures"); } #ifdef GLEW_NV_primitive_restart supportRestartPrimitive = !!(GLEW_NV_primitive_restart); #endif // maximum 2D texture size { glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); } // retrieve maximu smoothed PointSize float2 aliasedPointSizeRange, smoothPointSizeRange; glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, (GLfloat*)&aliasedPointSizeRange); glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, (GLfloat*)&smoothPointSizeRange); maxSmoothPointSize = std::min(aliasedPointSizeRange.y, smoothPointSizeRange.y); // some GLSL relevant information { glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &glslMaxUniformBufferBindings); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &glslMaxUniformBufferSize); glGetIntegerv(GL_MAX_VARYING_FLOATS, &glslMaxVaryings); glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &glslMaxAttributes); glGetIntegerv(GL_MAX_DRAW_BUFFERS, &glslMaxDrawBuffers); glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &glslMaxRecommendedIndices); glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &glslMaxRecommendedVertices); glslMaxVaryings /= 4; // GL_MAX_VARYING_FLOATS returns max individual floats, we want float4 } // detect if GL_DEPTH_COMPONENT24 is supported (many ATIs don't do so) { // ATI seems to support GL_DEPTH_COMPONENT24 for static textures, but you can't render to them /* GLint state = 0; glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 16, 16, 0, GL_LUMINANCE, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &state); support24bitDepthBuffers = (state > 0); */ support24bitDepthBuffers = false; if (FBO::IsSupported() && !atiHacks) { const int fboSizeX = 16, fboSizeY = 16; FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, fboSizeX, fboSizeY); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT24, fboSizeX, fboSizeY); const GLenum status = fbo.GetStatus(); fbo.Unbind(); support24bitDepthBuffers = (status == GL_FRAMEBUFFER_COMPLETE_EXT); } } // print info LOG( "GL info:\n" "\thaveARB: %i, haveGLSL: %i, ATI hacks: %i\n" "\tFBO support: %i, NPOT-texture support: %i, 24bit Z-buffer support: %i\n" "\tmaximum texture size: %i, compress MIP-map textures: %i\n" "\tmaximum SmoothPointSize: %0.0f, maximum vec4 varying/attributes: %i/%i\n" "\tmaximum drawbuffers: %i, maximum recommended indices/vertices: %i/%i\n" "\tnumber of UniformBufferBindings: %i (%ikB)", haveARB, haveGLSL, atiHacks, FBO::IsSupported(), supportNPOTs, support24bitDepthBuffers, maxTextureSize, compressTextures, maxSmoothPointSize, glslMaxVaryings, glslMaxAttributes, glslMaxDrawBuffers, glslMaxRecommendedIndices, glslMaxRecommendedVertices, glslMaxUniformBufferBindings, glslMaxUniformBufferSize / 1024 ); teamNanospray = configHandler->GetBool("TeamNanoSpray"); }
int LuaFBOs::meta_gc(lua_State* L) { FBO* fbo = (FBO*)luaL_checkudata(L, 1, "FBO"); fbo->Free(L); return 0; }
void Composer::movitRender( Frame *dst, bool update ) { int i, j, start=0; Frame *f; //QTime time; //time.start(); Profile projectProfile = sampler->getProfile(); // find the lowest frame to process for ( j = 0 ; j < dst->sample->frames.count(); ++j ) { if ( (f = dst->sample->frames[j]->frame) ) { start = j; break; } } // build a "description" of the required chain // processing frames from bottom to top i = start; double pts = sampler->currentPTS(); QStringList currentDescriptor; int ow = projectProfile.getVideoWidth(); int oh = projectProfile.getVideoHeight(); while ( (f = getNextFrame( dst, i )) ) { FrameSample *sample = dst->sample->frames[i - 1]; // input and filters movitFrameDescriptor( "-", f, &sample->videoFilters, currentDescriptor, &projectProfile ); // transition if ( sample->transitionFrame.frame && !sample->transitionFrame.videoTransitionFilter.isNull() ) { // filters applied on first transition frame, if any currentDescriptor.append( "--" + sample->transitionFrame.videoTransitionFilter->getDescriptorFirst( pts, f, &projectProfile ) ); movitFrameDescriptor( "->", sample->transitionFrame.frame, &sample->transitionFrame.videoFilters, currentDescriptor, &projectProfile ); // filters applied on second transition frame, if any currentDescriptor.append( "-->" + sample->transitionFrame.videoTransitionFilter->getDescriptorSecond( pts, sample->transitionFrame.frame, &projectProfile ) ); currentDescriptor.append( "-<" + sample->transitionFrame.videoTransitionFilter->getDescriptor( pts, sample->transitionFrame.frame, &projectProfile ) ); } // overlay if ( (i - 1) > start ) currentDescriptor.append( GLOverlay().getDescriptor( pts, f, &projectProfile ) ); ow = f->glWidth; oh = f->glHeight; } // background currentDescriptor.append( movitBackground.getDescriptor( pts, NULL, &projectProfile ) ); // output if (outputResize.width() > 0) { currentDescriptor.append( QString("Resized output %1 %2").arg( outputResize.width() ).arg( outputResize.height() ) ); } else { currentDescriptor.append( QString("OUTPUT %1 %2").arg( ow ).arg( oh ) ); } // rebuild the chain if neccessary if ( currentDescriptor != movitChain.descriptor ) { for ( int k = 0; k < currentDescriptor.count(); k++ ) printf("%s\n", currentDescriptor[k].toLocal8Bit().data()); movitChain.descriptor = currentDescriptor; movitChain.reset(); movitChain.chain = new EffectChain( projectProfile.getVideoSAR() * projectProfile.getVideoWidth(), projectProfile.getVideoHeight(), movitPool ); i = start; Effect *last, *current = NULL; while ( (f = getNextFrame( dst, i )) ) { last = current; // input and filters MovitBranch *branch; FrameSample *sample = dst->sample->frames[i - 1]; current = movitFrameBuild( f, &sample->videoFilters, &branch ); // transition if ( sample->transitionFrame.frame && !sample->transitionFrame.videoTransitionFilter.isNull() ) { QList<Effect*> el = sample->transitionFrame.videoTransitionFilter->getMovitEffects(); // filters applied on first transition frame, if any QList<Effect*> first = sample->transitionFrame.videoTransitionFilter->getMovitEffectsFirst(); for ( int l = 0; l < first.count(); ++l ) current = movitChain.chain->add_effect( first.at( l ) ); MovitBranch *branchTrans; Effect *currentTrans = movitFrameBuild( sample->transitionFrame.frame, &sample->transitionFrame.videoFilters, &branchTrans ); // filters applied on second transition frame, if any QList<Effect*> second = sample->transitionFrame.videoTransitionFilter->getMovitEffectsSecond(); for ( int l = 0; l < second.count(); ++l ) currentTrans = movitChain.chain->add_effect( second.at( l ) ); branchTrans->filters.append( new MovitFilter( el ) ); for ( int l = 0; l < el.count(); ++l ) current = movitChain.chain->add_effect( el.at( l ), current, currentTrans ); } // overlay if ( last ) { GLOverlay *overlay = new GLOverlay(); QList<Effect*> el = overlay->getMovitEffects(); branch->overlay = new MovitFilter( el, overlay ); for ( int l = 0; l < el.count(); ++l ) current = movitChain.chain->add_effect( el.at( l ), last, current ); } } // background QList<Effect*> el = movitBackground.getMovitEffects(); movitChain.chain->add_effect( el[0] ); // output resizer if (outputResize.width() > 0) { Effect *e = new ResampleEffect(); e->set_int( "width", outputResize.width() ); e->set_int( "height", outputResize.height() ); movitChain.chain->add_effect( e ); } // output movitChain.chain->set_dither_bits( 8 ); ImageFormat output_format; output_format.color_space = COLORSPACE_sRGB; output_format.gamma_curve = GAMMA_REC_709; movitChain.chain->add_output( output_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED ); movitChain.chain->finalize(); } // update inputs data and filters parameters i = start, j = 0; int w = projectProfile.getVideoWidth(); int h = projectProfile.getVideoHeight(); while ( (f = getNextFrame( dst, i )) ) { f->glWidth = f->profile.getVideoWidth(); f->glHeight = f->profile.getVideoHeight(); f->glSAR = f->profile.getVideoSAR(); f->glOVD = 0; f->glOVDTransformList.clear(); // input and filters MovitBranch *branch = movitChain.branches[ j++ ]; branch->input->process( f, &gl ); int vf = 0; FrameSample *sample = dst->sample->frames[i - 1]; for ( int k = 0; k < branch->filters.count(); ++k ) { if ( !branch->filters[k]->filter ) sample->videoFilters[vf++]->process( branch->filters[k]->effects, pts, f, &projectProfile ); else branch->filters[k]->filter->process( branch->filters[k]->effects, pts, f, &projectProfile ); } // transition if ( sample->transitionFrame.frame && !sample->transitionFrame.videoTransitionFilter.isNull() ) { sample->transitionFrame.frame->glWidth = sample->transitionFrame.frame->profile.getVideoWidth(); sample->transitionFrame.frame->glHeight = sample->transitionFrame.frame->profile.getVideoHeight(); sample->transitionFrame.frame->glSAR = sample->transitionFrame.frame->profile.getVideoSAR(); MovitBranch *branchTrans = movitChain.branches[ j++ ]; branchTrans->input->process( sample->transitionFrame.frame, &gl ); int tvf = 0; int k; for ( k = 0; k < branchTrans->filters.count() - 1; ++k ) { if ( !branchTrans->filters[k]->filter ) sample->transitionFrame.videoFilters[tvf++]->process( branchTrans->filters[k]->effects, pts, sample->transitionFrame.frame, &projectProfile ); else branchTrans->filters[k]->filter->process( branchTrans->filters[k]->effects, pts, sample->transitionFrame.frame, &projectProfile ); } sample->transitionFrame.videoTransitionFilter->process( branchTrans->filters[k]->effects, pts, f, sample->transitionFrame.frame, &projectProfile ); } // overlay if ( branch->overlay && branch->overlay->filter ) branch->overlay->filter->process( branch->overlay->effects, pts, f, f, &projectProfile ); w = f->glWidth; h = f->glHeight; } // render waitFence(); // output resizer if (outputResize.width() > 0) { w = outputResize.width(); h = outputResize.height(); } FBO *fbo = gl.getFBO( w, h, GL_RGBA ); movitChain.chain->render_to_fbo( fbo->fbo(), w, h ); dst->glWidth = w; dst->glHeight = h; dst->glSAR = projectProfile.getVideoSAR(); if ( !update ) { dst->setVideoFrame( Frame::GLTEXTURE, w, h, dst->glSAR, projectProfile.getVideoInterlaced(), projectProfile.getVideoTopFieldFirst(), pts, projectProfile.getVideoFrameDuration() ); } dst->setFBO( fbo ); dst->setFence( gl.getFence() ); composerFence = gl.getFence(); glFlush(); //qDebug() << "elapsed" << time.elapsed(); }
int main(void) { srand(time(NULL)); //Create init object Init init = Init(); //Initialize glfw init.glfw(4, 1); //Open a window GLFWwindow *window = init.window(400, 400); //Print window info init.printWindowInfo(window); //Make opened window current context glfwMakeContextCurrent(window); init.glew(); int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glEnable(GL_CULL_FACE); // Nvidia cards require a vertex array to cooperate. GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); //Set up the initial state. unsigned int w = 32, h = 32, d = 32; State *prevState = new State(w, h, d); VelocityGrid *velocities = new VelocityGrid(w, h, d); prevState->setVelocityGrid(velocities); // init level set LevelSet *ls = factory::levelSet::ball(w, h, d); prevState->setLevelSet(ls); delete ls; // init simulator Simulator sim(*prevState, 0.1f); // BubbleMaxExporter bubbleExporter; // Dark black background glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Load in shaders static ShaderProgram colorCubeProg("../vertShader.vert", "../colorCube.frag"); static ShaderProgram rayCasterProg("../vertShader.vert", "../rayCaster.frag"); static ShaderProgram bubbleProg("../bubbleVertShader.vert", "../bubbleFragShader.frag"); static const GLfloat vertexBufferData[] = { -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; static const GLuint triangleBufferData[] = { // xy plane (z = -1) 0, 1, 3, 3, 2, 0, // xz plane (y = -1) 0, 5, 1, 0, 4, 5, // yz plane (x = -1) 0, 2, 4, 2, 6, 4, // xy plane (z = 1) 4, 7, 5, 4, 6, 7, // xz plane (y = 1) 2, 7, 6, 2, 3, 7, // yz plane (x = 1) 1, 5, 3, 3, 5, 7 }; std::vector<GLfloat> g_bubble_buffer_data; //Create vertex buffer GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexBufferData), vertexBufferData, GL_STATIC_DRAW); GLuint triangleBuffer; glGenBuffers(1, &triangleBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(triangleBufferData), triangleBufferData, GL_STATIC_DRAW); // Create bubble buffer GLuint bubbleBuffer; glGenBuffers(1, &bubbleBuffer); // Create framebuffer FBO *framebuffer = new FBO(width, height); GLuint volumeTextureId; glGenTextures(1, &volumeTextureId); glBindTexture(GL_TEXTURE_3D, volumeTextureId); //Object which encapsulates a texture + The destruction of a texture. Texture3D tex3D(w, h, d); double lastTime = glfwGetTime(); int nbFrames = 0; float deltaT = 0.1; //First time step glfwSwapInterval(1); int i = 0; do { framebuffer->activate(); // common for both render passes. sim.step(deltaT); // deltaT = sim.getDeltaT(); glm::mat4 matrix = glm::mat4(1.0f); matrix = glm::translate(matrix, glm::vec3(0.0f, 0.0f, 2.0f)); matrix = glm::rotate(matrix, -3.1415926535f / 4.0f, glm::vec3(1.0f, 0.0f, 0.0f)); matrix = glm::rotate(matrix, 0.1415926535f / 4.0f * (float) glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f)); // Render back face of the cube. colorCubeProg(); glCullFace(GL_FRONT); { GLuint tLocation = glGetUniformLocation(colorCubeProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(colorCubeProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); } glClear(GL_COLOR_BUFFER_BIT); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleBuffer); //Triangle coordinates glVertexAttribPointer( 0, // Location 0 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *) 0 // array buffer offset ); glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); // Do the ray casting. glBindFramebuffer(GL_FRAMEBUFFER, 0); // bind the screen glCullFace(GL_BACK); rayCasterProg(); { GLuint tLocation = glGetUniformLocation(rayCasterProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(rayCasterProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); GLuint windowSizeLocation = glGetUniformLocation(rayCasterProg, "windowSize"); glUniform2f(windowSizeLocation, width, height); } glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, *(framebuffer->getTexture())); GLuint textureLocation = glGetUniformLocation(rayCasterProg, "backfaceTexture"); glUniform1i(textureLocation, 0); State *currentState = sim.getCurrentState(); std::vector<glm::vec3> vertexList; std::vector<std::vector<int> > faceIndices; // copy desired quantities to texture for (unsigned int k = 0; k < d; ++k) { for (unsigned int j = 0; j < h; ++j) { for (unsigned int i = 0; i < w; ++i) { // velocity //tex3D.set(i,j,k,0, 0.5 + 0.5*currentState.getVelocityGrid()->u->get(i,j,k)); //tex3D.set(i,j,1, 0.5 + 0.5*currentState.getVelocityGrid()->v->get(i,j)); //tex3D.set(i,j,2, 0.5 + currentState.getCellTypeGrid()->get(i, j)); //tex3D.set(i,j,2, 0.5); //tex3D.set(i,j,3, 1.0f); // divergence //tex3D.set(i,j,0, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,1, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,2, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,3, 1.0f); // type // tex3D.set(i,j,k, 0, currentState.getCellTypeGrid()->get(i,j, k) == CellType::FLUID ? 1.0 : 0.0); // tex3D.set(i,j,k, 1, currentState.getCellTypeGrid()->get(i,j, k) == CellType::FLUID ? 1.0 : 0.0); // tex3D.set(i,j,k, 2, currentState.getCellTypeGrid()->get(i,j, k) == CellType::SOLID ? 1.0 : 0.0); // tex3D.set(i,j,k, 3, 1.0f); if(currentState->getSignedDistanceGrid()->isValid(i+1,j,k) && currentState->getSignedDistanceGrid()->isValid(i,j+1,k) && currentState->getSignedDistanceGrid()->isValid(i+1,j+1,k) && currentState->getSignedDistanceGrid()->isValid(i,j,k+1) && currentState->getSignedDistanceGrid()->isValid(i+1,j,k+1) && currentState->getSignedDistanceGrid()->isValid(i,j+1,k+1) && currentState->getSignedDistanceGrid()->isValid(i+1,j+1,k+1)){ marchingCubes::GRIDCELL gridcell; gridcell.p[0] = glm::vec3(i,j,k); gridcell.p[1] = glm::vec3(i,j+1,k); gridcell.p[2] = glm::vec3(i+1,j+1,k); gridcell.p[3] = glm::vec3(i+1,j,k); gridcell.p[4] = glm::vec3(i,j,k+1); gridcell.p[5] = glm::vec3(i,j+1,k+1); gridcell.p[6] = glm::vec3(i+1,j+1,k+1); gridcell.p[7] = glm::vec3(i+1,j,k+1); gridcell.val[0] = currentState->getSignedDistanceGrid()->get(i, j, k); gridcell.val[1] = currentState->getSignedDistanceGrid()->get(i, j+1, k); gridcell.val[2] = currentState->getSignedDistanceGrid()->get(i+1, j+1, k); gridcell.val[3] = currentState->getSignedDistanceGrid()->get(i+1, j, k); gridcell.val[4] = currentState->getSignedDistanceGrid()->get(i, j, k+1); gridcell.val[5] = currentState->getSignedDistanceGrid()->get(i, j+1, k+1); gridcell.val[6] = currentState->getSignedDistanceGrid()->get(i+1, j+1, k+1); gridcell.val[7] = currentState->getSignedDistanceGrid()->get(i+1, j, k+1); //std::cout << gridcell.val[0] << std::endl; marchingCubes::TRIANGLE *triangles = new marchingCubes::TRIANGLE[5]; int numTriangles = marchingCubes::PolygoniseCube(gridcell, 0.0, triangles); for(int i = 0; i < numTriangles; i++){ int startIndex = vertexList.size()+1; for(int j = 0; j < 3; j++){ //std::cout << triangles[i].p[j].x << " " << triangles[i].p[j].y << " " << triangles[i].p[j].z << std::endl; } vertexList.push_back(triangles[i].p[0]); vertexList.push_back(triangles[i].p[1]); vertexList.push_back(triangles[i].p[2]); std::vector<int> indices = { startIndex, startIndex+1, startIndex+2 }; faceIndices.push_back(indices); } delete[] triangles; } //signed dist float dist = currentState->getSignedDistanceGrid()->get(i, j, k); float solid = currentState->getCellTypeGrid()->get(i, j, k) == CellType::SOLID ? 1.0f : 0.0f; dist = (glm::clamp(dist + solid, -1.0f, 1.0f) + 1) / 2; tex3D.set(i, j, k, 0, solid); tex3D.set(i, j, k, 1, 0.0f); // not used tex3D.set(i, j, k, 2, dist); tex3D.set(i, j, k, 3, 1.0f); //closest point // tex3D.set(i,j,0, currentState.getClosestPointGrid()->get(i,j).x / 70.0); // tex3D.set(i,j,1, currentState.getClosestPointGrid()->get(i,j).y / 70.0); // tex3D.set(i,j,2, 0.0f); // tex3D.set(i,j,3, 1.0f); } } } printObjToFile("exported_" + std::to_string(i) + ".obj", vertexList, faceIndices); std::ofstream fileStream("exportedState_" + std::to_string(i) + ".pf", std::ios::binary); currentState->write(fileStream); fileStream.close(); // activate and upload texture to gpu tex3D(GL_TEXTURE1); GLuint volumeTextureLocation = glGetUniformLocation(rayCasterProg, "volumeTexture"); glUniform1i(volumeTextureLocation, 1); glEnableVertexAttribArray(0); glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); FBO::deactivate(); ////////////////// Start drawing bubbles ////////////////////// // Draw bubbles const std::vector<Bubble> bubbles = currentState->getBubbles(); g_bubble_buffer_data.clear(); std::cout << "frame=" << i << ", nBubbles=" << bubbles.size() << std::endl; for (int i = 0; i < bubbles.size(); i++) { Bubble b = bubbles.at(i); // std::cout << "bubble pos " << b.position.x << ", " << b.position.y << std::endl << b.radius << std::endl; g_bubble_buffer_data.push_back(b.position.x / (float)w * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.position.y / (float)h * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.position.z / (float)d * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.radius); } glBindBuffer(GL_ARRAY_BUFFER, bubbleBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * g_bubble_buffer_data.size(), &g_bubble_buffer_data[0], GL_DYNAMIC_DRAW); bubbleProg(); glEnable(GL_PROGRAM_POINT_SIZE); { GLuint tLocation = glGetUniformLocation(colorCubeProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(colorCubeProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); } // glEnable (GL_BLEND); // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPointSize(4.0); if (g_bubble_buffer_data.size() > 0) { glEnable(GL_PROGRAM_POINT_SIZE); glEnableVertexAttribArray(0); glVertexAttribPointer( 0, //Location 0 4, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glDrawArrays(GL_POINTS, 0, 4 * g_bubble_buffer_data.size()); // 3 indices starting at 0 -> 1 triangle glDisableVertexAttribArray(0); } ////////////////// End drawing bubbles ////////////////////// glfwPollEvents(); glfwSwapBuffers(window); double currentTime = glfwGetTime(); nbFrames++; if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1 sec ago // printf and reset timer std::string title = std::to_string(1000.0 / double(nbFrames)) + "ms/frame " + std::to_string(deltaT) + " dt"; glfwSetWindowTitle(window, title.c_str()); nbFrames = 0; lastTime += 1.0; } i++; // bubbleExporter.update(i, sim.getBubbleTracker()); // bubbleExporter.exportSnapshot(i, "bubbles_" + std::to_string(i) + ".mx"); /* if (i > 600) { bubbleExporter.exportBubbles("bubbles.mx"); break; }*/ } // Check if the ESC key was pressed or the window was closed while (!glfwWindowShouldClose(window)); std::cout << "Cleaning up!" << std::endl; // Close OpenGL window and terminate GLFW glfwDestroyWindow(window); glfwTerminate(); glDeleteBuffers(1, &vertexbuffer); glDeleteVertexArrays(1, &VertexArrayID); exit(EXIT_SUCCESS); }
void CDecalsDrawerGL4::GenerateAtlasTexture() { std::unordered_map<std::string, STex> textures; GetBuildingDecals(textures); GetGroundScars(textures); GetFallbacks(textures); CQuadtreeAtlasAlloc atlas; atlas.SetNonPowerOfTwo(globalRendering->supportNPOTs); atlas.SetMaxSize(globalRendering->maxTextureSize, globalRendering->maxTextureSize); for (auto it = textures.begin(); it != textures.end(); ++it) { if (it->second.id == 0) continue; const float maxSize = 1024; //512; int2 size = it->second.size; if (size.x > maxSize) { size.y = size.y * (maxSize / size.x); size.x = maxSize; } if (size.y > maxSize) { size.x = size.x * (maxSize / size.y); size.y = maxSize; } atlas.AddEntry(it->first, size); } /*bool success =*/ atlas.Allocate(); glGenTextures(1, &atlasTex); glBindTexture(GL_TEXTURE_2D, atlasTex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f); glSpringTexStorage2D(GL_TEXTURE_2D, atlas.GetMaxMipMaps(), GL_RGBA8, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); FBO fb; if (!fb.IsValid()) { LOG_L(L_ERROR, "[%s] framebuffer not valid", __FUNCTION__); return; } fb.Bind(); fb.AttachTexture(atlasTex); if (!fb.CheckStatus(LOG_SECTION_DECALS_GL4)) { LOG_L(L_ERROR, "[%s] Couldn't render to FBO!", __FUNCTION__); return; } glViewport(0, 0, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); glSpringMatrix2dProj(atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // transparent black glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_DEPTH_TEST); CVertexArray va; for (auto& p: textures) { if (p.second.id == 0) continue; const float4 texCoords = atlas.GetTexCoords(p.first); const float4 absCoords = atlas.GetEntry(p.first); atlasTexs[p.first] = SAtlasTex(texCoords); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBindTexture(GL_TEXTURE_2D, p.second.id); va.Initialize(); va.AddVertex2dT(absCoords.x, absCoords.y, 0.0f, 0.0f); va.AddVertex2dT(absCoords.z+1, absCoords.y, 1.0f, 0.0f); //FIXME why +1? va.AddVertex2dT(absCoords.x, absCoords.w+1, 0.0f, 1.0f); va.AddVertex2dT(absCoords.z+1, absCoords.w+1, 1.0f, 1.0f); //FIXME why +1? va.DrawArray2dT(GL_TRIANGLE_STRIP); glDeleteTextures(1, &p.second.id); } fb.Unbind(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, atlasTex); glGenerateMipmap(GL_TEXTURE_2D); #ifdef DEBUG_SAVE_ATLAS glSaveTexture(atlasTex, "x_decal_atlas.png"); #endif }