السلام عليكــم ورحمـة الله وبركاتــه ،،
- الموضوع في الأصل هو إجابة على تساؤل ورد في البريد الالكتروني .. وهو سؤال سهل ولكن لكثرة تكراره .. اضطررت لكتابة هذا الموضوع .
- المطلوب رسم مجموعة من النقاط عن النقر في الماوس وسحبها .. كما هو في برامج التصميم
- هذا المثال , دائماً مايسأل عنه المبتدؤون في هذا المجال .. وهو أحد مواضع الاسئلة في الاختبارات ( -_- )
- في الكليات ( في الغالب) يتم حل هذه المشكلة بأسلوب ركيك .. بغرض تسهيل الحل ..
عندما نقول .. ارسم نقاط عند النقر في على الماوس وسحبها .. سيأتي أحدهم ويضع كود شبيه بهذا ..
void motion(int x,int y)
{
glBegin(GL_POINTS);
glVertex2i( x, y);
glEnd();
}البرنامج سيعمل .. لكن فور اعادة رسم النافذة ( بتصغيرها مثلا .. سيختفي كل شيء ) ولن يبقى الا ماهو موجود في الدالة المسجلة في GLUT الخاصة بالرسم .. في الغالب نسميها display .. اعتدنا على ذلك ..
لذلك لاتقم أبداً بالرسم داخل أي دالة عدا الدالة المخصصة للرسم display , حتى لو رأيت من يقوم بتدريسك يكتبها في مكان آخر .. اعرف أنه اما أنه لايعرف شيء عن مبدأ اعادة الرسم Repaint ، أو أنه يبحث عن تسهيل الحل .
الحل الصحيح :
- أنشئ مصفوفة ( ويفضل استخدام مصفوفة ديناميكية أو استخدم vector للتسهيل ( راجع قسم السي بلس اذا كنت لا تعرف ماهو الـ vector ) .
- عند الضغط على الماوس .. خزن الاحداثيات في المصفوفة .
- بعد انتهاء التخزين في المصفوفة .. قم باستدعاء دالة الرسم display .
- في الدالة display اعمل Loop على المصفوفة وارسم جميع النقاط ذات الاحداثيات المخزنة داخل تلك المصفوفة .. مثال :
#include<windows.h>
#include<gl/glut.h>
#include<vector>
#include <iostream>
bool left_button_down = false;
struct XPoint
{
int x;
int y;
int size;
};
std::vector<XPoint> vec;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
for(int i=0;i<vec.size();i++)
{
glPointSize(vec.size);
glBegin(GL_POINTS);
glVertex2i(vec.x,vec.y);
glEnd();
}
glutSwapBuffers();
}
void motion(int x,int y)
{
if(left_button_down==true)
{
XPoint xp={x,y};
srand(GetTickCount());
xp.size = rand()%10;
vec.push_back(xp);
}
glutPostRedisplay();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,w,h,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int b,int s,int x,int y)
{
if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN)
{
left_button_down = true;
}
else
left_button_down=false;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB );
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
MessageBox(0,"using the mouse ,Click on the left button to draw points","info",MB_OK);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}المثال بالمرفقات .
