Texture wrap, not actually wrapping?

Hi, I’m trying to get a simple kaleidoscope shader working. I have everything working, except I cannot for the life of me, get the texture wrap setting to use GL_REPEAT. Currently I’m testing a project with OpenGL3.2 on mac 10.9 with xcode. I’m using mostly sample code that simply draws an ofImage onto an ofPlane between an ofShader.begin() & .end() call.

The main app follows:

ofImage opal;
ofPlanePrimitive plane;
ofShader shader_keliedo;
ofShader shader;

bool use_kal = false;

//--------------------------------------------------------------
void testApp::setup(){
   
   std::cout<<glGetString(GL_VERSION)<<std::endl;
   
   opal.loadImage("opal.jpg");
   
   float planeScale = 0.75;
   int planeWidth = ofGetWidth() * planeScale;
   int planeHeight = ofGetHeight() * planeScale;
   int planeGridSize = 20;
   int planeColumns = planeWidth / planeGridSize;
   int planeRows = planeHeight / planeGridSize;
   
   plane.set(planeWidth, planeHeight, planeColumns, planeRows, OF_PRIMITIVE_TRIANGLES);
   plane.mapTexCoordsFromTexture(opal.getTextureReference());
   
   if(ofIsGLProgrammableRenderer()){
      shader_keliedo.load("gl3/kaleidoscope");
      shader.load("gl3/shader"); //passthrough shader
   }else{
      shader_keliedo.load("gl2/kaleidoscope");
      shader.load("gl2/shader"); //passthrough shader
   }
}

//--------------------------------------------------------------
void testApp::update(){
}

//--------------------------------------------------------------
void testApp::draw(){
   ofClear(255.0f, 255.f, 255.f);
   ofSetColor(255);
   //The next 4 lines don't seem to work.
   opal.getTextureReference().setTextureWrap(GL_REPEAT,GL_REPEAT); //doesn't work
   ofSetTextureWrap(GL_REPEAT,GL_REPEAT); //doesn't work
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //doesn't work
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //doesn't work
   
   opal.getTextureReference().bind();
   
   float mousePositionX = ofMap(mouseX, 0, ofGetWidth(), plane.getWidth(), -plane.getWidth(), true);
   float mousePositionY = ofMap(mouseY, 0, ofGetHeight(), plane.getHeight(), -plane.getHeight(), true);
   
   if (use_kal){
      shader_keliedo.begin();
      shader_keliedo.setUniform2f("mouse", mousePositionX, mousePositionY);
      shader_keliedo.setUniform1f("time", ofGetElapsedTimef());
      shader_keliedo.setUniform2f("resolution", ofGetWidth(),ofGetHeight());
      ofPushMatrix();
      ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
      plane.draw();
      ofPopMatrix();
      shader_keliedo.end();
   }else{
      shader.begin();
      shader.setUniform2f("mouse", mousePositionX, mousePositionY);
      ofPushMatrix();
      ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
      plane.draw();
      ofPopMatrix();
      shader.end();
   }
   
   opal.getTextureReference().unbind();
}


//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
   use_kal = !use_kal;
}

My gl3/kaleidoscope.vert shader:

#version 150

// these are for the programmable pipeline system and are passed in
// by default from OpenFrameworks
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 textureMatrix;
uniform mat4 modelViewProjectionMatrix;

in vec4 position;
in vec4 color;
in vec4 normal;
in vec2 texcoord;
// this is the end of the default functionality

// this is something we're creating for this shader
out vec2 varyingtexcoord;

// this is coming from our C++ code
uniform vec2 mouse;

void main()
{
   // here we move the texture coordinates
   varyingtexcoord = vec2(texcoord.x + mouse.x, texcoord.y + mouse.y);
   
   // send the vertices to the fragment shader
   gl_Position = modelViewProjectionMatrix * position;
}

and my kaleidoscope.frag shader:

#version 150

const float PI = 3.141592658;
const float TAU = 2.0 * PI;
const float sections = 10.0;

uniform vec2 resolution;
uniform float time;
uniform sampler2DRect tex0;

in vec2 varyingtexcoord;

out vec4 outputColor;

void main(void){
   vec2 pos = (gl_FragCoord.xy - resolution*0.5);//vec2(varyingtexcoord - 0.5 * resolution) / resolution.y;

  float rad = length(pos);
  float angle = atan(pos.y, pos.x);

  float ma = mod(angle, TAU/sections);
  ma = abs(ma - PI/sections);
  
  float x = cos(ma) * rad;
  float y = sin(ma) * rad;
	
  float t = time*5.0;
  
   outputColor = texture(tex0, vec2(x-t, y-t));
}

Here’s my full mac 10.8 xcode 5 source on github: https://github.com/abigpotostew/kaleidoscope

I don’t know if/what I’m doing wrong. I’m setting both the OF texture wrap functions as well as the OpenGL texture wrap settings, but nothing seems to work.I would be so grateful if you could help me get my texture wrap settings working.

PS I’m not set on OpenGL3+, if you have a working example with OpenGL2 or ES2+ I’d love to see it.

Hi!

I’m not sure why it’s not working, but I might have a workaround for you.
For the purpose of OpenGL ES 2.0 renderer in oF iOS app i had to make custom
fragment shader for warping (repeating) uv coordinates:

precision highp float;

uniform sampler2D tex;
uniform vec2 uvOffset; // normalised (0-1) uv offset 
uniform vec2 uvCorrection; // for correcting non ARB textures

varying vec2 texCoordVarying;


void main(void)
{
    vec2 uv = ( texCoordVarying + uvOffset ) * uvCorrection;
	gl_FragColor = texture2D( tex, mod( uv, uvCorrection ) );
    
}

The above shader results in scrolled ( via uvOffset ) and repeated texture.
You probably can ged rid of uvCorrection if using desktop version of openGL
which support non ARB ( not power of 2 ) textures.
Hope that helps somehow :smile:

@jkozniewski thanks! Your tip greatly helped me indirectly-- my biggest problem was thinking I was using normalized coordinates, but now I realize sampler2DRect uses non-normalized tex coordinates. I ended up fixing my problem by reverting to OpenGL2.1 using the non-programmable renderer, disabling non-power of 2 textures with ofDisableArbTex(), switching over my tex coordinates to the normalized [0…1] range, then calling setTextureWrap() on my non ARB ofTexture.

The result is pretty :smiley: http://imgur.com/r7NXNyn

You can check out the source: https://github.com/abigpotostew/kaleidoscope

My shader’s final destination is a Raspberry Pi using ES so I may end up using your warping algorithm.

Also, I’m curious what I was doing wrong with the OpenGL3 GLSL 150 version. If anyone has any insight, let me know!

Great to hear that I was able to help you out and good luck with raspberry pi implementation :slight_smile:

Hi,

I’m not sure it can help you, but I just read this in the openGL tutorial :

Since we’re not using power of two textures, i.e. textures that are strange sizes, we can’t use the classic GL_REPEAT, but that’s fine, it’s not really that useful anyways, honestly.

I have something like this working now, check out the full thread here: