//============================================================================== // //------------------------------------------------------------------------------ void Sprite3D::draw(const Renderer* renderer) { auto pDevice = renderer->getDevice(); auto shader = renderer->getShader(); shader->setVtxShader(_vtxShaderID); auto vtxShader = shader->getNowVtxShader(); UINT nSamplerIndex = shader->getNowPixShader()->_constTable->GetSamplerIndex("TexSamp0"); if(UINT_MAX != nSamplerIndex) { pDevice->SetTexture(nSamplerIndex,renderer->getTexture()->getTexture(_textureID)); } // 色 vtxShader->_constTable->SetFloatArray(pDevice,"gMaterial",_color,4); Matrix norMtx; D3DXMatrixInverse(&norMtx,nullptr,&getWorldMtx()); D3DXMatrixTranspose(&norMtx,&norMtx); vtxShader->_constTable->SetMatrix(pDevice,"gNorWorld",&norMtx); Matrix wvp = getWorldMtx() * renderer->getCamera()->getViewMtx() * renderer->getProjMtx(); vtxShader->_constTable->SetMatrix(pDevice,"gWorld",&getWorldMtx()); vtxShader->_constTable->SetMatrix(pDevice,"gWVP",&wvp); // デクラレーション設定 pDevice->SetVertexDeclaration(_p3DDec); // 頂点送信 pDevice->SetStreamSource(0,_vtxBuff,0,sizeof(VERTEX_3D)); // 描画 pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); }
IZ_BOOL CGraphicsDevice::DrawInstancedPrimitive( E_GRAPH_PRIM_TYPE prim_type, IZ_UINT idxOffset, IZ_UINT nPrimCnt) { return DrawPrimitive(prim_type, idxOffset, nPrimCnt); }
//------------------------------------ //NAME : Direct3DRender() //DESC : 绘制3D场景 //------------------------------------ void Direct3DRender() { /* Direct3D的绘制过程就是:绘制→显示→绘制→显示。 但是,每当开始绘制图形之前,都需要通过IDirect3DDevice9接口的Clear方法将后台缓存中的内容进行清空,并设置表面的填充颜色等 HRESULT IDirect3DDevice9::Clear( DWORD Count, const D3DRECT *pRects, //指定对表面指定的矩形区域进行清除操作,数组中包含的矩形的数量由Count参数指定 DWORD Flags, //指定了需要清除的表面,该参数可以取值于D3DCLEAR_TARGET、D3DCLEAR_ZBUFFER和D3DCLEAR_STENCIL,分别表示对后台缓存、深度缓存和模板缓存进行清除 D3DCOLOR Color, //用于指定在清除缓存内容后设置的背景色,可以通过D3DCOLOR_XRGB宏将RGB值转换给该参数 float Z, //指定当清除缓存内容后设置深度缓存的值 DWORD Stencil ); */ g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);//黑色背景 //开始绘制 g_pd3dDevice->BeginScene(); //在绘制立方体之前,分别取得绕x,y,z轴旋转变换的矩阵,然后将他们组合并让立方体同时绕这3个轴旋转 SetTransform(); /*图形绘制的实际过程*/ DrawPrimitive(); //结束绘制 g_pd3dDevice->EndScene(); //翻转 g_pd3dDevice->Present(NULL,NULL,NULL,NULL); }
void OvRenderer::RenderUnitRect( OvVertexShaderSPtr v_shader , OvPixelShaderSPtr p_shader ) { struct SScreenRect { OvPoint3 pos; OvPoint2 tex; }; static D3DVERTEXELEMENT9 rect_elem[] = { { 0, 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_POSITION, 0 }, { 0, 12 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; static SScreenRect rect[] = { {OvPoint3(-1,-1,0),OvPoint2(0,1)} , {OvPoint3(-1,+1,0),OvPoint2(0,0)} , {OvPoint3(+1,+1,0),OvPoint2(1,0)} , {OvPoint3(+1,-1,0),OvPoint2(1,1)}}; static LPDIRECT3DVERTEXBUFFER9 rectVertBuffer = CreateVertexStream( (void*)&rect[0], sizeof( SScreenRect ), 4 ); static LPDIRECT3DVERTEXDECLARATION9 rectDecl = CreateVertexDeclaration( rect_elem ); if ( v_shader ) SetVertexShader( v_shader ); if ( p_shader ) SetPixelShader( p_shader ); SetVertexStream( 0, SVertexStreamInfo( rectVertBuffer, sizeof( SScreenRect ), 0) ); SetVertexDeclaration( rectDecl ); DrawPrimitive( D3DPT_TRIANGLEFAN, 2); }
void GSDevice10::StretchRect(Texture& st, const GSVector4& sr, Texture& dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear) { BeginScene(); // om OMSetDepthStencilState(m_convert.dss, 0); OMSetBlendState(bs, 0); OMSetRenderTargets(dt, NULL); // ia float left = dr.x * 2 / dt.GetWidth() - 1.0f; float top = 1.0f - dr.y * 2 / dt.GetHeight(); float right = dr.z * 2 / dt.GetWidth() - 1.0f; float bottom = 1.0f - dr.w * 2 / dt.GetHeight(); GSVertexPT1 vertices[] = { {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, }; D3D10_BOX box = {0, 0, 0, sizeof(vertices), 1, 1}; m_dev->UpdateSubresource(m_convert.vb, 0, &box, vertices, 0, 0); IASetVertexBuffer(m_convert.vb, sizeof(vertices[0])); IASetInputLayout(m_convert.il); IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // vs VSSetShader(m_convert.vs, NULL); // gs GSSetShader(NULL); // ps PSSetShader(ps, ps_cb); PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); PSSetShaderResources(st, NULL); // rs RSSet(dt.GetWidth(), dt.GetHeight()); // DrawPrimitive(countof(vertices)); // EndScene(); }
static HRESULT STDMETHODCALLTYPE MyDrawPrimitive(IDirect3DDeviceN* pThis, D3DPRIMITIVETYPE a, DWORD b, LPVOID c, DWORD d, DWORD e) { d3ddebugprintf(__FUNCTION__ "(0x%X) called.\n", pThis); if(ShouldSkipDrawing(false, true)) return D3D_OK; HRESULT rv = DrawPrimitive(pThis, a, b, c, d, e); return rv; }
void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear) { BeginScene(); GSVector2i ds = dt->GetSize(); // om OMSetDepthStencilState(m_convert.dss, 0); OMSetBlendState(bs, 0); OMSetRenderTargets(dt, NULL); // ia float left = dr.x * 2 / ds.x - 1.0f; float top = 1.0f - dr.y * 2 / ds.y; float right = dr.z * 2 / ds.x - 1.0f; float bottom = 1.0f - dr.w * 2 / ds.y; GSVertexPT1 vertices[] = { {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)}, {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)}, }; IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); IASetInputLayout(m_convert.il); IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // vs VSSetShader(m_convert.vs, NULL); // gs GSSetShader(NULL); // ps PSSetShaderResources(st, NULL); PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); PSSetShader(ps, ps_cb); // DrawPrimitive(); // EndScene(); PSSetShaderResources(NULL, NULL); }
void Arrow::draw() { auto device = ShaderDevise::device(); device->SetTransform(D3DTS_WORLD, &world); device->SetFVF(D3DFVF_CUSTOMVERTEX); device->SetRenderState(D3DRS_LIGHTING, false); device->SetStreamSource(0, vbuf, 0, sizeof(CUSTOMVERTEX)); device->DrawPrimitive(D3DPT_LINELIST, 0, 2); device->SetRenderState(D3DRS_LIGHTING, true); }
void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVertices)[4], bool datm) { const GSVector2i& size = rt->GetSize(); if(GSTexture* t = CreateRenderTarget(size.x, size.y, rt->IsMSAA())) { // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows BeginScene(); ClearStencil(ds, 0); // om OMSetDepthStencilState(m_date.dss, 1); OMSetBlendState(m_date.bs, 0); OMSetRenderTargets(t, ds); // ia IASetVertexBuffer(iaVertices, sizeof(iaVertices[0]), countof(iaVertices)); IASetInputLayout(m_convert.il); IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // vs VSSetShader(m_convert.vs, NULL); // gs GSSetShader(NULL); // ps GSTexture* rt2 = rt->IsMSAA() ? Resolve(rt) : rt; PSSetShaderResources(rt2, NULL); PSSetSamplerState(m_convert.pt, NULL); PSSetShader(m_convert.ps[datm ? 2 : 3], NULL); // DrawPrimitive(); // EndScene(); Recycle(t); if(rt2 != rt) Recycle(rt2); } }
void AnimaRenderer::DrawPrimitives(AnimaScene* scene, AnimaShaderProgram* program) { if(program == nullptr) return; program->Use(); program->SetUniform("_projectionViewMatrix", scene->GetCamerasManager()->GetActiveCamera()->GetProjectionViewMatrix()); AInt nPrimitives = _primitives.GetSize(); for(AInt i = 0; i < nPrimitives; i++) DrawPrimitive(_primitives[i], program); }
/*************************************************************//** * * @brief 描画処理を行う * @param なし * @return なし * ****************************************************************/ void C_SpriteCreater::Draw() { // 頂点の書き換え pPointDatas_->RewriteVertices(vertices_.data(), drawSpriteCount_); // シェーダーの使用開始 pGlslObject_->Begin(); // サブルーチンを設定 pGlslObject_->BindActiveSubroutine(subroutineIndices_[cameraType_], Shader::GLSL::Type::s_GEOMETRY); // ユニフォーム変数を設定 SetUniformVariable(); // テクスチャマネージャーとOpenGLマネージャーを取得 auto pTextureManager = Texture::C_TextureManager::s_GetInstance(); auto pOpenGlManager = OpenGL::C_OpenGlManager::s_GetInstance(); // ブレンドを有効化し、ブレンドに使用する関数を設定 pOpenGlManager->EnableBlend(true); pOpenGlManager->SetBlendFunction(sourceFactor_, destinationFactor_); // カリングを無効化 pOpenGlManager->EnableCulling(false); // 深度のマスクを有効化 pOpenGlManager->EnableDepthMask(true); // アクティブなテクスチャユニットを設定し、テクスチャをバインド pTextureManager->SetActiveUnit(Fixed::Texture::s_UNIT_NUMBER); pTextureManager->Bind(Texture::Type::s_2D, pTextureData_->handle_); // スプライトを描画 pOpenGlManager->DrawPrimitive(OpenGL::Primitive::s_POINT, pPointDatas_->GetVertexArrayObjectHandle(), drawSpriteCount_); // 深度のマスクを無効化 pOpenGlManager->EnableDepthMask(false); // カリングを有効化 pOpenGlManager->EnableCulling(true); // ブレンドを無効化 pOpenGlManager->EnableBlend(false); // テクスチャをアンバインド pTextureManager->Unbind(Texture::Type::s_2D); // シェーダーの使用終了 pGlslObject_->End(); drawSpriteCount_ = 0; }
void OpenGLEngine::Draw (std::shared_ptr<VertexBuffer> vertexBuffer, std::shared_ptr<IndexBuffer> indexBuffer, std::shared_ptr<VisualEffect> visualEffect) { std::shared_ptr<Program> program = visualEffect->GetProgram (); std::string programName = program->GetProgramName (); OGLProgram* oglProgram = dynamic_cast<OGLProgram*> (program.get()); if (oglProgram) { GLuint programHandle = oglProgram->GetProgramHandle (); glUseProgram (programHandle); if (EnableShaders (visualEffect, programHandle)) { std::shared_ptr<OGLVertexBuffer> oglVertexBuffer = nullptr; std::shared_ptr<OGLIndexBuffer> oglIndexBuffer = nullptr; OGLVertexArrayObject* vao = nullptr; m_MapCO.Get (std::make_pair (vertexBuffer.get(), indexBuffer.get ()), vao); if (vao) { vao->Enable (); } else { if (vertexBuffer) { oglVertexBuffer = std::static_pointer_cast<OGLVertexBuffer> (Bind (vertexBuffer)); } if (indexBuffer) { oglIndexBuffer = std::static_pointer_cast<OGLIndexBuffer> (Bind(indexBuffer)); } vao = static_cast<OGLVertexArrayObject*> (Bind (oglVertexBuffer, oglIndexBuffer)); } DrawPrimitive (vertexBuffer.get (), indexBuffer.get ()); vao->Disable (); DisableShaders (visualEffect, programHandle); } else { fprintf (stderr, "The draw method in OpenGLEngine failed, because the OGL Program was not correct.\n"); } } }
static GLboolean _gld_mesa_render_stage_run( struct gl_context *ctx, struct tnl_pipeline_stage *stage) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_render_func *tab; GLint pass = 0; GLD_pb_dx9 *gldPB; /* Allow the drivers to lock before projected verts are built so * that window coordinates are guarenteed not to change before * rendering. */ ASSERT(tnl->Driver.Render.Start); tnl->Driver.Render.Start( ctx ); // NOTE: Setting D3DRS_SOFTWAREVERTEXPROCESSING for a mixed-mode device resets // stream, indices and shader to default values of NULL or 0. /* if ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) && gld->VStwosidelight.hShader && !ctx->Fog.Enabled) { IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware); _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); gldPB = &gld->PBtwosidelight; tnl->Driver.Render.Points = gld_Points2DTwoside_DX9; if (ctx->_TriangleCaps & DD_FLATSHADE) { tnl->Driver.Render.Line = gld_Line2DFlatTwoside_DX9; tnl->Driver.Render.Triangle = gld_Triangle2DFlatTwoside_DX9; tnl->Driver.Render.Quad = gld_Quad2DFlatTwoside_DX9; } else { tnl->Driver.Render.Line = gld_Line2DSmoothTwoside_DX9; tnl->Driver.Render.Triangle = gld_Triangle2DSmoothTwoside_DX9; tnl->Driver.Render.Quad = gld_Quad2DSmoothTwoside_DX9; } } else {*/ // IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE); IDirect3DDevice9_SetSoftwareVertexProcessing(gld->pDev, TRUE); gldPB = &gld->PB2d; _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); tnl->Driver.Render.Points = _gldSetupPoints[gld->iSetupFunc]; tnl->Driver.Render.Line = _gldSetupLine[gld->iSetupFunc]; tnl->Driver.Render.Triangle = _gldSetupTriangle[gld->iSetupFunc]; tnl->Driver.Render.Quad = _gldSetupQuad[gld->iSetupFunc]; // } _GLD_DX9_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; // Allocate primitive pointers // gldPB->pPoints is always first gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); ASSERT(tnl->Driver.Render.BuildVertices); ASSERT(tnl->Driver.Render.PrimitiveNotify); ASSERT(tnl->Driver.Render.Points); ASSERT(tnl->Driver.Render.Line); ASSERT(tnl->Driver.Render.Triangle); ASSERT(tnl->Driver.Render.Quad); ASSERT(tnl->Driver.Render.ResetLineStipple); ASSERT(tnl->Driver.Render.Interp); ASSERT(tnl->Driver.Render.CopyPV); ASSERT(tnl->Driver.Render.ClippedLine); ASSERT(tnl->Driver.Render.ClippedPolygon); ASSERT(tnl->Driver.Render.Finish); tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); if (VB->ClipOrMask) { tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; } else { tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); } do { GLuint i, length, flags = 0; for (i = 0 ; !(flags & PRIM_END) ; i += length) { flags = VB->Primitive[i].mode; length= VB->Primitive[i].count; ASSERT(length || (flags & PRIM_END)); ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); if (length) tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); } } while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass( ctx, ++pass )); // tnl->Driver.Render.Finish( ctx ); _GLD_DX9_VB(Unlock(gldPB->pVB)); _GLD_DX9_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, 0, gldPB->dwStride)); if (gldPB->nPoints) { _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); gldPB->nPoints = 0; } if (gldPB->nLines) { _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); gldPB->nLines = 0; } if (gldPB->nTriangles) { _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); gldPB->nTriangles = 0; } return GL_FALSE; /* finished the pipe */ }
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear) { if(!sTex || !dTex) { ASSERT(0); return; } BeginScene(); GSVector2i ds = dTex->GetSize(); // om OMSetDepthStencilState(m_convert.dss, 0); OMSetBlendState(bs, 0); OMSetRenderTargets(dTex, NULL); // ia float left = dRect.x * 2 / ds.x - 1.0f; float top = 1.0f - dRect.y * 2 / ds.y; float right = dRect.z * 2 / ds.x - 1.0f; float bottom = 1.0f - dRect.w * 2 / ds.y; GSVertexPT1 vertices[] = { {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sRect.x, sRect.y)}, {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sRect.z, sRect.y)}, {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sRect.x, sRect.w)}, {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sRect.z, sRect.w)}, }; IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); IASetInputLayout(m_convert.il); IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // vs VSSetShader(m_convert.vs, NULL); // gs /* NVIDIA HACK!!!! Not sure why, but having the Geometry shader disabled causes the strange stretching in recent drivers*/ GSSelector sel; //Don't use shading for stretching, we're just passing through - Note: With Win10 it seems to cause other bugs when shading is off if any of the coords is greater than 0 //I really don't know whats going on there, but this seems to resolve it mostly (if not all, not tester a lot of games, only BIOS, FFXII and VP2) //sel.iip = (sRect.y > 0.0f || sRect.w > 0.0f) ? 1 : 0; //sel.prim = 2; //Triangle Strip //SetupGS(sel); GSSetShader(NULL, NULL); /*END OF HACK*/ // // ps PSSetShaderResources(sTex, NULL); PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); PSSetShader(ps, ps_cb); // DrawPrimitive(); // EndScene(); PSSetShaderResources(NULL, NULL); }
void OpenGLEngine::Draw (std::shared_ptr<VertexBuffer> vertexBuffer, std::shared_ptr<VertexBuffer> instancedBuffer, std::shared_ptr<IndexBuffer> indexBuffer, std::shared_ptr<VisualEffect> visualEffect) { std::shared_ptr<Program> program = visualEffect->GetProgram (); std::string programName = program->GetProgramName (); OGLProgram* oglProgram = dynamic_cast<OGLProgram*> (program.get()); if (oglProgram) { GLuint programHandle = oglProgram->GetProgramHandle (); glUseProgram (programHandle); if (EnableShaders (visualEffect, programHandle)) { std::shared_ptr<OGLVertexBuffer> oglVertexBuffer = nullptr; std::shared_ptr<OGLVertexBuffer> oglInstancedBuffer = nullptr; std::shared_ptr<OGLIndexBuffer> oglIndexBuffer = nullptr; OGLVertexArrayObject* vao = nullptr; m_MapCO.Get (std::make_pair (vertexBuffer.get(), indexBuffer.get ()), vao); if (vao) { vao->Enable (); } else { if (vertexBuffer) { oglVertexBuffer = std::static_pointer_cast<OGLVertexBuffer> (Bind (vertexBuffer)); } if (indexBuffer) { oglIndexBuffer = std::static_pointer_cast<OGLIndexBuffer> (Bind(indexBuffer)); } vao = static_cast<OGLVertexArrayObject*> (Bind (oglVertexBuffer, oglIndexBuffer)); oglInstancedBuffer = std::static_pointer_cast<OGLVertexBuffer> (Bind (instancedBuffer)); oglInstancedBuffer->Enable (); VertexAttributes vertexAttrib = vertexBuffer->GetVertexAttrib (); VertexAttributes instancedAttrib = instancedBuffer->GetVertexAttrib (); int vertexBufferNumAttrib = vertexAttrib.GetNumAttrib (); int instancedBufferNumAttrib = instancedAttrib.GetNumAttrib (); for (int i = vertexBufferNumAttrib; i < vertexBufferNumAttrib + instancedBufferNumAttrib; i++) { ContainerType type = instancedAttrib.GetContainerType (i - vertexBufferNumAttrib); int offset = instancedAttrib.GetOffset(i - vertexBufferNumAttrib); int numElements = DataAttributes::GetNumElement (type); GLenum channelType = oglInstancedBuffer->m_ChannelType[DataAttributes::GetElementType (type)]; size_t vertSize = instancedAttrib.GetVertexSize (); glEnableVertexAttribArray (i); glVertexAttribPointer (i, numElements, channelType, GL_FALSE, vertSize, (void*)offset); glVertexAttribDivisor (i, 1); } } DrawPrimitive (vertexBuffer.get (), instancedBuffer.get (), indexBuffer.get ()); vao->Disable (); DisableShaders (visualEffect, programHandle); } else { fprintf (stderr, "The draw method in OpenGLEngine failed, because the OGL Program was not correct.\n"); } } }
int HookedPlayMovieBink(const char* filename, const SubtitleLine* subtitles, int flags, uint32_t soundtrackId) { if (!binkInitialized) { return 0; } movieFuncs.MovieIsPlaying = true; binkFuncs.initialize(); uint32_t openFlags = 0; if (soundtrackId) { binkFuncs.BinkSetSoundTrack(1, &soundtrackId); openFlags |= 0x4000; // Apparently tells BinkOpen a soundtrack was used } auto movie = binkFuncs.BinkOpen(filename, openFlags); if (!movie) { logger->error("Unable to load BINK movie {} with flags {}", filename, openFlags); return 13; } // The disasm apparently goes crazy for the conversion here int binkVolume = (*tigSoundAddresses.movieVolume) * 258; binkFuncs.BinkSetVolume(movie, 0, binkVolume); auto d3dDevice = graphics->device(); d3dDevice->ShowCursor(FALSE); // Create the movie texture we write to IDirect3DTexture9* texture; if (D3DLOG(d3dDevice->CreateTexture(movie->width, movie->height, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr)) != D3D_OK) { logger->error("Unable to create texture for bink video"); return 0; } // Clear screen with black color and present immediately d3dDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0, 0); d3dDevice->Present(nullptr, nullptr, nullptr, nullptr); processTigMessages(); MovieRect movieRect = getMovieRect(movie); // TODO UV should be manipulated for certain vignettes since they have been letterboxed in the bink file!!! // Set vertex shader MovieVertex vertices[4] = { {movieRect.left, movieRect.top, 0, 0}, {movieRect.right, movieRect.top, 1, 0}, {movieRect.right, movieRect.bottom, 1, 1}, {movieRect.left, movieRect.bottom, 0, 1} }; IDirect3DVertexBuffer9* vertexBuffer; D3DLOG(d3dDevice->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_DEFAULT, &vertexBuffer, nullptr)); void* data; D3DLOG(vertexBuffer->Lock(0, 0, &data, 0)); memcpy(data, vertices, sizeof(vertices)); vertexBuffer->Unlock(); SubtitleRenderer subtitleRenderer(subtitles); bool keyPressed = false; while (!keyPressed && binkRenderFrame(movie, texture)) { D3DLOG(d3dDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0, 0)); D3DLOG(d3dDevice->BeginScene()); renderStates->SetTexture(0, texture); renderStates->SetTextureMinFilter(0, D3DTEXF_LINEAR); renderStates->SetTextureMagFilter(0, D3DTEXF_LINEAR); renderStates->SetTextureMipFilter(0, D3DTEXF_LINEAR); renderStates->SetLighting(false); renderStates->SetZEnable(false); renderStates->SetCullMode(D3DCULL_NONE); renderStates->SetTextureTransformFlags(0, D3DTTFF_DISABLE); renderStates->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); renderStates->SetStreamSource(0, vertexBuffer, sizeof(MovieVertex)); renderStates->SetTextureColorOp(0, D3DTOP_SELECTARG1); renderStates->SetTextureColorArg1(0, D3DTA_TEXTURE); renderStates->SetTextureAlphaOp(0, D3DTOP_SELECTARG1); renderStates->SetTextureAlphaArg1(0, D3DTA_TEXTURE); renderStates->Commit(); D3DLOG(d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2)); subtitleRenderer.Render(); D3DLOG(d3dDevice->EndScene()); D3DLOG(d3dDevice->Present(NULL, NULL, NULL, NULL)); templeFuncs.ProcessSystemEvents(); TigMsg msg; while (!msgFuncs.Process(&msg)) { // Flags 1 seems to disable skip via keyboard. Also seems unused. if (!(flags & 1) && msg.type == TigMsgType::KEYSTATECHANGE && LOBYTE(msg.arg2) == 1) { // TODO Wait for the key to be unpressed again keyPressed = true; break; } } } binkFuncs.BinkClose(movie); texture->Release(); vertexBuffer->Release(); // Unclear what this did (black out screen after last frame?) /* Haven't found a single occasion where it's used. if (!(flags & 8)) { sub_101D8790(0); play_movie_present(); } */ movieFuncs.MovieIsPlaying = false; d3dDevice->ShowCursor(TRUE); return 0; }