I coded it up quickly just to double check and it does indeed work.
Disclaimer: The following code is absolutely horrible and is a proof-of-concept only. Please note that it contains significant risk of divide-by-zero errors. You'll obviously need to replace Array and ImageLoader with your preferred image loading function/library. This code is hardcoded to work with an 8 by 8 BGR texture. Variables v1, v2 and v3 are the positions of the vertices of the triangle. Variables t1, t2 and t3 are the texture coordinates at those vertices.
#include <GL/glut.h>#include <GL/glext.h>#include "Array.h"#include "ImageLoader.h"GLuint texture;void display();void reshape(int width, int height);int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_STENCIL | GLUT_ALPHA); glutInitWindowPosition(0, 0); glutInitWindowSize(640, 480); glutCreateWindow("Texel Position Test"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutIdleFunc(display); Array<unsigned char> texData = ImageLoader::loadImage("texture.bmp"); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (void*)texData.getRawArray()); glEnable(GL_TEXTURE_2D); glPointSize(5); glutMainLoop(); return 0;}void reshape(int width, int height){ GLfloat fovy = width / (float)height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, width, height); gluPerspective(45.0f,fovy,1.0f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}class Point{ public: Point(float mx = 0, float my = 0, float mz = 0) { x = mx; y = my; z = mz; } Point operator-(Point p) const { return Point(x - p.x, y - p.y, z - p.z); } float x, y, z;};Point solve(int x, int y, Point v1, Point v2, Point v3, Point t1, Point t2, Point t3){ float nx = (x + 0.5f) / 8.0f; float ny = (y + 0.5f) / 8.0f; Point vv1 = v2 - v1; Point vv2 = v3 - v1; Point tv1 = t2 - t1; Point tv2 = t3 - t1; float beta = (ny - (t1.y + ((nx * tv1.y) / tv1.x) - ((t1.x * tv1.y) / tv1.x))) / (tv2.y - ((tv2.x * tv1.y) / tv1.x)); float alpha = (nx - (t1.x + (beta * tv2.x))) / tv1.x; Point conf(t1.x + (alpha * tv1.x) + (beta * tv2.x), t1.y + (alpha * tv1.y) + (beta * tv2.y)); return Point(v1.x + (alpha * vv1.x) + (beta * vv2.x), v1.y + (alpha * vv1.y) + (beta * vv2.y), v1.z + (alpha * vv1.z) + (beta * vv2.z));}void display(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0, 0, -50); glBegin(GL_TRIANGLES); glTexCoord2f(0.3, 0.1); glVertex3f(-13, -11, -7); glTexCoord2f(1, 0.2); glVertex3f(5, -12, 0); glTexCoord2f(0.8, 0.8); glVertex3f(11, 12, 6); glEnd(); Point v1(-13, -11, -7); Point v2(5, -12, 0); Point v3(11, 12, 6); Point t1(0.3, 0.1); Point t2(1, 0.2); Point t3(0.8, 0.8); Point point = solve(6, 2, v1, v2, v3, t1, t2, t3); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glColor3f(0, 1, 0); glBegin(GL_POINTS); glVertex3f(point.x, point.y, point.z); glEnd(); glColor3f(1, 1, 1); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glutSwapBuffers();}
Enigma