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();
}
Beispiel #2
0
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(&notice->dwSavedStateBlock);

    pd3dDevice->BeginStateBlock();
    apply_render_state(pd3dDevice);
    pd3dDevice->SetTexture(0, notice->pTexture);
    pd3dDevice->EndStateBlock(&notice->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;
}