#include #include #include #include #define WINDSIZEX 100 #define WINDSIZEY 100 GLfloat *ActualImage; GLint Width = 55, Height = 0; //55; GLfloat *ExpectedImage = NULL; GLfloat *ExpectedSubImage = NULL; GLfloat xTc1, xTc2, xTc3, xTc4; GLfloat yTc1, yTc2, yTc3, yTc4; GLint ImgWidth, ImgHeight; GLint TextureName; long FillImageBuffer( GLint Wid, GLint Hei, GLboolean SubImage ) { GLint i; GLfloat beta; GLfloat Color = 0.0; beta = 1.0 / (GLfloat) (Wid * Hei); if (!SubImage) ExpectedImage = malloc(sizeof(GLfloat) * Wid * Hei * 4); else ExpectedSubImage = malloc(sizeof(GLfloat) * Wid * Hei * 4); for(i = 0; i < (Wid*Hei*4); i+=4) { if( !(SubImage) ) { ExpectedImage[i] = (1.0 - Color)/2.0; ExpectedImage[i+1] = (Color/2.0); ExpectedImage[i+2] = (1.0 - Color); ExpectedImage[i+3] = 1.0; } else { ExpectedSubImage[i] = Color/2.0; ExpectedSubImage[i+1] = (1.0 - Color); ExpectedSubImage[i+2] = (1.0 - Color)/2.0; ExpectedSubImage[i+3] = 1.0; } Color += beta; } return 0; } void init(void) { glDisable(GL_FRAGMENT_PROGRAM_ARB); ActualImage = malloc(sizeof(GLfloat) * 4 * WINDSIZEX * WINDSIZEY); if(ActualImage == NULL) { printf("can not alloc memory for ActualImage\n"); exit(1); } glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } static void draw(GLint Wid, GLint Hei) { glEnable(GL_TEXTURE_RECTANGLE_ARB); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBegin(GL_QUADS); glTexCoord2f(xTc1, yTc1); glVertex2f(0.0, 0.0); glTexCoord2f(xTc2, yTc2); glVertex2f(0.0, (GLfloat)Hei); glTexCoord2f(xTc3, yTc3); glVertex2f((GLfloat)Wid, (GLfloat)Hei); glTexCoord2f(xTc4, yTc4); glVertex2f((GLfloat)Wid, 0.0); glEnd(); glFlush(); glDisable(GL_TEXTURE_RECTANGLE_ARB); } static void first(){ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &TextureName); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, TextureName); ///////////////////////////////////////// xTc1 = 0.0; yTc1 = 0.0; xTc2 = 0.0; yTc2 = Height; xTc3 = Width; yTc3 = Height; xTc4 = Width; yTc4 = 0.0; FillImageBuffer(Width, Height, GL_FALSE); glTexImage2D(GL_PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_FLOAT, NULL); // glTexImage2D call! glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_FLOAT, ExpectedImage); /* draw(Width, Height); //////////////////////////////////////// ImgWidth = Width / 2; ImgHeight = Height / 2; xTc1 = 0.0; yTc1 = 0.0; xTc2 = 0.0; yTc2 = (GLfloat)ImgHeight; xTc3 = (GLfloat)ImgWidth; yTc3 = (GLfloat)ImgHeight; xTc4 = (GLfloat)ImgWidth; yTc4 = 0.0; FillImageBuffer(ImgWidth, ImgHeight, GL_TRUE); glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, ImgWidth, ImgHeight, GL_RGBA, GL_FLOAT, ExpectedSubImage); int i; // Update the Actual Image with the subImage values. for(i = 0; i < ImgHeight; i++) { memcpy(&ExpectedImage[i*Width*4], &ExpectedSubImage[i*ImgWidth*4], sizeof(GLfloat) * ImgWidth * 4); } draw(ImgWidth, ImgHeight); */ } static void test(void){ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_FLOAT, ActualImage); GLint i; GLfloat tolerance = 0.008; for(i = 0; i < (Width * Height * 4); i+=4) { if( fabs(ExpectedImage[i] - ActualImage[i]) > tolerance || fabs(ExpectedImage[i+1] - ActualImage[i+1]) > tolerance || fabs(ExpectedImage[i+2] - ActualImage[i+2]) > tolerance || fabs(ExpectedImage[i+3] - ActualImage[i+3]) > tolerance) { printf("ERROR at %d!\n", i); printf("expected: %f %f %f %f\n", ExpectedImage[i], ExpectedImage[i+1], ExpectedImage[i+2], ExpectedImage[i+3]); printf("actual: %f %f %f %f\n", ActualImage[i], ActualImage[i+1], ActualImage[i+2], ActualImage[i+3]); exit(-1); } } printf("PASS!\n"); exit(0); } void display(void) { glViewport(0, 0, WINDSIZEX, WINDSIZEY); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, WINDSIZEX, 0, WINDSIZEY); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); first(); test(); } int main(int argc, char** argv) { printf("pls check extension GL_ARB_texture_rectangle yourself!\n"); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(WINDSIZEX, WINDSIZEY); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutMainLoop(); return 0; }