void GLRenderer::apply_render_state(const boost::shared_ptr<State> state) { switch( state->SpecType ) { case Resource::TEXTURE: case Resource::DATA_TEXTURE: { if( !state->RenderData ) { glBindTexture( GL_TEXTURE_2D, 0 ); break; } shared_ptr<GLTexture> gltex = boost::shared_static_cast<GLTexture, Resource>( state->RenderData ); _UseColor = false; glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glEnable( gltex->GLTarget ); glBindTexture( gltex->GLTarget, gltex->GLTex ); break; } case Resource::MULTI_TEXTURE: { shared_ptr<MultiTexture> mt = boost::shared_static_cast<MultiTexture, State>( state ); glActiveTextureARB( GL_TEXTURE0_ARB + mt->TextureUnit ); apply_render_state( mt->Texture ); glClientActiveTextureARB( GL_TEXTURE0_ARB + mt->TextureUnit ); glTexCoordPointer( 2, GL_FLOAT, 0, &mt->Coordinates[0] ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glClientActiveTextureARB( GL_TEXTURE0_ARB ); glActiveTextureARB( GL_TEXTURE0_ARB ); break; } case Resource::FLAT_COLOR: { shared_ptr<Color> c = boost::shared_static_cast<Color, State>( state ); _UseColor = true; _Color = c->RawColor; glDisable( GL_TEXTURE_2D ); glColor4ub( _Color.r, _Color.g, _Color.b, c->Alpha ); if( c->Alpha != 255 ) glEnable( GL_BLEND ); break; } case Resource::CULLING: { shared_ptr<Culling> c = boost::shared_static_cast<Culling, State>( state ); if( c->enabled ) { glEnable( GL_CULL_FACE ); glCullFace( c->front?GL_FRONT:GL_BACK ); } else { glDisable( GL_CULL_FACE ); } break; } case Resource::PROGRAM: { if( !state->RenderData ) { glUseProgramObjectARB( 0 ); //revert to fixed function break; } shared_ptr<GLProgram> glprog = boost::shared_static_cast<GLProgram, Resource>( state->RenderData ); glUseProgramObjectARB( glprog->GLProg ); break; } case Resource::RENDER_TARGET: { if( !state->RenderData ) { glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); glDrawBuffer( GL_BACK ); break; } shared_ptr<RenderTarget> targ = boost::shared_static_cast<RenderTarget, State>( state ); shared_ptr<GLTarget> gltarg = boost::shared_static_cast<GLTarget, Resource>( state->RenderData ); glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, gltarg->GLFBO ); glViewport( 0, 0, targ->Width, targ->Height ); GLenum ready = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ); if( ready != GL_FRAMEBUFFER_COMPLETE_EXT || !targ->Targets.size() ) { check_errors(); break; } glDrawBuffers( (GLenum)gltarg->Targets.size(), &gltarg->Targets[0] ); break; } case Resource::LIGHT: { shared_ptr<Light> l = boost::shared_static_cast<Light, State>( state ); if( l->Enabled ) glEnable( GL_LIGHTING ); else glDisable( GL_LIGHTING ); l->apply(); break; } case Resource::CAMERA: { shared_ptr<Camera> cam = boost::shared_static_cast<Camera, State>( state ); CameraPosition = cam->_Position; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( cam->_FOV, (GLfloat)cam->_Width/(GLfloat)cam->_Height, cam->_NearZ, cam->_FarZ ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( cam->_Position.x, cam->_Position.y, cam->_Position.z, cam->_Look.x, cam->_Look.y, cam->_Look.z, cam->_Up.x, cam->_Up.y, cam->_Up.z ); break; } case Resource::ORTHO: { shared_ptr<Ortho> ort = boost::shared_static_cast<Ortho, State>( state ); CameraPosition = Vector3f( ort->_Width / 2.0f, ort->_Height / 2.0f, (ort->_NearZ+ort->_FarZ)/2.0f ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( 0, ort->_Width, 0, ort->_Height, ort->_NearZ, ort->_FarZ ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); break; } } check_errors(); }
Filename_notice *prepare_filename_notice(LPDIRECT3DDEVICE8 pd3dDevice, char const *filename) { HRESULT result; Filename_notice *notice = NULL; HDC hDC = NULL; HFONT hFont = NULL; SIZE size; int width, height; LPDIRECT3DTEXTURE8 pTexture = NULL; LPDIRECT3DVERTEXBUFFER8 pVB = NULL; DWORD *pBitmapBits = NULL; BITMAPINFO bmi; HBITMAP hbmBitmap = NULL; D3DLOCKED_RECT d3dlr; BYTE *pDstRow; int x, y; hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); hFont = CreateFont( FONT_HEIGHT, // height 0, // width (0 = closest) 0, // escapement (0 = none) 0, // orientation (0 = none) FW_NORMAL, // bold FALSE, // italic FALSE, // underline FALSE, // strikeout DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, // TrueType (OUT_TT_PRECIS) doesn't help CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, FONT_NAME); if (hFont == NULL) { goto done; } // Set text properties SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); GetTextExtentPoint32(hDC, filename, strlen(filename), &size); width = size.cx; height = size.cy; // Create a new texture for the font result = pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &pTexture); if (FAILED(result)) { goto done; } // Prepare to create a bitmap ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; // negative means top-down bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0); SelectObject(hDC, hbmBitmap); ExtTextOut(hDC, 0, 0, ETO_OPAQUE, NULL, filename, strlen(filename), NULL); // Lock the surface and write the alpha values for the set pixels pTexture->LockRect(0, &d3dlr, 0, 0); pDstRow = (BYTE*)d3dlr.pBits; for (y = 0; y < height; y++) { WORD *pDst16 = (WORD *)pDstRow; for (x = 0; x < width; x++) { BYTE bAlpha = (BYTE)((pBitmapBits[width*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (WORD)((bAlpha << 12) | 0x0fff); } else { *pDst16++ = (WORD)(0x0000); } } pDstRow += d3dlr.Pitch; } // Done updating texture pTexture->UnlockRect(0); // Create vertices result = pd3dDevice->CreateVertexBuffer(4*sizeof(FONT2DVERTEX), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &pVB); if (FAILED(result)) { goto done; } notice = new Filename_notice; notice->width = width; notice->height = height; notice->pd3dDevice = pd3dDevice; notice->pTexture = pTexture; pTexture = NULL; notice->pVB = pVB; pVB = NULL; pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwSavedStateBlock); pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwDrawTextStateBlock); done: if (pVB != NULL) { pVB->Release(); } if (pTexture != NULL) { pTexture->Release(); } if (hbmBitmap != NULL) { DeleteObject(hbmBitmap); } if (hFont != NULL) { DeleteObject(hFont); } if (hDC != NULL) { DeleteDC(hDC); } return notice; }