Jump to content

Cropping A Texture


tjheldna
 Share

Recommended Posts

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!

trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

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!

trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

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

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

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.

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

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...