openFrameworks tutorial, part II: Texture Mapping - mesh.addTexCoord(ofPoint()) args error

Hi! I was going through this nice tutorial and ran into a snag when my code would not compile. it has to do with ofMesh and adding texture coordinates. I seem to be giving the correct args when calling mesh.addTexCoord(ofPoint()) but i get an error message. Does anyone have insight on what i’m doing wrong? thanks!!

this is the url of the tutorial :

http://clab.concordia.ca/openframeworks-tutorial-part-ii-texture-mapping/

the error is in this line :

mesh.addTexCoord(ofPoint(x * (videoWidth / W), y * (videoHeight / H)));

error message is :

No viable conversion from ‘ofPoint’ (aka ‘ofVec3f’) to ‘const glm::vec<2, float, glm::packed_highp>’

this is the code for the implementation :

void ofApp::setup(){

// some code not included

//Set up vertices
for (int y=0; y<H; y++)
{
for (int x=0; x<W; x++)
{
// adding texture coordinates allows us to bind textures to it later
// --> this could be made into a function so that textures can be swapped / updated
mesh.addVertex(ofPoint((x - W/2) * meshSize, (y - H/2) * meshSize, 0));
mesh.addTexCoord(ofPoint(x * (videoWidth / W), y * (videoHeight / H)));
mesh.addColor(ofColor(255, 255, 255));
}
}

// some code not included

}

and here are the definitions in the .h file :

#pragma once

#include “ofMain.h”

class ofApp : public ofBaseApp{

public :

// some code not included

ofVideoPlayer video; //Prerecorded video

ofFbo fbo;

ofMesh mesh;

ofImage image;

ofPixels fboPixels;

private:

int videoHeight = 1080;

int videoWidth = 1920;

int W = 100; //Grid size

int H = 100;

int meshSize = 6;

float tiltCurrent = 0;

float tiltTarget = 0;

float turnCurrent = 1;

float turnTarget = 1;

};

I think issue is ofPoint is 3 floats (an x, y & z coordinate) but texCoords are 2 dimensional.

if you change the ofPoint(…) to glm::vec2(…) it should compile ok

1 Like

Thank you! I was able to compile with your changes.

Yeah cool, just for reference, oF has changed from using its own vector types to using glm, which is more of an industry standard library.

Wherever you see ofVec2/3/4f or ofMat you can replace it with glm::vec2/3/4 or glm::mat if you have any issues.

I think all of the oF docs and examples have switched but theres still plenty of examples out there from other sources that might need a bit of updating. Just something to be aware of.

1 Like

Great! Very helpful information!

I’m having an issue. When my video renders to the screen I can hear the video audio but no image. I just get a black screen which is the background. if I comment out the background, my rendering window is the default color. I’m using an fbo object. I think it has to do with the fbo object reading the video file maybe within this if statement:

if (video.isFrameNew())
{
// draw video into fbo
fbo.begin();

  int alpha = 20; // amount of smoothing
  ofEnableAlphaBlending();
  ofSetColor(255, 255, 255, alpha);

  // draw image into fbo
  video.draw(0, 0);
  ofDisableAlphaBlending();
  fbo.end();

}

here is the full code:

ofApp.h :

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
      ofVideoPlayer video; //Prerecorded video
      ofFbo fbo;
      ofMesh mesh;
      ofImage image;
      ofPixels fboPixels;
      
   private:
      int videoHeight = 1080;
      int videoWidth = 1920;
      int W = 100; //Grid size
      int H = 100;
      int meshSize = 6;
      float tiltCurrent = 0;
      float tiltTarget = 0;
      float turnCurrent = 1;
      float turnTarget = 1;

		
};

ofApp.cpp :

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
   video.load( "IMG_1943.mov" ); //Load the video file
   video.play(); //Start the video

   //setup fbo
   fbo.allocate(videoWidth, videoHeight);
   // clear fbo
   fbo.begin();
   ofClear(255,255,255, 0);
   fbo.end();

   if (video.isFrameNew())
   {
      // draw video into fbo
      fbo.begin();

      int alpha = 20; // amount of smoothing
      ofEnableAlphaBlending();
      ofSetColor(255, 255, 255, alpha);

      // draw image into fbo
      video.draw(0, 0);
      ofDisableAlphaBlending();
      fbo.end();
   }

   //Set up vertices
   for (int y=0; y<H; y++)
   {
      for (int x=0; x<W; x++)
      {
            // adding texure coordinates allows us to bind textures to it later
            // --> this could be made into a function so that textures can be swapped / updated
            mesh.addVertex(ofPoint((x - W/2) * meshSize, (y - H/2) * meshSize, 0));
            mesh.addTexCoord(glm::vec2(x * (videoWidth / W), y * (videoHeight / H)));
            mesh.addColor(ofColor(255, 255, 255));
      }
   }

   //Set up triangles' indices
   for (int y=0; y<H-1; y++)
   {
      for (int x=0; x<W-1; x++)
      {
         int i1 = x + W * y;
         int i2 = x+1 + W * y;
         int i3 = x + W * (y+1);
         int i4 = x+1 + W * (y+1);
         mesh.addTriangle( i1, i2, i3 );
         mesh.addTriangle( i2, i4, i3 );
      }
   }

   //convert fbo to ofImage format
   fbo.readToPixels(fboPixels);
   image.setFromPixels(fboPixels);

}

//--------------------------------------------------------------
void ofApp::update(){
   video.update();

   //Change vertices
   for (int y=0; y<H; y++)
   {
      for (int x=0; x<W; x++)
      {

         //Vertex index
         int i = x + W * y;
         ofPoint p = mesh.getVertex( i );

         float scaleX = videoWidth / W;
         float scaleY = videoHeight / H;

         // get brightness
         int index = ((x * scaleX) + videoWidth * (y * scaleY)) * 4; // FBO has four components (including Alpha)
         int brightness = fboPixels[index] / 4; // 4 is an arbitrary scalar to reduce the amount of distortion

         //Change z-coordinate of vertex
         p.z = ofNoise(x * 0.05, y * 0.05, ofGetElapsedTimef() * 0.5) * 100;
         mesh.setVertex( i, p );

         //Change color of vertex
         mesh.setColor(i , ofColor(255, 255, 255));
      }
   }


}

//--------------------------------------------------------------
void ofApp::draw(){
   //Set background to black and rendering color to white
//   ofBackground(0);
   ofSetHexColor(0xffffff);
   fbo.draw(0, 0);

   ofPushMatrix(); //Store the coordinate system

   //Move the coordinate center to screen's center
   ofTranslate( ofGetWidth()/2, ofGetHeight()/2, 0 );

   tiltCurrent = ofLerp(tiltCurrent, tiltTarget, 0.1);
   turnCurrent = ofLerp(turnCurrent, turnTarget, 0.1);
   ofRotateX(tiltCurrent);
   ofRotateZ(turnCurrent);

   //Draw mesh
   image.bind();
   mesh.draw();
   image.unbind();
   // mesh.drawWireframe();

   ofPopMatrix(); //Restore the coordinate system

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
   if (key == OF_KEY_DOWN)
   {
      tiltTarget -= 5;
   }
   else if (key == OF_KEY_UP)
   {
      tiltTarget += 5;
   }
   else if (key == OF_KEY_LEFT)
   {
      turnTarget -= 5;
   }
   else if (key == OF_KEY_RIGHT)
   {
      turnTarget += 5;
   }

}

I think you need to move the if (video.isFrameNew()) { ... } to update, setup is only called at the start while update is called every frame.

second, i think you need to call image.update() after the .setFromPixels()

If you’re not doing any processing on the pixels themselves, you can skip the whole image thing and call fbo.getTextureReference().bind()/.unbind() when you draw the mesh