tjheldna Posted October 5, 2014 Share Posted October 5, 2014 What I'm trying to achieve is create a viewport of the character speaking to go along with the dialog displayed. What I have done is create a new buffer which grabs a screen of character speaking. and draw the image next to the characters dialog. What I don't know how to do is to crop the image as I just want to get the center portion which will be of the character's face (at the moment it's displaying the entire screen). Are there any texture functions that will do this or alike? Cheers! Quote Link to comment Share on other sites More sharing options...
macklebee Posted October 5, 2014 Share Posted October 5, 2014 see here: http://www.leadwerks.com/werkspace/topic/10809-lua-drawing-a-tiled-image/#entry79259 Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
tjheldna Posted October 6, 2014 Author Share Posted October 6, 2014 Sorry this post was done real quickly. K here is the shader, I created a new one called drawimagecrop.shader instead of modifying... uniform vec4 drawcolor; uniform sampler2D texture0; uniform vec2 scale = vec2(1.0,1.0); //added for tiling uniform vec2 clipcoords = vec2(0.0,0.0); //added for clipping in vec2 vTexCoords0; out vec4 fragData0; void main(void) { fragData0 = drawcolor * texture(texture0, (vTexCoords0 + clipcoords) * scale); } here is my C++ ViewportWidget class // // ViewportWidget.cpp // BCS // // Created by Tim Heldna on 13/03/13. // Copyright (c) 2013 BCS. All rights reserved. // #include "ViewportWidget.h" #include "GameWorld.h" ViewportWidget::ViewportWidget(World *&w, Context *current, short posX, short posY, short width, short height) : Widget(posX, posY, width, height, kWidgetTypeRemoteCamera) { cbuffer = NULL; world = w; context = Context::GetCurrent(); bufferTexture = Texture::Create(current->GetWidth(), current->GetHeight()); cbuffer = Buffer::Create(current->GetWidth(), current->GetHeight(), 1, 0, 0); cbuffer->SetColorTexture(bufferTexture); shader = Shader::Load("Shaders/Drawing/drawimagecrop.shader"); shader->SetVec2("clipcoords", Vec2(0.01, 0.4)); SetFlags(GetFlags() | kWidgetFlagsNoInput); } ViewportWidget::~ViewportWidget() { if(shader)shader->Release(); if(cbuffer)cbuffer->Release(); if (bufferTexture) bufferTexture->Release(); } Widget *ViewportWidget::HandleMouseEvent(Widget *widget) { if (TheGameWorld) { //Render to buffer cbuffer->Enable(); cbuffer->Clear(); Vec3 currPos = TheGameWorld->GetCamera()->GetEntity()->GetPosition(); Vec3 currRot = TheGameWorld->GetCamera()->GetEntity()->GetRotation(); //TheGameWorld->GetCamera()->GetEntity()->SetPosition(pos); //TheGameWorld->GetCamera()->GetEntity()->SetRotation(rot); world->Render(); TheGameWorld->GetCamera()->GetEntity()->SetPosition(currPos); TheGameWorld->GetCamera()->GetEntity()->SetRotation(currRot); cbuffer->Disable(); //Switch back to context and render Context::SetCurrent(context); } return Widget::HandleMouseEvent(widget); } void ViewportWidget::Render() { Widget::Render(); if (bufferTexture) { bufferTexture->clamp[0] = true; bufferTexture->clamp[1] = true; Shader*prevShader = context->GetShader(); context->SetShader(shader); context->DrawImage(bufferTexture, worldPosX, worldPosY, width, height); context->SetShader(prevShader); } } void ViewportWidget::Remove() { Widget::Remove(); } Here is the result Note in the code I'm setting the clamp's if I don't the texture will tile. Also correct me if I'm wrong but is this only clipping this on two sides? Cheers! Quote Link to comment Share on other sites More sharing options...
macklebee Posted October 6, 2014 Share Posted October 6, 2014 well the intention of that shader modification was for the "clipcoords" uniform to be used in conjunction with the "scale" uniform to control what is being shown on the screen. Also remember that the "clipcoords" is in units from 0 to 1. So with clamping in effect when you set the clipcoords then you would have to scale the image to fill the rest of the buffer or you will get a smeared image filling the rest... Also, I should have updated that post but I found that multiplying the texcoords by the scale and then adding the clipcoords resulted better in what was intended... so the shader line should look like this: fragData0 = drawcolor * texture(texture0, (vTexCoords0 * scale + clipcoords)); and this is an example program to try (keeping in mind its still based on the drawimage shader modified): function App:Start() self.window = Window:Create("example",0,0,800,600,Window.Titlebar+Window.Center) self.context = Context:Create(self.window) self.world = World:Create() self.camera = Camera:Create() self.camera:SetPosition(0,0,-3) self.light = DirectionalLight:Create() self.light:SetRotation(45,45,0) self.buffer1 = Buffer:GetCurrent() self.box = Model:Box() self.box:SetColor(1,0.5,0,1) self.buffer2 = Buffer:Create(self.context:GetWidth(),self.context:GetHeight(),1,1) self.texture = Texture:Load("Materials/Developer/bluegrid.tex") self.texture:SetClampMode(true,true) self.shader = Shader:Load("Shaders/Drawing/drawimage.shader") self.buffer2:Enable() self.shader:SetVec2("clipcoords", Vec2(0.5,0.5)) --start drawing at center of image self.shader:SetVec2("scale", Vec2(0.5,0.5)) -- scales the UV coords by 2 self.context:DrawImage(self.texture,0,0,self.buffer2:GetWidth(),self.buffer2:GetHeight()) self.shader:SetVec2("clipcoords", Vec2(0.0,0.0)) --set back to default self.shader:SetVec2("scale", Vec2(1.0,1.0))--set back to default self.buffer1:Enable() return true end function App:Loop() if (self.window:Closed() or self.window:KeyDown(Key.Escape)) then return false end self.box:Turn(Time:GetSpeed()*0.5,Time:GetSpeed()*0.5,0) Time:Update() self.world:Update() self.world:Render() self.context:SetBlendMode(Blend.Alpha) self.context:DrawImage(self.buffer2:GetColorTexture(0),550,350, 200, 200) self.context:Sync(); return true end Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
macklebee Posted October 6, 2014 Share Posted October 6, 2014 For what you are doing though you could probably get away with just setting the buffers size ratios to be the same and camera FOV to create a zoomed in look. The intention with that shader modfication was more for just controlling what parts of a texture image to show. In your case, since you are already doing a buffer, then i would do it the way we did in LE2 and just control the size of what was being drawn to the buffer. Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.