#include "DeferredShader.h" #include "FrameBufferObject.h" #include "RenderState.h" using namespace std; namespace CHCDemoEngine { static void PrintGLerror(char *msg) { GLenum errCode; const GLubyte *errStr; if ((errCode = glGetError()) != GL_NO_ERROR) { errStr = gluErrorString(errCode); fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg); } } static GLenum mymrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT}; static CGprogram sCgDeferredProgram; static CGprogram sCgAntiAliasingProgram; static CGparameter sColorsTexParam; static CGparameter sPositionsTexParam; static CGparameter sNormalsTexParam; static CGparameter sColorsTexAntiAliasingParam; static CGparameter sNormalsTexAntiAliasingParam; DeferredShader::DeferredShader(int w, int h): mWidth(w), mHeight(h) { //mFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE); //mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false); } DeferredShader::~DeferredShader() { if (sCgDeferredProgram) cgDestroyProgram(sCgDeferredProgram); //DEL_PTR(mFbo); } void DeferredShader::Init(CGcontext context) { sCgDeferredProgram = cgCreateProgramFromFile(context, CG_SOURCE, "src/shaders/deferred.cg", RenderState::sCgFragmentProfile, "main", NULL); if (sCgDeferredProgram != NULL) { cgGLLoadProgram(sCgDeferredProgram); // we need size of texture for scaling sPositionsTexParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); sColorsTexParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); sNormalsTexParam = cgGetNamedParameter(sCgDeferredProgram, "normals"); } else cerr << "deferred program failed to load" << endl; sCgAntiAliasingProgram = cgCreateProgramFromFile(context, CG_SOURCE, "src/shaders/antialiasing.cg", RenderState::sCgFragmentProfile, "main", NULL); if (sCgAntiAliasingProgram != NULL) { cgGLLoadProgram(sCgAntiAliasingProgram); sColorsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "colors"); sNormalsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "normals"); } else cerr << "antialiasing program failed to load" << endl; PrintGLerror("init"); } void DeferredShader::Render(FrameBufferObject *fbo) { FirstPass(fbo); AntiAliasing(fbo); } void DeferredShader::FirstPass(FrameBufferObject *fbo) { GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture(); GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture(); GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture(); fbo->Bind(); glDrawBuffers(1, mymrt + 3); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, mWidth, mHeight); glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); const float offs = 0.5f; glOrtho(-offs, offs, -offs, offs, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cgGLEnableProfile(RenderState::sCgFragmentProfile); cgGLBindProgram(sCgDeferredProgram); cgGLSetTextureParameter(sColorsTexParam, colorsTex); cgGLEnableTextureParameter(sColorsTexParam); cgGLSetTextureParameter(sPositionsTexParam, positionsTex); cgGLEnableTextureParameter(sPositionsTexParam); cgGLSetTextureParameter(sNormalsTexParam, normalsTex); cgGLEnableTextureParameter(sNormalsTexParam); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); float offs2 = 0.5f; glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f); glTexCoord2f(1, 1); glVertex3f( offs2, offs2, -0.5f); glTexCoord2f(0, 1); glVertex3f(-offs2, offs2, -0.5f); glEnd(); cgGLDisableTextureParameter(sColorsTexParam); cgGLDisableTextureParameter(sPositionsTexParam); cgGLDisableTextureParameter(sNormalsTexParam); cgGLDisableProfile(RenderState::sCgFragmentProfile); glEnable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); FrameBufferObject::Release(); PrintGLerror("deferred shading"); } static void SetVertex(float x, float y, float x_offs, float y_offs) { glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom glVertex3f(x - 0.5f, y - 0.5f, -0.5f); } void DeferredShader::AntiAliasing(FrameBufferObject *fbo) { GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture(); GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture(); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, mWidth, mHeight); glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); const float offs = 0.5f; glOrtho(-offs, offs, -offs, offs, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cgGLEnableProfile(RenderState::sCgFragmentProfile); cgGLBindProgram(sCgAntiAliasingProgram); cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex); cgGLEnableTextureParameter(sColorsTexAntiAliasingParam); cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex); cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam); glColor3f(1.0f, 1.0f, 1.0f); float offs2 = 0.5f; glBegin(GL_QUADS); // the neighbouring texels float x_offs = 1.0f / mWidth; float y_offs = 1.0f / mHeight; SetVertex(0, 0, x_offs, y_offs); SetVertex(1, 0, x_offs, y_offs); SetVertex(1, 1, x_offs, y_offs); SetVertex(0, 1, x_offs, y_offs); glEnd(); cgGLDisableTextureParameter(sColorsTexAntiAliasingParam); cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam); cgGLDisableProfile(RenderState::sCgFragmentProfile); glEnable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); PrintGLerror("deferred shading"); } } // namespace