RESULT GradientEffect::Init() { RETAILMSG(ZONE_SHADER, "GradientEffect::Init()"); RESULT rval = S_OK; if (s_GradientShadersLoaded) { return S_OK; } CHR(OpenGLESEffect::Init()); CHR(ShaderMan.CreateShader( "GradientEffect", s_GradientVertexShaderName, s_GradientFragmentShaderName, &s_hGradientShader )); // Save uniform handles. s_GradientShaderProgram = ShaderMan.GetShaderProgramID( s_hGradientShader ); VERIFYGL(glUseProgram(s_GradientShaderProgram)); VERIFYGL(s_uModelViewMatrix = glGetUniformLocation(s_GradientShaderProgram, "uMatModelView")); VERIFYGL(s_uProjectionMatrix = glGetUniformLocation(s_GradientShaderProgram, "uMatProjection")); VERIFYGL(s_uTexture = glGetUniformLocation(s_GradientShaderProgram, "uTexture")); VERIFYGL(s_uStartColor = glGetUniformLocation(s_GradientShaderProgram, "uStartColor")); VERIFYGL(s_uStartPoint = glGetUniformLocation(s_GradientShaderProgram, "uStartPoint")); VERIFYGL(s_uEndColor = glGetUniformLocation(s_GradientShaderProgram, "uEndColor")); VERIFYGL(s_uEndPoint = glGetUniformLocation(s_GradientShaderProgram, "uEndPoint")); VERIFYGL(s_uGlobalColor = glGetUniformLocation(s_GradientShaderProgram, "uGlobalColor")); VERIFYGL(s_uWidth = glGetUniformLocation(s_GradientShaderProgram, "uWidth")); VERIFYGL(s_uHeight = glGetUniformLocation(s_GradientShaderProgram, "uHeight")); // VERIFYGL(s_uTexCoordOffset = glGetUniformLocation(s_GradientShaderProgram, "uTexCoordOffset")); s_GradientShadersLoaded = true; Exit: return rval; }
RESULT GradientEffect::Draw( Vertex *pVertices, UINT32 numVertices, PRIMITIVE_TYPE primitiveType ) { DEBUGMSG(ZONE_SHADER, "GradientEffect[%d]::DrawTriangleStrip()", m_ID); RESULT rval = S_OK; Rectangle sourceRect; Rectangle textureRect; Util::GetBoundingRect ( pVertices, numVertices, &sourceRect ); Util::GetTextureMapping( pVertices, numVertices, &textureRect ); // Reinit if our source frame changes, i.e. the object // we're drawing is being scaled. Util::GetBoundingRect( m_pGradientVertices, m_numGradientVertices, &m_gradientRect ); if (!Util::CompareRectangles(sourceRect, m_gradientRect) || !m_pGradientVertices || m_frameChanged) { CHR(InitScratchSurfaces( sourceRect, textureRect )); m_frameChanged = false; } // Assign values to shader parameters. // TODO: move to BeginFrame()? VERIFYGL(glUseProgram(s_GradientShaderProgram)); VERIFYGL(glUniformMatrix4fv(s_uProjectionMatrix, 1, GL_FALSE, (GLfloat*)m_projectionMatrix.Pointer())); VERIFYGL(glUniformMatrix4fv(s_uModelViewMatrix, 1, GL_FALSE, (GLfloat*)m_modelViewMatrix.Pointer())); VERIFYGL(glUniform1i(s_uTexture, 0)); VERIFYGL(glUniform4f(s_uGlobalColor, m_globalColor.floats.r, m_globalColor.floats.g, m_globalColor.floats.b, m_globalColor.floats.a)); VERIFYGL(glUniform4f(s_uStartColor, m_startColor.floats.r, m_startColor.floats.g, m_startColor.floats.b, m_startColor.floats.a)); VERIFYGL(glUniform2f(s_uStartPoint, (m_startPoint.x * textureRect.width) + textureRect.x, (m_startPoint.y * textureRect.height) + textureRect.y)); VERIFYGL(glUniform4f(s_uEndColor, m_endColor.floats.r, m_endColor.floats.g, m_endColor.floats.b, m_endColor.floats.a)); VERIFYGL(glUniform2f(s_uEndPoint, (m_endPoint.x * textureRect.width) + textureRect.x, (m_endPoint.y * textureRect.height) + textureRect.y)); VERIFYGL(glUniform1f(s_uWidth, textureRect.width)); VERIFYGL(glUniform1f(s_uHeight, textureRect.height)); // Draw the mesh with gradient applies. VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &m_pGradientVertices->x)); VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_DIFFUSE, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), &m_pGradientVertices->color)); VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_TEXTURE_COORD0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &m_pGradientVertices->texCoord[0])); switch (primitiveType) { // NOTE: for this effect we ignore the passed-in vertices and draw a triangle list (GL_TRIANGLES) not a triangle strip (GL_TRIANGLE_STRIP). case PRIMITIVE_TYPE_TRIANGLE_STRIP: case PRIMITIVE_TYPE_TRIANGLE_LIST: VERIFYGL(glDrawArrays(GL_TRIANGLES, 0, m_numGradientVertices)); break; default: // TODO: might it ever be useful to apply Color to a field of point sprites? DEBUGCHK(0); } Exit: return rval; }
RESULT RippleEffect::Init() { RETAILMSG(ZONE_RENDER, "RippleEffect::Init()"); RESULT rval = S_OK; if (s_RippleShadersLoaded) { return S_OK; } CHR(OpenGLESEffect::Init()); CHR(ShaderMan.CreateShader( "RippleEffect", s_RippleVertexShaderName, s_RippleFragmentShaderName, &s_hRippleShader )); // Save uniform handles. s_RippleShaderProgram = ShaderMan.GetShaderProgramID( s_hRippleShader ); VERIFYGL(glUseProgram(s_RippleShaderProgram)); VERIFYGL(s_uModelViewMatrix = glGetUniformLocation(s_RippleShaderProgram, "uMatModelView")); VERIFYGL(s_uProjectionMatrix = glGetUniformLocation(s_RippleShaderProgram, "uMatProjection")); VERIFYGL(s_uTexture = glGetUniformLocation(s_RippleShaderProgram, "uTexture")); VERIFYGL(s_uGlobalColor = glGetUniformLocation(s_RippleShaderProgram, "uGlobalColor")); VERIFYGL(s_uAmplitude = glGetUniformLocation(s_RippleShaderProgram, "uAmplitude")); VERIFYGL(s_uTime = glGetUniformLocation(s_RippleShaderProgram, "uTime")); VERIFYGL(s_uRadius = glGetUniformLocation(s_RippleShaderProgram, "uRadius")); VERIFYGL(s_uOrigin = glGetUniformLocation(s_RippleShaderProgram, "uOrigin")); VERIFYGL(s_uHalfWaveLength = glGetUniformLocation(s_RippleShaderProgram, "uHalfWaveLength")); VERIFYGL(s_uNumWaves = glGetUniformLocation(s_RippleShaderProgram, "uNumWaves")); VERIFYGL(s_uColor = glGetUniformLocation(s_RippleShaderProgram, "uColor")); s_RippleShadersLoaded = true; Exit: return rval; }
HRESULT FrameBufferObject::Initialize( COpenGLDevice* pOGLDevice, unsigned int width, unsigned int height ) { RETAILMSG(ZONE_INFO, (TEXT("FrameBufferObject::Initialize( %d x %d )"), width, height )); HRESULT hr = S_OK; if (!pOGLDevice || !width || !height) { RETAILMSG(ZONE_ERROR, (TEXT("ERROR: FrameBufferObject::Initialize(): pOGLdevice 0x%x, width %d, height %d\n"), pOGLDevice, width, height)); CHR(E_INVALIDARG); } if (m_pOGLDevice != NULL) { m_pOGLDevice->Lock(); // We are being re-initialized (probably because the screen changed size) VERIFYGL( glDeleteRenderbuffers(1, &m_uiDepthRenderbuffer )); VERIFYGL( glDeleteFramebuffers (1, &m_uiFramebuffer )); VERIFYGL( glDeleteTextures (1, &m_uiTextureID )); m_pOGLDevice->Unlock(); m_pOGLDevice->Release(); RETAILMSG(ZONE_INFO, (TEXT("FrameBufferObject::Initialize(); discard old FBO because because of resize\n"))); } m_pOGLDevice = pOGLDevice; m_pOGLDevice->AddRef(); m_TexWidth = width; m_TexHeight = height; m_pOGLDevice->Lock(); #ifdef USE_DEPTH_BUFFER VERIFYGL(glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE, &m_MaxRenderbufferSize )); if ((m_MaxRenderbufferSize <= m_TexWidth) || (m_MaxRenderbufferSize <= m_TexHeight)) { // cannot use framebuffer objects as we need to create // a depth buffer as a renderbuffer object DEBUGCHK(0); return E_OUTOFMEMORY; } VERIFYGL(glGenRenderbuffers (1, &m_uiDepthRenderbuffer)); #endif // Create a texture and attach to the FBO as a render target VERIFYGL(glGenTextures (1, &m_uiTextureID)); VERIFYGL(glBindTexture (GL_TEXTURE_2D, m_uiTextureID)); VERIFYGL(glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); VERIFYGL(glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); VERIFYGL(glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); VERIFYGL(glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); if ( m_pOGLDevice->Use16BitTextures() ) { VERIFYGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_TexWidth, m_TexHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL)); } else if ( m_pOGLDevice->IsGlBGRAExtSupported() ) { VERIFYGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_TexWidth, m_TexHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL)); } else { VERIFYGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TexWidth, m_TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); } // Generate an off-screen Framebuffer and make it active VERIFYGL(glGenFramebuffers (1, &m_uiFramebuffer)); VERIFYGL(glBindFramebuffer(GL_FRAMEBUFFER, m_uiFramebuffer)); // Attach our texture to FBO VERIFYGL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uiTextureID, 0)); #ifdef USE_DEPTH_BUFFER // Create a depth buffer and attach to the FBO as a render target VERIFYGL(glBindRenderbuffer (GL_RENDERBUFFER, m_uiDepthRenderbuffer)); VERIFYGL(glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_TexWidth, m_TexHeight)); VERIFYGL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uiDepthRenderbuffer)); //VERIFYGL(glClear(GL_DEPTH_BUFFER_BIT)); #endif VERIFYGL(glClearColor(1.0f, 0.0f, 1.0f, 1.0f)); VERIFYGL(glClear(GL_COLOR_BUFFER_BIT)); GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { RETAILMSG(ZONE_ERROR, (TEXT("ERROR: FrameBufferObject::Initialize() failed. Off-screen rendering disabled.\n"))); DEBUGCHK(0); hr = E_FAIL; } Error: // Restore the default OS-provided framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); m_pOGLDevice->Unlock(); RETAILMSG(S_OK == hr && ZONE_INFO, (TEXT("FrameBufferObject::Initialize() OK\n"))); return hr; }
RESULT RippleEffect::Draw( Vertex *pVertices, UINT32 numVertices, PRIMITIVE_TYPE primitiveType ) { DEBUGMSG(ZONE_SHADER, "RippleEffect[%d]::DrawTriangleStrip()", m_ID); RESULT rval = S_OK; Rectangle sourceRect; Rectangle textureRect; Util::GetBoundingRect ( pVertices, numVertices, &sourceRect ); Util::GetTextureMapping( pVertices, numVertices, &textureRect ); // TODO: reinit if our source frame changes, i.e. the object // we're rippling is being scaled. if (!m_pRippledVertices || m_frameChanged) { CHR(InitScratchSurfaces( sourceRect, textureRect )); m_frameChanged = false; } // Assign values to shader parameters. // TODO: move to BeginPass()? VERIFYGL(glUseProgram(s_RippleShaderProgram)); VERIFYGL(glUniformMatrix4fv(s_uProjectionMatrix, 1, GL_FALSE, (GLfloat*)m_projectionMatrix.Pointer())); VERIFYGL(glUniformMatrix4fv(s_uModelViewMatrix, 1, GL_FALSE, (GLfloat*)m_modelViewMatrix.Pointer())); VERIFYGL(glUniform1i(s_uTexture, 0)); VERIFYGL(glUniform4f(s_uGlobalColor, m_globalColor.floats.r, m_globalColor.floats.g, m_globalColor.floats.b, m_globalColor.floats.a)); VERIFYGL(glUniform1f(s_uAmplitude, m_fAmplitude)); VERIFYGL(glUniform1f(s_uTime, m_fSpeed * GameTime.GetTimeDouble())); VERIFYGL(glUniform1f(s_uRadius, m_fRadius)); VERIFYGL(glUniform1f(s_uHalfWaveLength, m_fWaveLength/2.0f)); VERIFYGL(glUniform1f(s_uNumWaves, m_fNumWaves)); VERIFYGL(glUniform2f(s_uOrigin, m_origin.x, m_origin.y)); VERIFYGL(glUniform4f(s_uColor, m_color.floats.r, m_color.floats.g, m_color.floats.b, m_color.floats.a)); // Draw the texture mapped onto the rippling mesh. VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &m_pRippledVertices->x)); VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_DIFFUSE, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), &m_pRippledVertices->color)); VERIFYGL(glVertexAttribPointer(ATTRIBUTE_VERTEX_TEXTURE_COORD0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &m_pRippledVertices->texCoord[0])); switch (primitiveType) { // NOTE: for this effect we ignore the passed-in vertices and draw a triangle list (GL_TRIANGLES) not a triangle strip (GL_TRIANGLE_STRIP). case PRIMITIVE_TYPE_TRIANGLE_STRIP: case PRIMITIVE_TYPE_TRIANGLE_LIST: VERIFYGL(glDrawArrays(GL_TRIANGLES, 0, m_numRippledVertices)); break; default: // TODO: might it ever be useful to apply Ripple to a field of point sprites? DEBUGCHK(0); } Exit: return rval; }