Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/image view tex coords #107

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 61 additions & 16 deletions src/bluecadet/views/ImageView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ ImageView::ImageView() : BaseView(),
mTexture(nullptr),
mTextureScale(1.0f),
mScaleMode(sDefaultScaleMode),
mTopDown(false)
mTopDown(false),
mHasCustomTexCoords(false),
mTexCoordsAreDirty(true)
{
mDefaultTexCoords = { vec2(0.0f, 0.0f), vec2(1.0f, 0.0f), vec2(1.0f, 1.0f), vec2(0.0f, 1.0f) };
mTexCoords = mDefaultTexCoords;
}

ImageView::~ImageView() {
Expand All @@ -27,6 +31,18 @@ void ImageView::reset() {
setScaleMode(sDefaultScaleMode);
}

void ImageView::setTexCoords(std::vector<ci::vec2> coords ) {
mUserTexCoords = coords;
mHasCustomTexCoords = true;
mTexCoordsAreDirty = true;
invalidate(false, true);
}

void ImageView::setTexture(ci::gl::TextureRef texture, std::vector<ci::vec2> coords, const bool resizeToTexture) {
setTexCoords(coords);
setTexture(texture, resizeToTexture);
}

void ImageView::setTexture(ci::gl::TextureRef texture, const bool resizeToTexture) {
mTexture = texture;

Expand All @@ -41,6 +57,7 @@ void ImageView::setTexture(ci::gl::TextureRef texture, const bool resizeToTextur
}

invalidate(false, true);

}

void ImageView::validateContent() {
Expand Down Expand Up @@ -70,19 +87,26 @@ void ImageView::validateContent() {
break;
}
}
}

void ImageView::draw() {
if (!mTexture) return;

BaseView::draw();
//use the appropriate tex coords
if (!mHasCustomTexCoords) {
mTexCoords = mDefaultTexCoords;
} else {
mTexCoords = mUserTexCoords;
}

//flip the tex coords if we're not using top down
if (!mTopDown) {
swap(mTexCoords[0], mTexCoords[3]);
swap(mTexCoords[1], mTexCoords[2]);
}

//setup static shader once for all instances
static gl::GlslProgRef shader = nullptr;
static gl::BatchRef batch = nullptr;

if (!shader) {
shader = gl::GlslProg::create(gl::GlslProg::Format()
.vertex(CI_GLSL(150,
shader = gl::GlslProg::create(gl::GlslProg::Format().vertex(CI_GLSL(150,

uniform mat4 ciModelViewProjection;
uniform vec2 uSize;
in vec4 ciPosition;
Expand All @@ -97,17 +121,17 @@ void ImageView::draw() {
vec4 pos = ciPosition * vec4(uSize, 0, 1);
gl_Position = ciModelViewProjection * pos;
}

)).fragment(CI_GLSL(150,

uniform sampler2D uTex0;
uniform vec2 uTexScale;
uniform int uTopDown;
in vec2 vTexCoord0;
in vec4 vColor;
out vec4 oColor;

void main(void) {
vec2 texCoord = vTexCoord0;
texCoord.y = uTopDown != 0 ? 1.0 - texCoord.y : texCoord.y; // flip y if necessary
texCoord = (texCoord - vec2(0.5)) * uTexScale + vec2(0.5); // scale around center

if (texCoord.x < 0 || texCoord.y < 0 || texCoord.x > 1.0 || texCoord.y > 1.0) {
Expand All @@ -118,16 +142,37 @@ void ImageView::draw() {
oColor.rgb /= oColor.a;
oColor *= vColor;
}

)));
}

// make the batch only if: it hasn't been made and the shader is ready,
//or if the tex coords need updating
if ( (!mBatch && shader) || mTexCoordsAreDirty ) {

auto rect = geom::Rect().rect(Rectf(0, 0, 1.0f, 1.0f))
.texCoords( mTexCoords[0],
mTexCoords[1],
mTexCoords[2],
mTexCoords[3] );
mTexCoordsAreDirty = false;

mBatch = gl::Batch::create(rect, shader);

batch = gl::Batch::create(geom::Rect().rect(Rectf(0, 0, 1.0f, 1.0f)), shader);
}

}

void ImageView::draw() {

if (!mTexture || !mBatch) return;

BaseView::draw();

mTexture->bind(0);
shader->uniform("uTexScale", mTextureScale);
shader->uniform("uSize", mTextureSize);
shader->uniform("uTopDown", mTopDown ? 1 : 0);
batch->draw();
mBatch->getGlslProg()->uniform("uTexScale", mTextureScale);
mBatch->getGlslProg()->uniform("uSize", mTextureSize);
mBatch->draw();
}

}
Expand Down
31 changes: 26 additions & 5 deletions src/bluecadet/views/ImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,27 @@ class ImageView : public BaseView {
void reset() override;

inline ci::gl::TextureRef getTexture() const { return mTexture; }
inline void setTexture(const ci::gl::TextureRef value, const bool resizeToTexture = true);
inline void setTexture(const ci::gl::TextureRef value, const bool resizeToTexture = true);

//overloaded setup for applying custom texcoords
void setTexture(const ci::gl::TextureRef value, const std::vector<ci::vec2> coords, const bool resizeToTexture = true);

//for updating the texCoords after initialization
std::vector<ci::vec2> getTexCoords() { return mTexCoords; }
void setTexCoords( const std::vector<ci::vec2> coords );

//setting the default texture coordinates also causes
//the image to re-validate with the new texcoords
void setDefaultTexCoords(const std::vector<ci::vec2> coords) { mDefaultTexCoords = coords; setTexCoords(mDefaultTexCoords); }
std::vector<ci::vec2> getDefaultTexCoords() { return mDefaultTexCoords; }

//! Defaults to getDefaultScaleMode()
inline ScaleMode getScaleMode() const { return mScaleMode; }
inline void setScaleMode(const ScaleMode scaleMode) { mScaleMode = scaleMode; invalidate(false, true); }
inline ScaleMode getScaleMode() const { return mScaleMode; }
inline void setScaleMode(const ScaleMode scaleMode) { mScaleMode = scaleMode; invalidate(false, true); }

//! Defaults to STRETCH
static ScaleMode getDefaultScaleMode() { return sDefaultScaleMode; }
static void setDefaultScaleMode(const ScaleMode scaleMode) { sDefaultScaleMode = scaleMode; }
static ScaleMode getDefaultScaleMode() { return sDefaultScaleMode; }
static void setDefaultScaleMode(const ScaleMode scaleMode) { sDefaultScaleMode = scaleMode; }

//! Defaults to false. Can be set independently of the texture's top-down setting in case you have less control over that.
void setTopDown(const bool value) { mTopDown = value; }
Expand All @@ -55,11 +67,20 @@ class ImageView : public BaseView {

static ScaleMode sDefaultScaleMode;

ci::gl::BatchRef mBatch;
ci::gl::TextureRef mTexture;
ci::vec2 mTextureScale;
ci::vec2 mTextureSize;
ScaleMode mScaleMode;
bool mTopDown;

//normalized texture coordinates, clockwise starting at upper left
std::vector<ci::vec2> mDefaultTexCoords;
std::vector<ci::vec2> mTexCoords;
std::vector<ci::vec2> mUserTexCoords;
bool mHasCustomTexCoords;
bool mTexCoordsAreDirty;

};

}
Expand Down