Ticket #1380: waterFramebuffer.2.patch

File waterFramebuffer.2.patch, 13.5 KB (added by wraitii, 10 years ago)
  • Users/Lancelot/Desktop/0ad-svn/trunk/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    // try binding the framebuffer
     1180    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_WaterBuffer);
     1181    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_ReflectionTexture, 0);
     1182   
     1183    GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     1184    if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
    11751185    {
    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);
     1186        wm.m_WaterBuffer = -1;
     1187        // revert to old method
     1188        if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
     1189        {
     1190            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     1191           
     1192            glFrontFace(GL_CW);
     1193           
     1194            // Render sky, terrain and models
     1195            m->skyManager.RenderSky();
     1196            ogl_WarnIfError();
     1197            RenderPatches(context, &m_ViewCamera.GetFrustum());
     1198            ogl_WarnIfError();
     1199            RenderModels(context, &m_ViewCamera.GetFrustum());
     1200            ogl_WarnIfError();
     1201            RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1202            ogl_WarnIfError();
     1203           
     1204            glFrontFace(GL_CCW);
     1205           
     1206            glDisable(GL_SCISSOR_TEST);
     1207           
     1208            // Copy the image to a texture
     1209            pglActiveTextureARB(GL_TEXTURE0);
     1210            glEnable(GL_TEXTURE_2D);
     1211            glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
     1212            glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
     1213                                screenScissor.x1, screenScissor.y1,
     1214                                screenScissor.x1, screenScissor.y1,
     1215                                screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1216        }
     1217        // Reset old camera
     1218        m_ViewCamera = normalCamera;
     1219        m->SetOpenGLCamera(m_ViewCamera);
    11961220
    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);
     1221        // rebind post-processing frambuffer.
     1222        pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1223       
     1224        return screenScissor;
    12051225    }
    12061226
     1227    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1228    glClear(GL_COLOR_BUFFER_BIT);
     1229    glFrontFace(GL_CW);
     1230   
     1231    // Render sky, terrain and models
     1232    m->skyManager.RenderSky();
     1233    ogl_WarnIfError();
     1234    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1235    ogl_WarnIfError();
     1236    RenderModels(context, &m_ViewCamera.GetFrustum());
     1237    ogl_WarnIfError();
     1238    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1239    ogl_WarnIfError();
     1240   
     1241    glFrontFace(GL_CCW);
     1242    glDisable(GL_SCISSOR_TEST);
     1243
    12071244    // Reset old camera
    12081245    m_ViewCamera = normalCamera;
    12091246    m->SetOpenGLCamera(m_ViewCamera);
    12101247
     1248    // rebind post-processing frambuffer.
     1249    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1250
    12111251    return screenScissor;
    12121252}
    12131253
     
    12181258{
    12191259    PROFILE3_GPU("water refractions");
    12201260
     1261    // Save the post-processing framebuffer.
     1262    GLint fbo;
     1263    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
     1264   
    12211265    WaterManager& wm = m->waterManager;
    12221266
    12231267    // Remember old camera
     
    12411285    scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
    12421286    m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat;
    12431287
    1244     m->SetOpenGLCamera(m_ViewCamera);
    1245 
    12461288    CVector4D camPlane(0, -1, 0, wm.m_WaterHeight);
    12471289    SetObliqueFrustumClipping(camPlane);
    12481290
     
    12541296    screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
    12551297    screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
    12561298    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);
    12641299
    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);
     1300    glEnable(GL_SCISSOR_TEST);
     1301    glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1302   
     1303    // try binding the framebuffer
     1304    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_WaterBuffer);
     1305    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_RefractionTexture, 0);
     1306   
     1307    GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     1308    if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
     1309    {
     1310        wm.m_WaterBuffer = -1;
     1311        // revert to old method
     1312        if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
     1313        {
     1314            glEnable(GL_SCISSOR_TEST);
     1315            glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1316           
     1317            glClearColor(0.5f, 0.5f, 0.5f, 1.0f);       // a neutral gray to blend in with shores
     1318            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     1319           
     1320            // Render terrain and models
     1321            RenderPatches(context, &m_ViewCamera.GetFrustum());
     1322            ogl_WarnIfError();
     1323            RenderModels(context, &m_ViewCamera.GetFrustum());
     1324            ogl_WarnIfError();
     1325            RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1326            ogl_WarnIfError();
     1327           
     1328            glDisable(GL_SCISSOR_TEST);
     1329           
     1330            // Copy the image to a texture
     1331            pglActiveTextureARB(GL_TEXTURE0);
     1332            glEnable(GL_TEXTURE_2D);
     1333            glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
     1334            glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
     1335                                screenScissor.x1, screenScissor.y1,
     1336                                screenScissor.x1, screenScissor.y1,
     1337                                screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
     1338        }
     1339        // Reset old camera
     1340        m_ViewCamera = normalCamera;
     1341        m->SetOpenGLCamera(m_ViewCamera);
     1342       
     1343        // rebind post-processing frambuffer.
     1344        pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    12741345
    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);
     1346        return screenScissor;
    12831347    }
     1348   
     1349    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1350    glClear(GL_COLOR_BUFFER_BIT);
    12841351
     1352    // Render sky, terrain and models
     1353    m->skyManager.RenderSky();
     1354    ogl_WarnIfError();
     1355    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1356    ogl_WarnIfError();
     1357    RenderModels(context, &m_ViewCamera.GetFrustum());
     1358    ogl_WarnIfError();
     1359    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1360    ogl_WarnIfError();
     1361   
     1362    glDisable(GL_SCISSOR_TEST);
     1363   
    12851364    // Reset old camera
    12861365    m_ViewCamera = normalCamera;
    12871366    m->SetOpenGLCamera(m_ViewCamera);
    1288 
     1367   
     1368    // rebind post-processing frambuffer.
     1369    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1370   
    12891371    return screenScissor;
    12901372}
    12911373
    1292 
    12931374void CRenderer::RenderSilhouettes(const CShaderDefines& context)
    12941375{
    12951376    PROFILE3_GPU("silhouettes");
     
    15081589                dirty.x2 = reflectionScissor.x2;
    15091590                dirty.y2 = reflectionScissor.y2;
    15101591            }
    1511             if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2)
     1592            if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2 && m_WaterManager->m_WaterBuffer == (GLuint)-1)
    15121593            {
    15131594                glEnable(GL_SCISSOR_TEST);
    15141595                glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1);
  • Users/Lancelot/Desktop/0ad-svn/trunk/source/renderer/TerrainRenderer.cpp

     
    703703            glGenTextures(1, (GLuint*)&depthTex);
    704704            WaterMgr->m_depthTT = depthTex;
    705705            glBindTexture(GL_TEXTURE_2D, WaterMgr->m_depthTT);
    706            
    707 #if CONFIG2_GLES
    708             GLenum format = GL_DEPTH_COMPONENT;
    709 #else
    710             GLenum format = GL_DEPTH_COMPONENT32;
    711 #endif
    712            
    713             // TODO: use POT texture
    714             glTexImage2D(GL_TEXTURE_2D, 0, format, g_Renderer.GetWidth(), g_Renderer.GetHeight(),
    715                          0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
     706            glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, g_Renderer.GetWidth(), g_Renderer.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
     707            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     708            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     709            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     710            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     711        } else {
     712            glBindTexture(GL_TEXTURE_2D, WaterMgr->m_depthTT);
     713            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight(), 0);
    716714        }
    717         glBindTexture(GL_TEXTURE_2D, WaterMgr->m_depthTT);
    718 #if !CONFIG2_GLES
    719         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
    720 #endif
    721         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    722         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    723         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    724         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    725        
    726         glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight(), 0);
    727715       
    728716        glBindTexture(GL_TEXTURE_2D, 0);
    729717    }
     
    762750        {
    763751            glGenTextures(1, &renderedTexture);
    764752            WaterMgr->m_waveTT = renderedTexture;
    765            
    766753            glBindTexture(GL_TEXTURE_2D, WaterMgr->m_waveTT);
    767             // TODO: use POT texture
    768754            glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);
    769755
    770756        }
  • Users/Lancelot/Desktop/0ad-svn/trunk/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    pglDeleteFramebuffersEXT(1, &m_WaterBuffer);
    235242}
    236243
    237244///////////////////////////////////////////////////////////////////
  • Users/Lancelot/Desktop/0ad-svn/trunk/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;