void DrawBitmap(UINT texID, float alpha, const Vect2 &startPos, const Vect2 &startSize) { DWORD curAlpha = DWORD(alpha*255.0f); Vect2 pos = Vect2(0.0f, 0.0f); Vect2 size = fullSize; Vect2 itemSize = Vect2((float)textures[texID]->Width(), (float)textures[texID]->Height()); double sourceAspect = double(itemSize.x)/double(itemSize.y); if(!CloseDouble(baseAspect, sourceAspect)) { if(baseAspect < sourceAspect) size.y = float(double(size.x) / sourceAspect); else size.x = float(double(size.y) * sourceAspect); pos = (fullSize-size)*0.5f; pos.x = (float)round(pos.x); pos.y = (float)round(pos.y); size.x = (float)round(size.x); size.y = (float)round(size.y); } pos /= fullSize; pos *= startSize; pos += startPos; Vect2 lr; lr = pos + (size/fullSize*startSize); DrawSprite(textures[texID], (curAlpha<<24) | 0xFFFFFF, pos.x, pos.y, lr.x, lr.y); }
void SceneItem::Update() { pos = Vect2(element->GetFloat(TEXT("x")), element->GetFloat(TEXT("y"))); size = Vect2(element->GetFloat(TEXT("cx"), 100.0f), element->GetFloat(TEXT("cy"), 100.0f)); //just reset the size if configuration changed, that way the user doesn't have to screw with the size //if(source) size = source->GetSize(); /*element->SetInt(TEXT("cx"), int(size.x)); element->SetInt(TEXT("cy"), int(size.y));*/ }
SceneItem* Scene::InsertImageSource(UINT pos, XElement *sourceElement) { if(GetSceneItem(sourceElement->GetName()) != NULL) { AppWarning(TEXT("Scene source '%s' already in scene. actually, no one should get this error. if you do send it to jim immidiately."), sourceElement->GetName()); return NULL; } if(pos > sceneItems.Num()) { AppWarning(TEXT("Scene::InsertImageSource: pos >= sceneItems.Num()")); pos = sceneItems.Num(); } CTSTR lpClass = sourceElement->GetString(TEXT("class")); ImageSource *source = NULL; if(!lpClass) AppWarning(TEXT("No class for source '%s' in scene '%s'"), sourceElement->GetName(), API->GetSceneElement()->GetName()); else { source = API->CreateImageSource(lpClass, sourceElement->GetElement(TEXT("data"))); if(!source) AppWarning(TEXT("Could not create image source '%s' in scene '%s'"), sourceElement->GetName(), API->GetSceneElement()->GetName()); } float x = sourceElement->GetFloat(TEXT("x")); float y = sourceElement->GetFloat(TEXT("y")); float cx = sourceElement->GetFloat(TEXT("cx"), 100); float cy = sourceElement->GetFloat(TEXT("cy"), 100); bool render = sourceElement->GetInt(TEXT("render"), 1) > 0; SceneItem *item = new SceneItem; item->element = sourceElement; item->parent = this; item->source = source; item->pos = Vect2(x, y); item->size = Vect2(cx, cy); item->crop.w = sourceElement->GetFloat(TEXT("crop.top")); item->crop.x = sourceElement->GetFloat(TEXT("crop.left")); item->crop.y = sourceElement->GetFloat(TEXT("crop.bottom")); item->crop.z = sourceElement->GetFloat(TEXT("crop.right")); item->SetRender(render); API->EnterSceneMutex(); if(bSceneStarted) source->BeginScene(); sceneItems.Insert(pos, item); API->LeaveSceneMutex(); if(!source) bMissingSources = true; return item; }
Vect2 TangentLine::Q(const Vect2& s, const double D, const int eps) { double sq_s = s.sqv(); double sq_D = sq(D); double delta = sq_s -sq_D; if (delta >= 0) { double alpha = sq_D/sq_s; double beta = D*sqrt_safe(delta)/sq_s; return Vect2(alpha*s.x+eps*beta*s.y, alpha*s.y-eps*beta*s.x); } return Vect2(); }
Vect2 Vect2::ScalAdd(double k, const Vect2& v) const { // Vect2 u = new Vect2(x,y); // u.scal(k); // u.add(v); // return u; return Vect2(k*x+v.x,k*y+v.y); }
Vect2 Vect2::AddScal(double k, const Vect2& v) const { //Vect2 u = new Vect2(x,y); // Vect2 vv = new Vect2(v.x,v.y); // vv.scal(k); // vv.add(this); // return vv; return Vect2(x+k*v.x,y+k*v.y); }
void Scene::RenderSelections() { for(UINT i=0; i<sceneItems.Num(); i++) { SceneItem *item = sceneItems[i]; if(item->bSelected) { Vect2 pos = API->MapFrameToWindowPos(item->GetPos())+1.0f; Vect2 size = API->MapFrameToWindowSize(item->GetSize())-2.0f; Vect2 selectBoxSize = Vect2(10.0f, 10.0f); DrawBox(pos, selectBoxSize); DrawBox((pos+size)-selectBoxSize, selectBoxSize); DrawBox(pos+Vect2(size.x-selectBoxSize.x, 0.0f), selectBoxSize); DrawBox(pos+Vect2(0.0f, size.y-selectBoxSize.y), selectBoxSize); DrawBox(pos, size); } } }
Vect2 Vect2::Hat() const { //Vect2 v = new Vect2(this); //v.hat(); //return v; double n = norm(); if ( n == 0.0) { // this is only checking the divide by zero case, so an exact comparison is correct. return ZERO(); } return Vect2(x/n, y/n); }
void Game::updateMap() { updateBullets(); updateMinions(); QuadTree q(Vect2(0, 0), Vect2(800, 600), _gameTime); q.createInfluenceTree(_ennemies); for (std::list<Player *>::iterator it = _playerList.begin(); it != _playerList.end(); ++it) { if ((*it)->isAlive()) { q.insert(*it); } } for (std::list<Entity *>::iterator it = _missiles.begin(); it != _missiles.end(); ++it) { if ((*it)->isAlive()) { q.insert(*it); } } }
SceneItem* Scene::InsertImageSource(UINT pos, XElement *sourceElement) { if(GetSceneItem(sourceElement->GetName()) != NULL) { AppWarning(TEXT("Scene source '%s' already in scene. actually, no one should get this error. if you do send it to jim immidiately."), sourceElement->GetName()); return NULL; } if(pos > sceneItems.Num()) { AppWarning(TEXT("Scene::InsertImageSource: pos >= sceneItems.Num()")); pos = sceneItems.Num(); } bool render = sourceElement->GetInt(TEXT("render"), 1) > 0; float x = sourceElement->GetFloat(TEXT("x")); float y = sourceElement->GetFloat(TEXT("y")); float cx = sourceElement->GetFloat(TEXT("cx"), 100); float cy = sourceElement->GetFloat(TEXT("cy"), 100); SceneItem *item = new SceneItem; item->element = sourceElement; item->parent = this; item->pos = Vect2(x, y); item->size = Vect2(cx, cy); item->crop.w = sourceElement->GetFloat(TEXT("crop.right")); item->crop.x = sourceElement->GetFloat(TEXT("crop.left")); item->crop.y = sourceElement->GetFloat(TEXT("crop.top")); item->crop.z = sourceElement->GetFloat(TEXT("crop.bottom")); item->SetRender(render); API->EnterSceneMutex(); sceneItems.Insert(pos, item); API->LeaveSceneMutex(); /*if(!source) bMissingSources = true;*/ return item; }
void Scene::RenderSelections(Shader *solidPixelShader) { for(UINT i=0; i<sceneItems.Num(); i++) { SceneItem *item = sceneItems[i]; if(item->bSelected) { Vect2 pos = API->MapFrameToWindowPos(item->GetPos())+1.0f; Vect2 scale = API->GetFrameToWindowScale(); pos.x += item->GetCrop().w * scale.x; pos.y += item->GetCrop().x * scale.y; Vect2 size = API->MapFrameToWindowSize(item->GetSize())-2.0f; size.x -= (item->GetCrop().y + item->GetCrop().w) * scale.x; size.y -= (item->GetCrop().x + item->GetCrop().z) * scale.y; Vect2 selectBoxSize = Vect2(10.0f, 10.0f); DrawBox(pos, selectBoxSize); DrawBox((pos+size)-selectBoxSize, selectBoxSize); DrawBox(pos+Vect2(size.x-selectBoxSize.x, 0.0f), selectBoxSize); DrawBox(pos+Vect2(0.0f, size.y-selectBoxSize.y), selectBoxSize); // Top if (CloseFloat(item->crop.x, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos, Vect2(size.x, 0.0f)); // Left if (CloseFloat(item->crop.w, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos, Vect2(0.0f, size.y)); // Right if (CloseFloat(item->crop.y, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos+Vect2(size.x, 0.0f), Vect2(0.0f, size.y)); // Bottom if (CloseFloat(item->crop.z, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos+Vect2(0.0f, size.y), Vect2(size.x, 0.0f)); } } }
void ProcessDateTime::Render(const Vect2 &pos, const Vect2 &size, Texture *FilterTexture, bool bScaleFull, bool bIsLiveC) { bScaleFull = false; if (texture) { //EnableBlending(FALSE); Vect2 sizeMultiplier = size / Resolution; sizeMultiplier.x += 0.1; Vect2 newSize = Vect2(float(textureSize.cx), float(textureSize.cy)) * sizeMultiplier; DWORD alpha = DWORD(double(globalOpacity)*2.55); DWORD outputColor = (alpha << 24) | 0xFFFFFF; DrawSprite(texture, outputColor, pos.x, pos.y, pos.x + newSize.x, pos.y + newSize.y); //EnableBlending(TRUE); } }
void TextComponent_BullShit::Render() { int charIndex = 0; TextObject* textObj; SpriteComponent * textSprite; while (text[charIndex] != '\0') { textObj = OpenGLRenderer::GetRenderer()->GetCharacterImage(text[charIndex]); textSprite = textObj->GetTextSprite(); textSprite->SetHidden(false); textSprite->SetPosition(GetPosition() + Vect2(charIndex * CHAR_WIDTH, 0)); textSprite->Render(); textSprite->SetHidden(true); ++charIndex; } }
GameScene::GameScene(Vect2 avatarPosition) : Scene(avatarPosition), m_startedCountdown(false), m_transitioning(false) { b2FixtureDef fixDef; fixDef.density = 1.0f; fixDef.friction = 0.3f; // make left wall b2BodyDef leftWallBody; leftWallBody.position.Set(-30.0f,0.0); b2PolygonShape wallShape; wallShape.SetAsBox(.5f, 26.0f); mp_physicsWorld->CreateBody(&leftWallBody)->CreateFixture(&wallShape, 0.0f); b2PolygonShape ceilingShape; ceilingShape.SetAsBox(50.0f, .5f); // make right Wall b2BodyDef rightWallBody; rightWallBody.position.Set(50.0f,0.0); mp_physicsWorld->CreateBody(&rightWallBody)->CreateFixture(&wallShape, 0.0f); b2BodyDef ceilingBody; ceilingBody.position.Set(0.0f, -20.0f); mp_physicsWorld->CreateBody(&ceilingBody)->CreateFixture(&ceilingShape, 0.0f); mp_windmillPuzzle = new WindmillPuzzle(mp_physicsWorld); PhysicsSprite* junk[6]; junk[0] = new PhysicsSprite("Junk:bigpipe", *mp_physicsWorld, Vect2(-8, 15)); junk[1] = new PhysicsSprite("Junk:junkrect", *mp_physicsWorld, Vect2(1, 15)); junk[2] = new PhysicsSprite("Junk:bigpipe", *mp_physicsWorld, Vect2(10, 15)); junk[3] = new PhysicsSprite("Junk:smallpipe", *mp_physicsWorld, Vect2(15, 15)); junk[4] = new PhysicsSprite("Junk:bigpipe", *mp_physicsWorld, Vect2(20, 15)); junk[5] = new PhysicsSprite("Junk:junkrect", *mp_physicsWorld, Vect2(25, 15)); //Sprite * blueprintSprite = new Sprite("test:cow"); //blueprintSprite->position.x = 16.0; //blueprintSprite->position.y = 12.0; for (int i = 0; i < 6; ++i) { mr_camera->AddChild(*junk[i]); } mr_camera->AddChild(*mp_windmillPuzzle); //camera->AddChild(*blueprintSprite); }
virtual Vect2 GetRenderFrameControlSize() const {return Vect2(float(App->renderFrameCtrlWidth), float(App->renderFrameCtrlHeight));}
virtual Vect2 GetRenderFrameOffset() const {return Vect2(float(App->renderFrameX), float(App->renderFrameY));}
virtual Vect2 GetRenderFrameSize() const {return Vect2(float(App->renderFrameWidth), float(App->renderFrameHeight));}
virtual Vect2 GetBaseSize() const {return Vect2(float(App->baseCX), float(App->baseCY));}
Vect2 SceneItem::GetCropBR() { return Vect2(-GetCrop().w, -GetCrop().z); }
Vect2 SceneItem::GetCropTR() { return Vect2(-GetCrop().w, GetCrop().y); }
// The following functions return the difference in x/y coordinates, not the absolute distances. Vect2 SceneItem::GetCropTL() { return Vect2(GetCrop().x, GetCrop().y); }
void Scene::RenderSelections(Shader *solidPixelShader) { for(UINT i=0; i<sceneItems.Num(); i++) { SceneItem *item = sceneItems[i]; if(item->bSelected) { Vect2 baseScale = item->GetSource() ? item->GetSource()->GetSize() : item->GetSize(); Vect2 cropFactor = baseScale / item->GetSize(); Vect4 crop = item->GetCrop(); Vect2 pos = API->MapFrameToWindowPos(item->GetPos()); Vect2 scale = API->GetFrameToWindowScale(); crop.x *= scale.x; crop.y *= scale.y; crop.z *= scale.y; crop.w *= scale.x; pos.x += crop.x; pos.y += crop.y; Vect2 size = API->MapFrameToWindowSize(item->GetSize()); size.x -= (crop.x + crop.w); size.y -= (crop.y + crop.z); Vect2 selectBoxSize = Vect2(10.0f, 10.0f); DrawBox(pos, selectBoxSize); DrawBox((pos+size)-selectBoxSize, selectBoxSize); DrawBox(pos+Vect2(size.x-selectBoxSize.x, 0.0f), selectBoxSize); DrawBox(pos+Vect2(0.0f, size.y-selectBoxSize.y), selectBoxSize); // Top if (CloseFloat(crop.y, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos, Vect2(size.x, 0.0f)); // Left if (CloseFloat(crop.x, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos, Vect2(0.0f, size.y)); // Right if (CloseFloat(crop.w, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos+Vect2(size.x, 0.0f), Vect2(0.0f, size.y)); // Bottom if (CloseFloat(crop.z, 0.0f)) solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); else solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0x00FF00); DrawBox(pos+Vect2(0.0f, size.y), Vect2(size.x, 0.0f)); //#define DRAW_UNCROPPED_SELECTION_BOX #ifdef DRAW_UNCROPPED_SELECTION_BOX Vect2 realPos = API->MapFrameToWindowPos(item->GetPos()); Vect2 realSize = item->GetSize() * scale; solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFFFFFF); solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFFFFFF); DrawBox(realPos, Vect2(0.0f, realSize.y)); DrawBox(realPos, Vect2(realSize.x, 0.0f)); DrawBox(realPos+Vect2(realSize.x, 0.0f), Vect2(0.0f, realSize.y)); DrawBox(realPos+Vect2(0.0f, realSize.y), Vect2(realSize.x, 0.0f)); #endif } } }
Vect2 operator+(Vect2 const & rhs) { return Vect2(x + rhs.x, y + rhs.y); }
//todo: this function is an abomination, this is just disgusting. fix it. //...seriously, this is really, really horrible. I mean this is amazingly bad. void OBS::MainCaptureLoop() { int curRenderTarget = 0, curYUVTexture = 0, curCopyTexture = 0; int copyWait = NUM_RENDER_BUFFERS-1; bSentHeaders = false; bFirstAudioPacket = true; bool bLogLongFramesProfile = GlobalConfig->GetInt(TEXT("General"), TEXT("LogLongFramesProfile"), LOGLONGFRAMESDEFAULT) != 0; float logLongFramesProfilePercentage = GlobalConfig->GetFloat(TEXT("General"), TEXT("LogLongFramesProfilePercentage"), 10.f); Vect2 baseSize = Vect2(float(baseCX), float(baseCY)); Vect2 outputSize = Vect2(float(outputCX), float(outputCY)); Vect2 scaleSize = Vect2(float(scaleCX), float(scaleCY)); HANDLE hMatrix = yuvScalePixelShader->GetParameterByName(TEXT("yuvMat")); HANDLE hScaleVal = yuvScalePixelShader->GetParameterByName(TEXT("baseDimensionI")); //---------------------------------------- // x264 input buffers int curOutBuffer = 0; bool bUsingQSV = videoEncoder->isQSV();//GlobalConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0; bUsing444 = false; EncoderPicture lastPic; EncoderPicture outPics[NUM_OUT_BUFFERS]; for(int i=0; i<NUM_OUT_BUFFERS; i++) { if(bUsingQSV) { outPics[i].mfxOut = new mfxFrameSurface1; memset(outPics[i].mfxOut, 0, sizeof(mfxFrameSurface1)); mfxFrameData& data = outPics[i].mfxOut->Data; videoEncoder->RequestBuffers(&data); } else { outPics[i].picOut = new x264_picture_t; x264_picture_init(outPics[i].picOut); } } if(bUsing444) { for(int i=0; i<NUM_OUT_BUFFERS; i++) { outPics[i].picOut->img.i_csp = X264_CSP_BGRA; //although the x264 input says BGR, x264 actually will expect packed UYV outPics[i].picOut->img.i_plane = 1; } } else { if(!bUsingQSV) for(int i=0; i<NUM_OUT_BUFFERS; i++) x264_picture_alloc(outPics[i].picOut, X264_CSP_NV12, outputCX, outputCY); } int bCongestionControl = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("CongestionControl"), 0); bool bDynamicBitrateSupported = App->GetVideoEncoder()->DynamicBitrateSupported(); int defaultBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int currentBitRate = defaultBitRate; QWORD lastAdjustmentTime = 0; UINT adjustmentStreamId = 0; //std::unique_ptr<ProfilerNode> encodeThreadProfiler; //---------------------------------------- // time/timestamp stuff bool bWasLaggedFrame = false; totalStreamTime = 0; lastAudioTimestamp = 0; //---------------------------------------- // start audio capture streams desktopAudio->StartCapture(); if(micAudio) micAudio->StartCapture(); //---------------------------------------- // status bar/statistics stuff DWORD fpsCounter = 0; int numLongFrames = 0; int numTotalFrames = 0; bytesPerSec = 0; captureFPS = 0; curFramesDropped = 0; curStrain = 0.0; PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0); QWORD lastBytesSent[3] = {0, 0, 0}; DWORD lastFramesDropped = 0; double bpsTime = 0.0; double lastStrain = 0.0f; DWORD numSecondsWaited = 0; //---------------------------------------- // 444->420 thread data int numThreads = MAX(OSGetTotalCores()-2, 1); HANDLE *h420Threads = (HANDLE*)Allocate(sizeof(HANDLE)*numThreads); Convert444Data *convertInfo = (Convert444Data*)Allocate(sizeof(Convert444Data)*numThreads); zero(h420Threads, sizeof(HANDLE)*numThreads); zero(convertInfo, sizeof(Convert444Data)*numThreads); for(int i=0; i<numThreads; i++) { convertInfo[i].width = outputCX; convertInfo[i].height = outputCY; convertInfo[i].hSignalConvert = CreateEvent(NULL, FALSE, FALSE, NULL); convertInfo[i].hSignalComplete = CreateEvent(NULL, FALSE, FALSE, NULL); convertInfo[i].bNV12 = bUsingQSV; convertInfo[i].numThreads = numThreads; if(i == 0) convertInfo[i].startY = 0; else convertInfo[i].startY = convertInfo[i-1].endY; if(i == (numThreads-1)) convertInfo[i].endY = outputCY; else convertInfo[i].endY = ((outputCY/numThreads)*(i+1)) & 0xFFFFFFFE; } bool bEncode; bool bFirstFrame = true; bool bFirstImage = true; bool bFirstEncode = true; bool bUseThreaded420 = bUseMultithreadedOptimizations && (OSGetTotalCores() > 1) && !bUsing444; List<HANDLE> completeEvents; if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { h420Threads[i] = OSCreateThread((XTHREAD)Convert444Thread, convertInfo+i); completeEvents << convertInfo[i].hSignalComplete; } } //---------------------------------------- QWORD streamTimeStart = GetQPCTimeNS(); QWORD lastStreamTime = 0; QWORD firstFrameTimeMS = streamTimeStart/1000000; QWORD frameLengthNS = 1000000000/fps; while(WaitForSingleObject(hVideoEvent, INFINITE) == WAIT_OBJECT_0) { if (bShutdownVideoThread) break; QWORD renderStartTime = GetQPCTimeNS(); totalStreamTime = DWORD((renderStartTime-streamTimeStart)/1000000); bool bRenderView = !IsIconic(hwndMain) && bRenderViewEnabled; QWORD renderStartTimeMS = renderStartTime/1000000; QWORD curStreamTime = latestVideoTimeNS; if (!lastStreamTime) lastStreamTime = curStreamTime-frameLengthNS; QWORD frameDelta = curStreamTime-lastStreamTime; //if (!lastStreamTime) // lastStreamTime = renderStartTime-frameLengthNS; //QWORD frameDelta = renderStartTime-lastStreamTime; double fSeconds = double(frameDelta)*0.000000001; //lastStreamTime = renderStartTime; bool bUpdateBPS = false; profileIn("video thread frame"); //Log(TEXT("Stream Time: %llu"), curStreamTime); //Log(TEXT("frameDelta: %lf"), fSeconds); //------------------------------------ if(bRequestKeyframe && keyframeWait > 0) { keyframeWait -= int(frameDelta); if(keyframeWait <= 0) { GetVideoEncoder()->RequestKeyframe(); bRequestKeyframe = false; } } if(!pushToTalkDown && pushToTalkTimeLeft > 0) { pushToTalkTimeLeft -= int(frameDelta); OSDebugOut(TEXT("time left: %d\r\n"), pushToTalkTimeLeft); if(pushToTalkTimeLeft <= 0) { pushToTalkTimeLeft = 0; bPushToTalkOn = false; } } //------------------------------------ OSEnterMutex(hSceneMutex); if (bPleaseEnableProjector) ActuallyEnableProjector(); else if(bPleaseDisableProjector) DisableProjector(); if(bResizeRenderView) { GS->ResizeView(); bResizeRenderView = false; } //------------------------------------ if(scene) { profileIn("scene->Preprocess"); scene->Preprocess(); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->Preprocess(); profileOut; scene->Tick(float(fSeconds)); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->Tick(float(fSeconds)); } //------------------------------------ QWORD curBytesSent = 0; if (network) { curBytesSent = network->GetCurrentSentBytes(); curFramesDropped = network->NumDroppedFrames(); } else if (numSecondsWaited) { //reset stats if the network disappears bytesPerSec = 0; bpsTime = 0; numSecondsWaited = 0; curBytesSent = 0; zero(lastBytesSent, sizeof(lastBytesSent)); } bpsTime += fSeconds; if(bpsTime > 1.0f) { if(numSecondsWaited < 3) ++numSecondsWaited; //bytesPerSec = DWORD(curBytesSent - lastBytesSent); bytesPerSec = DWORD(curBytesSent - lastBytesSent[0]) / numSecondsWaited; if(bpsTime > 2.0) bpsTime = 0.0f; else bpsTime -= 1.0; if(numSecondsWaited == 3) { lastBytesSent[0] = lastBytesSent[1]; lastBytesSent[1] = lastBytesSent[2]; lastBytesSent[2] = curBytesSent; } else lastBytesSent[numSecondsWaited] = curBytesSent; captureFPS = fpsCounter; fpsCounter = 0; bUpdateBPS = true; } fpsCounter++; if(network) curStrain = network->GetPacketStrain(); EnableBlending(TRUE); BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA); //------------------------------------ // render the mini render texture LoadVertexShader(mainVertexShader); LoadPixelShader(mainPixelShader); SetRenderTarget(mainRenderTextures[curRenderTarget]); Ortho(0.0f, baseSize.x, baseSize.y, 0.0f, -100.0f, 100.0f); SetViewport(0, 0, baseSize.x, baseSize.y); if(scene) scene->Render(); //------------------------------------ if(bTransitioning) { if(!transitionTexture) { transitionTexture = CreateTexture(baseCX, baseCY, GS_BGRA, NULL, FALSE, TRUE); if(transitionTexture) { D3D10Texture *d3dTransitionTex = static_cast<D3D10Texture*>(transitionTexture); D3D10Texture *d3dSceneTex = static_cast<D3D10Texture*>(mainRenderTextures[lastRenderTarget]); GetD3D()->CopyResource(d3dTransitionTex->texture, d3dSceneTex->texture); } else bTransitioning = false; } else if(transitionAlpha >= 1.0f) { delete transitionTexture; transitionTexture = NULL; bTransitioning = false; } } if(bTransitioning) { EnableBlending(TRUE); transitionAlpha += float(fSeconds)*5.0f; if(transitionAlpha > 1.0f) transitionAlpha = 1.0f; } else EnableBlending(FALSE); //------------------------------------ // render the mini view thingy if (bProjector) { SetRenderTarget(projectorTexture); Vect2 renderFrameSize, renderFrameOffset; Vect2 projectorSize = Vect2(float(projectorWidth), float(projectorHeight)); float projectorAspect = (projectorSize.x / projectorSize.y); float baseAspect = (baseSize.x / baseSize.y); if (projectorAspect < baseAspect) { float fProjectorWidth = float(projectorWidth); renderFrameSize = Vect2(fProjectorWidth, fProjectorWidth / baseAspect); renderFrameOffset = Vect2(0.0f, (projectorSize.y-renderFrameSize.y) * 0.5f); } else { float fProjectorHeight = float(projectorHeight); renderFrameSize = Vect2(fProjectorHeight * baseAspect, fProjectorHeight); renderFrameOffset = Vect2((projectorSize.x-renderFrameSize.x) * 0.5f, 0.0f); } DrawPreview(renderFrameSize, renderFrameOffset, projectorSize, curRenderTarget, Preview_Projector); SetRenderTarget(NULL); } if(bRenderView) { // Cache const Vect2 renderFrameSize = GetRenderFrameSize(); const Vect2 renderFrameOffset = GetRenderFrameOffset(); const Vect2 renderFrameCtrlSize = GetRenderFrameControlSize(); SetRenderTarget(NULL); DrawPreview(renderFrameSize, renderFrameOffset, renderFrameCtrlSize, curRenderTarget, bFullscreenMode ? Preview_Fullscreen : Preview_Standard); //draw selections if in edit mode if(bEditMode && !bSizeChanging) { if(scene) { LoadVertexShader(solidVertexShader); LoadPixelShader(solidPixelShader); solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000); scene->RenderSelections(solidPixelShader); } } } else if(bForceRenderViewErase) { InvalidateRect(hwndRenderFrame, NULL, TRUE); UpdateWindow(hwndRenderFrame); bForceRenderViewErase = false; } //------------------------------------ // actual stream output LoadVertexShader(mainVertexShader); LoadPixelShader(yuvScalePixelShader); Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget]; SetRenderTarget(yuvRenderTexture); switch(colorDesc.matrix) { case ColorMatrix_GBR: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[0] : (float*)yuvMat[0]); break; case ColorMatrix_YCgCo: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[1] : (float*)yuvMat[1]); break; case ColorMatrix_BT2020NCL: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[2] : (float*)yuvMat[2]); break; case ColorMatrix_BT709: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[3] : (float*)yuvMat[3]); break; case ColorMatrix_SMPTE240M: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[4] : (float*)yuvMat[4]); break; default: yuvScalePixelShader->SetMatrix(hMatrix, colorDesc.fullRange ? (float*)yuvFullMat[5] : (float*)yuvMat[5]); } if(downscale < 2.01) yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/baseSize); else if(downscale < 3.01) yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/(outputSize*3.0f)); Ortho(0.0f, outputSize.x, outputSize.y, 0.0f, -100.0f, 100.0f); SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y); //why am I using scaleSize instead of outputSize for the texture? //because outputSize can be trimmed by up to three pixels due to 128-bit alignment. //using the scale function with outputSize can cause slightly inaccurate scaled images if(bTransitioning) { BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO); DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, 1.0f, 1.0f); BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha); } DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f); //------------------------------------ if (bProjector && !copyWait) projectorSwap->Present(0, 0); if(bRenderView && !copyWait) static_cast<D3D10System*>(GS)->swap->Present(0, 0); OSLeaveMutex(hSceneMutex); //------------------------------------ // present/upload profileIn("GPU download and conversion"); bEncode = true; if(copyWait) { copyWait--; bEncode = false; } else { //audio sometimes takes a bit to start -- do not start processing frames until audio has started capturing if(!bRecievedFirstAudioFrame) { static bool bWarnedAboutNoAudio = false; if (renderStartTimeMS-firstFrameTimeMS > 10000 && !bWarnedAboutNoAudio) { bWarnedAboutNoAudio = true; //AddStreamInfo (TEXT ("WARNING: OBS is not receiving audio frames. Please check your audio devices."), StreamInfoPriority_Critical); } bEncode = false; } else if(bFirstFrame) { firstFrameTimestamp = lastStreamTime/1000000; bFirstFrame = false; } if(!bEncode) { if(curYUVTexture == (NUM_RENDER_BUFFERS-1)) curYUVTexture = 0; else curYUVTexture++; } } lastStreamTime = curStreamTime; if(bEncode) { UINT prevCopyTexture = (curCopyTexture == 0) ? NUM_RENDER_BUFFERS-1 : curCopyTexture-1; ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture]; profileIn("CopyResource"); if(!bFirstEncode && bUseThreaded420) { WaitForMultipleObjects(completeEvents.Num(), completeEvents.Array(), TRUE, INFINITE); copyTexture->Unmap(0); } D3D10Texture *d3dYUV = static_cast<D3D10Texture*>(yuvRenderTextures[curYUVTexture]); GetD3D()->CopyResource(copyTexture, d3dYUV->texture); profileOut; ID3D10Texture2D *prevTexture = copyTextures[prevCopyTexture]; if(bFirstImage) //ignore the first frame bFirstImage = false; else { HRESULT result; D3D10_MAPPED_TEXTURE2D map; if(SUCCEEDED(result = prevTexture->Map(0, D3D10_MAP_READ, 0, &map))) { int prevOutBuffer = (curOutBuffer == 0) ? NUM_OUT_BUFFERS-1 : curOutBuffer-1; int nextOutBuffer = (curOutBuffer == NUM_OUT_BUFFERS-1) ? 0 : curOutBuffer+1; EncoderPicture &prevPicOut = outPics[prevOutBuffer]; EncoderPicture &picOut = outPics[curOutBuffer]; EncoderPicture &nextPicOut = outPics[nextOutBuffer]; if(!bUsing444) { profileIn("conversion to 4:2:0"); if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { convertInfo[i].input = (LPBYTE)map.pData; convertInfo[i].inPitch = map.RowPitch; if(bUsingQSV) { mfxFrameData& data = nextPicOut.mfxOut->Data; videoEncoder->RequestBuffers(&data); convertInfo[i].outPitch = data.Pitch; convertInfo[i].output[0] = data.Y; convertInfo[i].output[1] = data.UV; } else { convertInfo[i].output[0] = nextPicOut.picOut->img.plane[0]; convertInfo[i].output[1] = nextPicOut.picOut->img.plane[1]; convertInfo[i].output[2] = nextPicOut.picOut->img.plane[2]; } SetEvent(convertInfo[i].hSignalConvert); } if(bFirstEncode) bFirstEncode = bEncode = false; } else { if(bUsingQSV) { mfxFrameData& data = picOut.mfxOut->Data; videoEncoder->RequestBuffers(&data); LPBYTE output[] = {data.Y, data.UV}; Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, data.Pitch, outputCY, 0, outputCY, output); } else Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, outputCX, outputCY, 0, outputCY, picOut.picOut->img.plane); prevTexture->Unmap(0); } profileOut; } if(bEncode) { //encodeThreadProfiler.reset(::new ProfilerNode(TEXT("EncodeThread"), true)); //encodeThreadProfiler->MonitorThread(hEncodeThread); curFramePic = &picOut; } curOutBuffer = nextOutBuffer; } else { //We have to crash, or we end up deadlocking the thread when the convert threads are never signalled if (result == DXGI_ERROR_DEVICE_REMOVED) { String message; HRESULT reason = GetD3D()->GetDeviceRemovedReason(); switch (reason) { case DXGI_ERROR_DEVICE_RESET: case DXGI_ERROR_DEVICE_HUNG: message = TEXT("Your video card or driver froze and was reset. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_DEVICE_REMOVED: message = TEXT("Your video card disappeared from the system. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_DRIVER_INTERNAL_ERROR: message = TEXT("Your video driver reported an internal error. Please check for possible hardware / driver issues."); break; case DXGI_ERROR_INVALID_CALL: message = TEXT("Your video driver reported an invalid call. Please check for possible driver issues."); break; default: message = TEXT("DXGI_ERROR_DEVICE_REMOVED"); break; } message << TEXT(" This error can also occur if you have enabled opencl in x264 custom settings."); CrashError (TEXT("Texture->Map failed: 0x%08x 0x%08x\r\n\r\n%s"), result, reason, message.Array()); } else CrashError (TEXT("Texture->Map failed: 0x%08x"), result); } } if(curCopyTexture == (NUM_RENDER_BUFFERS-1)) curCopyTexture = 0; else curCopyTexture++; if(curYUVTexture == (NUM_RENDER_BUFFERS-1)) curYUVTexture = 0; else curYUVTexture++; if (bCongestionControl && bDynamicBitrateSupported && !bTestStream && totalStreamTime > 15000) { if (curStrain > 25) { if (renderStartTimeMS - lastAdjustmentTime > 1500) { if (currentBitRate > 100) { currentBitRate = (int)(currentBitRate * (1.0 - (curStrain / 400))); App->GetVideoEncoder()->SetBitRate(currentBitRate, -1); if (!adjustmentStreamId) adjustmentStreamId = App->AddStreamInfo (FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low); else App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array()); bUpdateBPS = true; } lastAdjustmentTime = renderStartTimeMS; } } else if (currentBitRate < defaultBitRate && curStrain < 5 && lastStrain < 5) { if (renderStartTimeMS - lastAdjustmentTime > 5000) { if (currentBitRate < defaultBitRate) { currentBitRate += (int)(defaultBitRate * 0.05); if (currentBitRate > defaultBitRate) currentBitRate = defaultBitRate; } App->GetVideoEncoder()->SetBitRate(currentBitRate, -1); /*if (!adjustmentStreamId) App->AddStreamInfo (FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low); else App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array());*/ App->RemoveStreamInfo(adjustmentStreamId); adjustmentStreamId = 0; bUpdateBPS = true; lastAdjustmentTime = renderStartTimeMS; } } } } lastRenderTarget = curRenderTarget; if(curRenderTarget == (NUM_RENDER_BUFFERS-1)) curRenderTarget = 0; else curRenderTarget++; if(bUpdateBPS || !CloseDouble(curStrain, lastStrain) || curFramesDropped != lastFramesDropped) { PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0); lastStrain = curStrain; lastFramesDropped = curFramesDropped; } //------------------------------------ // we're about to sleep so we should flush the d3d command queue profileIn("flush"); GetD3D()->Flush(); profileOut; profileOut; profileOut; //frame //------------------------------------ // frame sync //QWORD renderStopTime = GetQPCTimeNS(); if(bWasLaggedFrame = (frameDelta > frameLengthNS)) { numLongFrames++; if(bLogLongFramesProfile && (numLongFrames/float(max(1, numTotalFrames)) * 100.) > logLongFramesProfilePercentage) DumpLastProfileData(); } //OSDebugOut(TEXT("Frame adjust time: %d, "), frameTimeAdjust-totalTime); numTotalFrames++; } DisableProjector(); //encodeThreadProfiler.reset(); if(!bUsing444) { if(bUseThreaded420) { for(int i=0; i<numThreads; i++) { if(h420Threads[i]) { convertInfo[i].bKillThread = true; SetEvent(convertInfo[i].hSignalConvert); OSTerminateThread(h420Threads[i], 10000); h420Threads[i] = NULL; } if(convertInfo[i].hSignalConvert) { CloseHandle(convertInfo[i].hSignalConvert); convertInfo[i].hSignalConvert = NULL; } if(convertInfo[i].hSignalComplete) { CloseHandle(convertInfo[i].hSignalComplete); convertInfo[i].hSignalComplete = NULL; } } if(!bFirstEncode) { ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture]; copyTexture->Unmap(0); } } if(bUsingQSV) for(int i = 0; i < NUM_OUT_BUFFERS; i++) delete outPics[i].mfxOut; else for(int i=0; i<NUM_OUT_BUFFERS; i++) { x264_picture_clean(outPics[i].picOut); delete outPics[i].picOut; } } Free(h420Threads); Free(convertInfo); Log(TEXT("Total frames rendered: %d, number of late frames: %d (%0.2f%%) (it's okay for some frames to be late)"), numTotalFrames, numLongFrames, (numTotalFrames > 0) ? (double(numLongFrames)/double(numTotalFrames))*100.0 : 0.0f); }
virtual Vect2 GetOutputSize() const {return Vect2(float(App->outputCX), float(App->outputCY));}
Bullet::Bullet(Vect2 const & position, Vect2 const & direction) : Entity(position, BULLET, Vect2(8, 8)), _direction(direction) {}
void D3D10System::DrawSpriteEx(Texture *texture, DWORD color, float x, float y, float x2, float y2, float u, float v, float u2, float v2) { if(!curPixelShader) return; if(!texture) { AppWarning(TEXT("Trying to draw a sprite with a NULL texture")); return; } HANDLE hColor = curPixelShader->GetParameterByName(TEXT("outputColor")); if(hColor) curPixelShader->SetColor(hColor, color); //------------------------------ // crop positional values Vect2 totalSize = Vect2(x2-x, y2-y); Vect2 invMult = Vect2(totalSize.x < 0.0f ? -1.0f : 1.0f, totalSize.y < 0.0f ? -1.0f : 1.0f); totalSize.Abs(); x += curCropping[0] * invMult.x; y += curCropping[1] * invMult.y; x2 -= curCropping[2] * invMult.x; y2 -= curCropping[3] * invMult.y; //------------------------------ // crop texture coordinate values float cropMult[4]; cropMult[0] = curCropping[0]/totalSize.x; cropMult[1] = curCropping[1]/totalSize.y; cropMult[2] = curCropping[2]/totalSize.x; cropMult[3] = curCropping[3]/totalSize.y; Vect2 totalUVSize = Vect2(u2-u, v2-v); u += cropMult[0] * totalUVSize.x; v += cropMult[1] * totalUVSize.y; u2 -= cropMult[2] * totalUVSize.x; v2 -= cropMult[3] * totalUVSize.y; //------------------------------ // draw VBData *data = spriteVertexBuffer->GetData(); data->VertList[0].Set(x, y, 0.0f); data->VertList[1].Set(x, y2, 0.0f); data->VertList[2].Set(x2, y, 0.0f); data->VertList[3].Set(x2, y2, 0.0f); List<UVCoord> &coords = data->UVList[0]; coords[0].Set(u, v); coords[1].Set(u, v2); coords[2].Set(u2, v); coords[3].Set(u2, v2); spriteVertexBuffer->FlushBuffers(); LoadVertexBuffer(spriteVertexBuffer); LoadTexture(texture); Draw(GS_TRIANGLESTRIP); }
MenuObject* MenuObject::CreateMenuLetter(kLetter letter, b2World& world, const Vect2 &pos) { std::string name; // setting up bodyDef only // must call createBody to set the parent classes members b2FixtureDef fd; fd.restitution = .002; fd.density = 1.0; // very light fd.friction = 7.0; fd.isMagnetic = true; //Sprite* sprite = new Sprite("test:cow"); //this->AddChild(*sprite); b2CircleShape circleShape; //Figure out name switch (letter) { case kLetterG: name = "menu:G"; break; case kLetterR: name = "menu:R"; break; case kLetterO: name = "menu:O"; break; case kLetterU: name = "menu:U"; break; case kLetterN: name = "menu:N"; break; case kLetterD: name = "menu:D"; break; case kLetterP: name = "menu:P"; break; case kPlay: name = "menu:play"; break; } MenuObject * obj = new MenuObject(name); obj->scale = Vect2(.6f,.6f); obj->m_soundEffect = "SFX03"; b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(pos.x, pos.y); obj->mp_physicsBody = world.CreateBody(&bodyDef); float hx = obj->size.x * .6f * .5f; float hy = obj->size.y * .6f * .5f; b2MassData massData; massData.center = b2Vec2(0,0); massData.mass = 5; massData.I = 1.0; switch (letter) { case kPlay: { b2PolygonShape polyShape; polyShape.SetAsBox(hx, hy); fd.shape = &polyShape; obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&fd); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_fixture->SetIsMagnetic(true); } break; case kLetterG: { b2PolygonShape polyShape; polyShape.SetAsBox( hx * .45f, hy * .75f, b2Vec2(hx * .5f, (hy * .75f * .25f)), 0); fd.shape = &polyShape; obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&fd); obj->mp_fixture->SetPhysicsSprite(*obj); b2CircleShape circleShape; circleShape.m_radius = hy; obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterU: { b2CircleShape circleShape; circleShape.m_radius = hx; circleShape.m_p = b2Vec2(0,hy - hx); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, 0.05f); obj->mp_fixture->SetPhysicsSprite(*obj); //obj->mp_fixture->SetIsMagnetic(true); b2PolygonShape polyShape; polyShape.SetAsBox( hx, hy*.5, b2Vec2(0, -hy * .5f), 0); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&polyShape, 0.05f); //obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterD: { b2CircleShape circleShape; circleShape.m_radius = hx; obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); b2PolygonShape polyShape; polyShape.SetAsBox( hx * .5f, hy, b2Vec2(-hx * .5f, 0), 0); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&polyShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterP: { b2PolygonShape polyShape; polyShape.SetAsBox( hx * .45f, hy, b2Vec2(-hx * .575f, 0), 0); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&polyShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); b2CircleShape circleShape; circleShape.m_radius = hx * .68f; circleShape.m_p = b2Vec2(hx * .3f, -hy * .35f); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterR: { b2PolygonShape polyShape; polyShape.SetAsBox( hx * .75f, hy, b2Vec2(-hx * .25f, 0), 0); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&polyShape, 0.05f); obj->mp_fixture->SetPhysicsSprite(*obj); b2Vec2 verts[5]; verts[0].Set(0.0f, 0.0f); //center verts[1].Set(hx * .6f, 0.0f); verts[2].Set(hx * .9f, hy * .5f); verts[3].Set(hx, hy); //bottom right verts[4].Set(0.0f, hy); //bottom middle polyShape.Set(verts, 5); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&polyShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); b2CircleShape circleShape; circleShape.m_radius = hx * .55f; circleShape.m_p = b2Vec2(hx * .25f, -hy * .40f); obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, 0.05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterN: { b2PolygonShape polyShape; polyShape.SetAsBox(obj->size.x/2.0f * .6f, obj->size.y/2.0f * .6f); obj->mp_fixture =obj->mp_physicsBody->CreateFixture(&polyShape, .05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; case kLetterO: { b2CircleShape circleShape; circleShape.m_radius = obj->size.x/2.0f * .6f; obj->mp_fixture = obj->mp_physicsBody->CreateFixture(&circleShape, .05f); obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); obj->mp_physicsBody->SetMassData(&massData); } break; } obj->mp_fixture->SetIsMagnetic(true); obj->mp_fixture->SetPhysicsSprite(*obj); return obj; }
void GraphicsCaptureSource::Render(const Vect2 &pos, const Vect2 &size) { if(capture) { Shader *lastShader = GetCurrentPixelShader(); float fGamma = float(-(gamma-100) + 100) * 0.01f; LoadPixelShader(drawShader); HANDLE hGamma = drawShader->GetParameterByName(TEXT("gamma")); if(hGamma) drawShader->SetFloat(hGamma, fGamma); //---------------------------------------------------------- // capture mouse bMouseCaptured = false; if(bCaptureMouse) { CURSORINFO ci; zero(&ci, sizeof(ci)); ci.cbSize = sizeof(ci); if(GetCursorInfo(&ci) && hwndCapture) { mcpy(&cursorPos, &ci.ptScreenPos, sizeof(cursorPos)); ScreenToClient(hwndCapture, &cursorPos); if(ci.flags & CURSOR_SHOWING) { if(ci.hCursor == hCurrentCursor) bMouseCaptured = true; else { HICON hIcon = CopyIcon(ci.hCursor); hCurrentCursor = ci.hCursor; delete cursorTexture; cursorTexture = NULL; if(hIcon) { ICONINFO ii; if(GetIconInfo(hIcon, &ii)) { xHotspot = int(ii.xHotspot); yHotspot = int(ii.yHotspot); UINT width, height; LPBYTE lpData = GetCursorData(hIcon, ii, width, height); if(lpData) { cursorTexture = CreateTexture(width, height, GS_BGRA, lpData, FALSE); if(cursorTexture) bMouseCaptured = true; Free(lpData); } DeleteObject(ii.hbmColor); DeleteObject(ii.hbmMask); } DestroyIcon(hIcon); } } } } } //---------------------------------------------------------- // game texture Texture *tex = capture->LockTexture(); Vect2 texPos = Vect2(0.0f, 0.0f); Vect2 texStretch = Vect2(1.0f, 1.0f); if(tex) { Vect2 texSize = Vect2(float(tex->Width()), float(tex->Height())); Vect2 totalSize = API->GetBaseSize(); Vect2 center = totalSize*0.5f; BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO); if(bStretch) { if(bIgnoreAspect) texStretch *= totalSize; else { float multiplyVal = (texSize.y * (totalSize.x / texSize.x) > totalSize.y) ? totalSize.y / texSize.y : multiplyVal = totalSize.x / texSize.x; texStretch *= texSize*multiplyVal; texPos = center-(texStretch*0.5f); } } else { texStretch *= texSize; texPos = center-(texStretch*0.5f); } Vect2 sizeAdjust = size/totalSize; texPos *= sizeAdjust; texPos += pos; texStretch *= sizeAdjust; RoundVect2(texPos); RoundVect2(texSize); if(bFlip) DrawSprite(tex, 0xFFFFFFFF, texPos.x, texPos.y+texStretch.y, texPos.x+texStretch.x, texPos.y); else DrawSprite(tex, 0xFFFFFFFF, texPos.x, texPos.y, texPos.x+texStretch.x, texPos.y+texStretch.y); capture->UnlockTexture(); BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA); //---------------------------------------------------------- // draw mouse if(bMouseCaptured && cursorTexture && GetForegroundWindow() == hwndCapture) { Vect2 newCursorPos = Vect2(float(cursorPos.x-xHotspot), float(cursorPos.y-xHotspot)); Vect2 newCursorSize = Vect2(float(cursorTexture->Width()), float(cursorTexture->Height())); newCursorPos /= texSize; newCursorSize /= texSize; newCursorPos *= texStretch; newCursorPos += texPos; newCursorSize *= texStretch; bool bInvertCursor = false; if(invertShader) { if(bInvertCursor = ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0 || (GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0)) LoadPixelShader(invertShader); } DrawSprite(cursorTexture, 0xFFFFFFFF, newCursorPos.x, newCursorPos.y, newCursorPos.x+newCursorSize.x, newCursorPos.y+newCursorSize.y); } } if(lastShader) LoadPixelShader(lastShader); } }
Vect2 SceneItem::GetCropBL() { return Vect2(GetCrop().x, -GetCrop().z); }