We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Vertices+texture glitch
Page Index Toggle Pages: 1
Vertices+texture glitch? (Read 1626 times)
Vertices+texture glitch?
Apr 18th, 2009, 3:31am
 
Hey all,

I'm stumped by this.

In short what I'm trying to achieve: I draw a simple quad of vertices that maps the texture of a trapezium shape (screenX, -Ys of a simple 3D cube) to a square, hence reverting the perspective. (Or that's the goal at this stage)

http://tiemen.pruts.nl/files/pics/cube.png

The trapezium that's being mapped in this case is aehd (right surface)

Though it maps the corners correctly, something is going wrong by some diagonal somewhere in the middle. It's position is not stationary, but will move gradually when you move the cube (and thus the mapped area)

What I suspect is that it has somewhat to do with the triangulating of the surface, and taking only a very small area of the mapped texture might produce artifacts that look a lot like these schematics:
http://www.flashandmath.com/advanced/menu3d/transformer.html

My code is pretty straightforward:

Code:

void drawSquare() {

 beginShape();
 texture(img);

 vertex(0, 0, current_x[3], current_y[3]);
 vertex(grootte, 0, current_x[7], current_y[7]);
 vertex(grootte, grootte,  current_x[4],  current_y[4]);
 vertex(0, grootte,  current_x[0],  current_y[0]);

 endShape();

}


current_n are arrays containing the screenN's of the 3D cube.
Re: Vertices+texture glitch?
Reply #1 - Apr 18th, 2009, 4:16pm
 
i thin it might be this: http://processing.org/learning/3d/texturecube.html

"The textures get distorted using the P3D renderer as you can see, but they look great using OPENGL"
Re: Vertices+texture glitch?
Reply #2 - Apr 19th, 2009, 4:33pm
 
Thanks, forgot to mention I tried both renderers, and they made no difference at all regarding this issue.

Comparing to this cube example, the only difference is, and where I suspect the problem lies, is that I only try to use such a small area of the texture image. (And thus the default textureMode)
Re: Vertices+texture glitch?
Reply #3 - Apr 20th, 2009, 2:50am
 
> Thanks, forgot to mention I tried both renderers, and they made no difference at all regarding this issue.

ok.

can't really tell much else from the code snippet you provide. can you post the whole thing?
Re: Vertices+texture glitch?
Reply #4 - Apr 21st, 2009, 4:16am
 
Sure.. Please don't mind the uglyness..

Code:

import processing.opengl.*;

PImage img;
PFont font;

float[] xy = new float[2];
int grootte = 300;

Boolean enter = false;

float rotatex = 0;
float rotatey = 0;
float rotatez = 0;
float bokz = 0;

float[] current_x = new float[8];
float[] current_y = new float[8];

void setup() {
 size(800, 533, P3D);

 float fov = PI/3.0;
 float cameraZ = (height/2.0) / tan(fov/2.0);

 float aspect = float(width)/float(height);
 float zNear = cameraZ/10.0;
 float zFar = cameraZ*10.0;

 perspective(fov, aspect, zNear, zFar);

 img = loadImage("img.jpg");
 font = loadFont("Serif.vlw");
 

}

void draw() {
 background(64);

 if(mousePressed == true) {

   xy[0] = mouseX;
   xy[1] = mouseY;

 }

 //pointLight(255, 255, 255, 100, 100, 400);


 drawBox(xy[0], xy[1], bokz, grootte, rotatez, rotatey, rotatex);

 if (enter) {
   drawShape();
 }
 
 tint(255, 128);
 image(img, 0, 0);

}

void drawShape() {

 beginShape();
 texture(img);

 vertex(0, 0, current_x[3], current_y[3]);
 vertex(grootte, 0, current_x[7], current_y[7]);
 vertex(grootte, grootte,  current_x[4],  current_y[4]);
 vertex(0, grootte,  current_x[0],  current_y[0]);

 endShape();

}

void drawBox(float x, float y, float z, int boxsize, float rotz, float roty, float rotx) {
 stroke(255);
 //fill(255, 64);
 noFill();

 pushMatrix();

 translate(x, y, z);
 rotateZ(rotz);
 rotateY(roty);
 rotateX(rotx);

 box(boxsize);

 int n = boxsize/2;
 
 fill(255);

 translate(0, 0, -n);

 textFont(font);

 text("a, "+screenX(n, n, 0)+", "+screenY(n, n, 0), n, n);

 current_x[0] = screenX(n, n, 0);
 current_y[0] =  screenY(n, n, 0);

 text("b", -n, n);

 current_x[1] = screenX(-n, n, 0);
 current_y[1] =  screenY(-n, n, 0);

 text("c, "+screenX(-n,-n,0)+", "+screenY(-n,-n,0), -n, -n);

 current_x[2] = screenX(-n, -n, 0);
 current_y[2] = screenY(-n,-n,0);

 text("d, "+screenX(n,-n,0)+", "+screenY(n, -n,0), n, -n);

 current_x[3] = screenX(n, -n, 0);
 current_y[3] = screenY(n, -n, 0);

 translate(0,0, n*2); // boxsize

 text("e", n, n);

 current_x[4] = screenX(n, n, 0);
 current_y[4] =  screenY(n, n, 0);

 text("f", -n, n);

 current_x[5] = screenX(-n, n, 0);
 current_y[5] =  screenY(-n, n, 0);

 text("g", -n, -n);

 current_x[6] = screenX(-n, -n, 0);
 current_y[6] =  screenY(-n, -n, 0);

 text("h, "+screenX(n,-n,0)+", "+screenY(n, -n,0), n, -n);

 current_x[7] = screenX(n,-n,0);
 current_y[7] = screenY(n,-n,0);
 
 popMatrix();


}



void keyPressed() {
 if (key == CODED) {
   if (keyCode == UP) {
     rotatex += PI/180;
   }
   else
     if (keyCode == DOWN) {
     rotatex -= PI/180;
   }
   else
     if (keyCode == LEFT) {
     rotatey -= PI/180;
   }
   else
     if (keyCode == RIGHT) {
     rotatey += PI/180;
   }
   else
     if (keyCode == KeyEvent.VK_PAGE_DOWN) {
     rotatez -= PI/180;
   }
   else
     if (keyCode == KeyEvent.VK_PAGE_UP ) {
     rotatez += PI/180;
   }

 }

 else
   if (key == '=' || key == '+') {
   grootte += 5;
 }
 else
   if (key == '-' || key == '_') {
   grootte -= 5;
 }
 if (key == '[' || key == '{') {
   bokz += 5;
 }
 else
   if (key == ']' || key == '}') {
   bokz -= 5;
 }
 else
   if (key == ',' || key == '<') {
   rotatez -= PI/180;
 }
 else
   if (key == '.' || key == '>') {
   rotatez += PI/180;
 }
 else
   if (key == ENTER || key == RETURN ) {
   enter = true;
 }

}
Re: Vertices+texture glitch?
Reply #5 - Apr 21st, 2009, 2:14pm
 
no luck here. (Processing 1.0.3)

this: http://dev.processing.org/bugs/show_bug.cgi?id=103
mentions
 hint(ENABLE_ACCURATE_TEXTURES);
but that does nothing in opengl and disables textures completely in P3D.

i also tried adding QUADS to BeginShape() but that didn't help.
Re: Vertices+texture glitch?
Reply #6 - Apr 22nd, 2009, 6:09am
 
Bummer. Thanks for the effort.

I'll go look around, poke my nose. Maybe I'll come up with something.
Re: Vertices+texture glitch?
Reply #7 - Apr 22nd, 2009, 1:27pm
 
Try this experiment-
Move the box over an area where there is a straight horizontal line so that you get the distortion. Press the - key so the resulting image shrinks keeping the box face centred over the horizontal line. As the image shrinks the distortion gets less.

I changed the cube face you were using from a single quad into 2 triangles and the distortion was the same along the shared hypotenuse. Depending on which way I defined the triangles the distortion was either top-left to bottom right or top-right to botom-left.

It was obvious from these experiments that the mapping of the box edges is fine but the mapping on the diagonal does not work i.e. the centre on the box diagonal does not correspond to the center of the resulting image diagonal.

There are hints in the article at the URL in your first post which point to a possible solution. I say possible because the evidence suggests it will work but I have not personally tested it.

Instead of the cube face being a single quad change it so each face is 6x6 quads adjusting the texture coordinates accordingly. In this case the resulting image would comprise of 36 'tiles'. Based on the image I used in the above experiment this seems a reasonable compromise although images with very strong horizontals and diagonals a larger number (e.g. 8x8) would be appropriate.
Re: Vertices+texture glitch?
Reply #8 - Apr 22nd, 2009, 3:35pm
 
It turned out that my deductions were correct. Increasing the number of quads on the cube face improved it no end. The code below uses an 8x8 grid so there are 64 Squares and the diagonals are now an eighth of the original size reducing distortion.

I have modified your program so that it can easily be adapted so that you can change faces. It not the neatest code I have ever done but it is always harder to add 'unplanned features' to a program without some compromises.

You can try different grid sizes by changeing the gridSize variable.

The makeGrid function expects 4 integers representing the index values to use in your coordinate arrays.

Code:

import processing.opengl.*;

PImage img;
PFont font;

float[] xy = new float[2];
int grootte = 300;

Boolean enter = false;

float rotatex = 0;
float rotatey = 0;
float rotatez = 0;
float bokz = 0;

float[] current_x = new float[8];
float[] current_y = new float[8];

// Store texture coordinates for a face with multiple QUADS
int gridSize;
Point[][] gpoint;

class Point {
 public float x;
 public float y;

 public void interpolate(Point start, Point end, float interp){
   x = start.x + interp * (end.x - start.x);
   y = start.y + interp * (end.y - start.y);
 }

}


void setup() {
 size(800, 533, P3D);

 gridSize = 8;      // Try different values
 gpoint = new Point[gridSize + 1][gridSize + 1];
 for(int i = 0; i < gridSize + 1; i++)
   for(int j = 0; j < gridSize + 1; j++)
     gpoint[i][j] = new Point();

 float fov = PI/3.0;
 float cameraZ = (height/2.0) / tan(fov/2.0);

 float aspect = float(width)/float(height);
 float zNear = cameraZ/10.0;
 float zFar = cameraZ*10.0;

 perspective(fov, aspect, zNear, zFar);

// img = loadImage("img.jpg");
 img = loadImage("house.jpg");
 font = createFont("Serif",12);

}

void draw() {
 background(64);

 if(mousePressed == true) {
   xy[0] = mouseX;
   xy[1] = mouseY;
 }

 drawBox(xy[0], xy[1], bokz, grootte, rotatez, rotatey, rotatex);

 if (enter) {
   drawShape();
 }

 tint(255, 128);
 image(img, 0, 0);

}

void makeFaceGrid(int c0, int c1, int c2, int c3){
 // Set the corners
 gpoint[0][0].x = current_x[c0];
 gpoint[0][0].y = current_y[c0];

 gpoint[0][gridSize].x = current_x[c3];
 gpoint[0][gridSize].y = current_y[c3];

 gpoint[gridSize][gridSize].x = current_x[c2];
 gpoint[gridSize][gridSize].y = current_y[c2];

 gpoint[gridSize][0].x = current_x[c1];
 gpoint[gridSize][0].y = current_y[c1];

 float t = 1.0/gridSize;
 int e , r, c;

 // Calc the 4 grid edges
 for(e = 0; e < gridSize + 1; e++){
   gpoint[e][0].interpolate(gpoint[0][0], gpoint[gridSize][0], e * t);
   gpoint[e][gridSize].interpolate(gpoint[0][gridSize], gpoint[gridSize][gridSize], e * t);

   gpoint[0][e].interpolate(gpoint[0][0], gpoint[0][gridSize], e * t);
   gpoint[gridSize][e].interpolate(gpoint[gridSize][0], gpoint[gridSize][gridSize], e * t);
 }
 // Calc interia
 for(r = 1; r < gridSize; r++){
   for(c = 0; c < gridSize; c++){
     gpoint[c][r].interpolate(gpoint[0][r], gpoint[gridSize][r], c * t);
   }
 }
}

void drawShape() {
 
 makeFaceGrid(3, 7, 4, 0);

 beginShape(QUADS);
 texture(img);

 float delta = grootte/ (float)gridSize;

 for(int r = 0; r < gridSize; r++){
   for(int c = 0; c < gridSize; c++){
     vertex(c * delta, r * delta, gpoint[c][r].x, gpoint[c][r].y);    
     vertex(c * delta, (r+1) * delta, gpoint[c][r+1].x, gpoint[c][r+1].y);  
     vertex((c+1) * delta, (r+1) * delta, gpoint[c+1][r+1].x, gpoint[c+1][r+1].y);
     vertex((c+1) * delta, r * delta, gpoint[c+1][r].x, gpoint[c+1][r].y);
   }
 }
 endShape();
}

void drawBox(float x, float y, float z, int boxsize, float rotz, float roty, float rotx) {
 stroke(255);
 //fill(255, 64);
 noFill();

 pushMatrix();

 translate(x, y, z);
 rotateZ(rotz);
 rotateY(roty);
 rotateX(rotx);

 box(boxsize);

 int n = boxsize/2;

 fill(255);

 translate(0, 0, -n);

 textFont(font);

 text("a, "+screenX(n, n, 0)+", "+screenY(n, n, 0), n, n);

 current_x[0] = screenX(n, n, 0);
 current_y[0] =  screenY(n, n, 0);

 text("b", -n, n);

 current_x[1] = screenX(-n, n, 0);
 current_y[1] =  screenY(-n, n, 0);

 text("c, "+screenX(-n,-n,0)+", "+screenY(-n,-n,0), -n, -n);

 current_x[2] = screenX(-n, -n, 0);
 current_y[2] = screenY(-n,-n,0);

 text("d, "+screenX(n,-n,0)+", "+screenY(n, -n,0), n, -n);

 current_x[3] = screenX(n, -n, 0);
 current_y[3] = screenY(n, -n, 0);

 translate(0,0, n*2); // boxsize

 text("e", n, n);

 current_x[4] = screenX(n, n, 0);
 current_y[4] =  screenY(n, n, 0);

 text("f", -n, n);

 current_x[5] = screenX(-n, n, 0);
 current_y[5] =  screenY(-n, n, 0);

 text("g", -n, -n);

 current_x[6] = screenX(-n, -n, 0);
 current_y[6] =  screenY(-n, -n, 0);

 text("h, "+screenX(n,-n,0)+", "+screenY(n, -n,0), n, -n);

 current_x[7] = screenX(n,-n,0);
 current_y[7] = screenY(n,-n,0);

 popMatrix();
}

void keyPressed() {
 if (key == CODED) {
   if (keyCode == UP) {
     rotatex += PI/180;
   }
   else
     if (keyCode == DOWN) {
     rotatex -= PI/180;
   }
   else
     if (keyCode == LEFT) {
     rotatey -= PI/180;
   }
   else
     if (keyCode == RIGHT) {
     rotatey += PI/180;
   }
   else
     if (keyCode == KeyEvent.VK_PAGE_DOWN) {
     rotatez -= PI/180;
   }
   else
     if (keyCode == KeyEvent.VK_PAGE_UP ) {
     rotatez += PI/180;
   }

 }

 else
   if (key == '=' || key == '+') {
   grootte += 5;
 }
 else
   if (key == '-' || key == '_') {
   grootte -= 5;
 }
 if (key == '[' || key == '{') {
   bokz += 5;
 }
 else
   if (key == ']' || key == '}') {
   bokz -= 5;
 }
 else
   if (key == ',' || key == '<') {
   rotatez -= PI/180;
 }
 else
   if (key == '.' || key == '>') {
   rotatez += PI/180;
 }
 else
   if (key == ENTER || key == RETURN ) {
   enter = true;
 }
}
Re: Vertices+texture glitch?
Reply #9 - Apr 24th, 2009, 11:30pm
 
Wow thanks, I'll look into it shortly. But this effort is greatly appreciated.
Page Index Toggle Pages: 1