یکی از دوستان در مورد بافت ها سئوال پرسیده بود و در خواست یک مثال ساده از لود کردن یک فایل bmp توسط سی++ و قرار دادن بعنوان بافت را داشته بود من این کد را زدم که ضمیمه این پست است <br>
برای اینکار ما ابتدا باید فایل را باز کنیم و هدر های فایل را بخونیم و اندازه طول و عرض فایل بیتمپ را بدست بیاریم و بعد از اون بوسیله توابع یک تکسچر ایجاد و مقید کنیم برای توضیحات مفصل تر از لینک های زیر استفاده کنید :
http://nehe.gamedev.net/tutorial/texture_mapping/12038/
http://www.opengl-tutorial.org/begin...textured-cube/
#include <iostream>
#include <GL/gl.h> //سر فایل که هسته اپن جی ال را به برنامه اضافه می کند
#include <GL/glut.h>//سر فایل برای اضافه کردن توابع مورد نیاز ایجاد پنجره
GLfloat angle = 0.0;// برای چرخش مکعب ااین متغیر استفاده می کنیم ز
GLuint textureID; // ایجاد یک متغیر برای ایجاد شناسه برای بافت
GLuint loadBMP_custom(const char * imagepath){// تابع ساده برای لود کردن تصاویر بیتمپ از نوع 24 بیتی
// خواندن اطلاعات هدر فایل بیتمپ
unsigned char header[54]; // هر فایل بیتمپ با 54 بایت هدر شروع می شود که در این متغیر ذخیره می شود
unsigned int dataPos; // نگهداری موقعیت ما در فایل که تا کجا خوانده شده
unsigned int width, height;// متغیر برای ذخیره کردن طول و عرض بیتمپ
unsigned int imageSize; // = width*height*3 اندازه کلی تصویر برابر است با طول در عرض در 3 که شامل 3 مقدار رنگی است
// داده های واقعی بیتمپ در این متغیر ذخیره می شوند
unsigned char * data;
// باز کردن فایل
FILE * file = fopen(imagepath,"rb");//آدرس از ورودی تابع اصلی گرفته می شود
if (!file) {printf("Image could not be opened\n"); return 0;}
if ( fread(header, 1, 54, file)!=54 ){ // اگر 54 بایت هدر نداریم پس یک مشکل وجود دارد
printf("Not a correct BMP file\n");
return 0;
}
//هر فایل بیتمپ با این دو حرف شروع می شود
if ( header[0]!='B' || header[1]!='M' ){
printf("Not a correct BMP file\n");
return 0;
}
// گرفتن اطلاعات از هدری که قبلاً خوانده شده
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
// بعضی فایل های بیتمپ درست قالب بندی نشده اسند
if (imageSize==0) imageSize=width*height*3;
if (dataPos==0) dataPos=54; // گذر از هدر فایل بیتمپ
// ساخت یک بافر
data = new unsigned char [imageSize];
// خواندن داده های واقعی از فایل به داخل بافر
fread(data,1,imageSize,file);
//همه چیز در حافظه است الان می تونیم فایل را ببندیم
fclose(file);
//بیتمپ ها با فرمت بی جی آر ذخیره می شوند
//است که باید به آرایش ار جی بی تبدیل شود.
//BGR 2 RGB
for (int i = 0; i < imageSize; i+=3)
{
char c = data[i];
data[i] = data[i+2];
data[i+2] = c;
}
glGenTextures(1, &textureID); // ساخت یک بافت اپن جی ال
glBindTexture(GL_TEXTURE_2D, textureID);// مقید سازی بافت ساخته شده جدید تمام توابع بعدی این بافت را تغییر می دهند
// دادن تصویر به اپن جی ال
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR); // فیلتر سازی خطی
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
}
void init (void) {
loadBMP_custom("NeHe.bmp"); // لود کردن تصویر از آدرس داده شده
glEnable(GL_TEXTURE_2D); // فعال کردن نگاشت بافت دو بعدی
glShadeModel(GL_SMOOTH); // فعال کردن نرم کننده
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // مشخص کردن رنگ بک گراند
glClearDepth(1.0f); // فعال کردن بافر عمق
glEnable(GL_DEPTH_TEST); // فعال کردن تست عمق
glDepthFunc(GL_LEQUAL); // مشخص کردن نوع تست عمق
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // ساخت پرسپکتیو
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // فعال کردن بلندینگ و مشخص کردن نوع ان
glEnable(GL_BLEND);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// پاک کردن بافر
glLoadIdentity(); // لود ماتریس همانی یا 1
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);//مشخص کردن موقعیت دوربین
glRotatef(angle, 1.0, 0.0, 0.0);//چرخش با زاویه آنگل
glRotatef(angle, 0.0, 1.0, 0.0);//چرخش با زاویه آنگل
glRotatef(angle, 0.0, 0.0, 1.0);//چرخش با زاویه آنگل
glBegin(GL_QUADS);
/*برای نگاشت صحیح یک بافت روی مکعب , شما باید مطمئن شوید که بالا سمت راست بافت به بالا سمت راست مکعب نگاشت میشود و به همین ترتیب گوشه های دیگر اگر گوشه ها با یکدیگر مچ نشوند ممکن است تصویری نمایش داده نشود یا تصویر بر عکس شود ویا...
اولین glTexCoord2f روی محور ایکس سمت چپ است 0.5f وسط بافت و 1.0f سمت راست بافت است .
بنابراین حالا ما می دانیم که گوشه بالا سمت چپ با 0.0f در محور x و 1.0f برای محور y در بافت و بالا سمت چپ مکعب دارای مختصات -1.0f برای x و 1.0f برای محور y است و به همین ترتیب تا آخر*/
glTexCoord2f(0.0f, 0.0f); //مشخص کردن مختصات بافت
glVertex3f(-1.0f, -1.0f, 1.0f);//مشخص کردن رأس اول مکعب
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glutSwapBuffers();
angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
init ();
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutMainLoop ();
return 0;
}