Ticket #1380: waterFramebuffer.patch

File waterFramebuffer.patch, 10.6 KB (added by wraitii, 10 years ago)
  • source/renderer/WaterManager.cpp

     
    6969    m_RefractionTexture = 0;
    7070    m_ReflectionTextureSize = 0;
    7171    m_RefractionTextureSize = 0;
     72    m_WaterBuffer = -1;
    7273    m_WaterTexTimer = 0.0;
    7374    m_SpecularStrength = 0.6f;
    7475    m_Waviness = 8.0f;
     
    211212    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    212213    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    213214
     215    // Create the water framebuffer
     216    m_WaterBuffer = 0;
     217    pglGenFramebuffersEXT(1, &m_WaterBuffer);
     218
    214219    // Enable rendering, now that we've succeeded this far
    215220    m_RenderWater = true;
    216221
     
    227232        m_WaterTexture[i].reset();
    228233    }
    229234
    230 
    231235    for(size_t i = 0; i < ARRAY_SIZE(m_NormalMap); i++)
    232236    {
    233237        m_NormalMap[i].reset();
    234238    }
     239    glDeleteTextures(1, &m_ReflectionTexture);
     240    glDeleteTextures(1, &m_RefractionTexture);
     241    glDeleteFramebuffers(1, &m_WaterBuffer);
    235242}
    236243
    237244///////////////////////////////////////////////////////////////////
  • source/renderer/WaterManager.h

     
    107107    size_t m_ReflectionTextureSize;
    108108    size_t m_RefractionTextureSize;
    109109
     110    // framebuffer object
     111    GLuint m_WaterBuffer;
     112   
    110113    // Model-view-projection matrices for reflected & refracted cameras
    111114    // (used to let the vertex shader do projective texturing)
    112115    CMatrix3D m_ReflectionMatrix;
  • source/renderer/Renderer.cpp

     
    11311131{
    11321132    PROFILE3_GPU("water reflections");
    11331133
     1134    // Save the post-processing framebuffer.
     1135    GLint fbo;
     1136    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
     1137   
    11341138    WaterManager& wm = m->waterManager;
    11351139
    11361140    // Remember old camera
     
    11571161    scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
    11581162    m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat;
    11591163
    1160     m->SetOpenGLCamera(m_ViewCamera);
    1161 
    11621164    CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight);
    11631165    SetObliqueFrustumClipping(camPlane);
    11641166
     
    11701172    screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
    11711173    screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
    11721174    screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
    1173 
    1174     if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
     1175   
     1176    glEnable(GL_SCISSOR_TEST);
     1177    glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1178   
     1179    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_WaterBuffer);
     1180    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_ReflectionTexture, 0);
     1181   
     1182    GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     1183    if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
    11751184    {
    1176         glEnable(GL_SCISSOR_TEST);
    1177         glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1178 
    1179         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    1180 
    1181         glFrontFace(GL_CW);
    1182 
    1183         // Render sky, terrain and models
    1184         m->skyManager.RenderSky();
    1185         ogl_WarnIfError();
    1186         RenderPatches(context, &m_ViewCamera.GetFrustum());
    1187         ogl_WarnIfError();
    1188         RenderModels(context, &m_ViewCamera.GetFrustum());
    1189         ogl_WarnIfError();
    1190         RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
    1191         ogl_WarnIfError();
    1192 
    1193         glFrontFace(GL_CCW);
    1194 
    1195         glDisable(GL_SCISSOR_TEST);
    1196 
    1197         // Copy the image to a texture
    1198         pglActiveTextureARB(GL_TEXTURE0);
    1199         glEnable(GL_TEXTURE_2D);
    1200         glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
    1201         glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
    1202                 screenScissor.x1, screenScissor.y1,
    1203                 screenScissor.x1, screenScissor.y1,
    1204                 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1185        wm.m_WaterBuffer = -1;
     1186        // revert to old method
     1187        if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
     1188        {
     1189            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     1190           
     1191            glFrontFace(GL_CW);
     1192           
     1193            // Render sky, terrain and models
     1194            m->skyManager.RenderSky();
     1195            ogl_WarnIfError();
     1196            RenderPatches(context, &m_ViewCamera.GetFrustum());
     1197            ogl_WarnIfError();
     1198            RenderModels(context, &m_ViewCamera.GetFrustum());
     1199            ogl_WarnIfError();
     1200            RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1201            ogl_WarnIfError();
     1202           
     1203            glFrontFace(GL_CCW);
     1204           
     1205            glDisable(GL_SCISSOR_TEST);
     1206           
     1207            // Copy the image to a texture
     1208            pglActiveTextureARB(GL_TEXTURE0);
     1209            glEnable(GL_TEXTURE_2D);
     1210            glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
     1211            glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
     1212                                screenScissor.x1, screenScissor.y1,
     1213                                screenScissor.x1, screenScissor.y1,
     1214                                screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1215        }
     1216        // Reset old camera
     1217        m_ViewCamera = normalCamera;
     1218        m->SetOpenGLCamera(m_ViewCamera);
     1219       
     1220        return screenScissor;
    12051221    }
    12061222
     1223    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1224    glClear(GL_COLOR_BUFFER_BIT);
     1225    glFrontFace(GL_CW);
     1226   
     1227    // Render sky, terrain and models
     1228    m->skyManager.RenderSky();
     1229    ogl_WarnIfError();
     1230    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1231    ogl_WarnIfError();
     1232    RenderModels(context, &m_ViewCamera.GetFrustum());
     1233    ogl_WarnIfError();
     1234    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1235    ogl_WarnIfError();
     1236   
     1237    glFrontFace(GL_CCW);
     1238    glDisable(GL_SCISSOR_TEST);
     1239
    12071240    // Reset old camera
    12081241    m_ViewCamera = normalCamera;
    12091242    m->SetOpenGLCamera(m_ViewCamera);
    12101243
     1244    // rebind post-processing frambuffer.
     1245    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1246
    12111247    return screenScissor;
    12121248}
    12131249
     
    12181254{
    12191255    PROFILE3_GPU("water refractions");
    12201256
     1257    // Save the post-processing framebuffer.
     1258    GLint fbo;
     1259    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
     1260   
    12211261    WaterManager& wm = m->waterManager;
    12221262
    12231263    // Remember old camera
     
    12411281    scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
    12421282    m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat;
    12431283
    1244     m->SetOpenGLCamera(m_ViewCamera);
    1245 
    12461284    CVector4D camPlane(0, -1, 0, wm.m_WaterHeight);
    12471285    SetObliqueFrustumClipping(camPlane);
    12481286
     
    12541292    screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
    12551293    screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
    12561294    screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
    1257     if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
    1258     {
    1259         glEnable(GL_SCISSOR_TEST);
    1260         glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1261 
    1262         glClearColor(0.5f, 0.5f, 0.5f, 1.0f);       // a neutral gray to blend in with shores
    1263         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    12641295
    1265         // Render terrain and models
    1266         RenderPatches(context, &m_ViewCamera.GetFrustum());
    1267         ogl_WarnIfError();
    1268         RenderModels(context, &m_ViewCamera.GetFrustum());
    1269         ogl_WarnIfError();
    1270         RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
    1271         ogl_WarnIfError();
    1272 
    1273         glDisable(GL_SCISSOR_TEST);
    1274 
    1275         // Copy the image to a texture
    1276         pglActiveTextureARB(GL_TEXTURE0);
    1277         glEnable(GL_TEXTURE_2D);
    1278         glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
    1279         glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
    1280                 screenScissor.x1, screenScissor.y1,
    1281                 screenScissor.x1, screenScissor.y1,
    1282                 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1296    glEnable(GL_SCISSOR_TEST);
     1297    glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1298   
     1299    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_WaterBuffer);
     1300    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_RefractionTexture, 0);
     1301   
     1302    GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     1303    if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
     1304    {
     1305        wm.m_WaterBuffer = -1;
     1306        // revert to old method
     1307        if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
     1308        {
     1309            glEnable(GL_SCISSOR_TEST);
     1310            glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1311           
     1312            glClearColor(0.5f, 0.5f, 0.5f, 1.0f);       // a neutral gray to blend in with shores
     1313            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     1314           
     1315            // Render terrain and models
     1316            RenderPatches(context, &m_ViewCamera.GetFrustum());
     1317            ogl_WarnIfError();
     1318            RenderModels(context, &m_ViewCamera.GetFrustum());
     1319            ogl_WarnIfError();
     1320            RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1321            ogl_WarnIfError();
     1322           
     1323            glDisable(GL_SCISSOR_TEST);
     1324           
     1325            // Copy the image to a texture
     1326            pglActiveTextureARB(GL_TEXTURE0);
     1327            glEnable(GL_TEXTURE_2D);
     1328            glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
     1329            glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
     1330                                screenScissor.x1, screenScissor.y1,
     1331                                screenScissor.x1, screenScissor.y1,
     1332                                screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1333        }
     1334        // Reset old camera
     1335        m_ViewCamera = normalCamera;
     1336        m->SetOpenGLCamera(m_ViewCamera);
     1337       
     1338        return screenScissor;
    12831339    }
     1340   
     1341    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1342    glClear(GL_COLOR_BUFFER_BIT);
    12841343
     1344    // Render sky, terrain and models
     1345    m->skyManager.RenderSky();
     1346    ogl_WarnIfError();
     1347    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1348    ogl_WarnIfError();
     1349    RenderModels(context, &m_ViewCamera.GetFrustum());
     1350    ogl_WarnIfError();
     1351    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1352    ogl_WarnIfError();
     1353   
     1354    glDisable(GL_SCISSOR_TEST);
     1355   
    12851356    // Reset old camera
    12861357    m_ViewCamera = normalCamera;
    12871358    m->SetOpenGLCamera(m_ViewCamera);
    1288 
     1359   
     1360    // rebind post-processing frambuffer.
     1361    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1362   
    12891363    return screenScissor;
    12901364}
    12911365
    1292 
    12931366void CRenderer::RenderSilhouettes(const CShaderDefines& context)
    12941367{
    12951368    PROFILE3_GPU("silhouettes");
     
    15081581                dirty.x2 = reflectionScissor.x2;
    15091582                dirty.y2 = reflectionScissor.y2;
    15101583            }
    1511             if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2)
     1584            if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2 && m_WaterManager->m_WaterBuffer == (GLuint)-1)
    15121585            {
    15131586                glEnable(GL_SCISSOR_TEST);
    15141587                glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1);