PDA

View Full Version : چنتا سوال در مورد opengl



1485159
دوشنبه 05 بهمن 1388, 00:39 صبح
سلام
در opengl در حالت 2 بعدی با این کد:

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0, 0, ClientWidth, ClientHeight);
glOrtho(0,form1.ClientWidth,form1.ClientHeight,0);
میشه هر واحد رو به یک پیکسل نسبت داد! ولی در حالت 3 بعدی نمیتونم!!!
در ضمن با کد بالا در حالت 2 بعدی نقطه 0و0 میشه گوشه چپ و بالا ولی در حالت سه بعدی نمیشه!
میشه یه راهنمایی کنید که 2 عمل بالا رو در حالت 3 بعدی هم برقرار کنم؟ زبانش مهم نیست شما به هر زبانی که دوس داری بنویس.
:lol:
ممنون.

1485159
دوشنبه 05 بهمن 1388, 17:56 عصر
کسی چیزی نمیخواد بگه؟

kochol
سه شنبه 06 بهمن 1388, 20:15 عصر
سلام

من که دقیقا سوالت رو نفهمیدم ولی این کاری رو هم که می گی شدنی نیست و اینکه چه نیازی هم به این کار است رو نمی دونم

1485159
سه شنبه 06 بهمن 1388, 20:32 عصر
من که دقیقا سوالت رو نفهمیدم ولی این کاری رو هم که می گی شدنی نیست و اینکه چه نیازی هم به این کار است رو نمی دونم
سلام
بعد از 2 روز نا امیدی واقعا خوشحال شدم!!!! چرا؟ ببین کی جواب دادی؟:قلب:
منظورم اینه که توی حالت 3 بعدی من اگه بخوام یه مربع در مختصات 50 و 50 و 50 پیکسل رسم کنم، نمیتونم!!
و یا مثلا با جابجا کردن موس مربع هم با موس حرکت کنه...
ممنون.

kochol
چهارشنبه 07 بهمن 1388, 17:13 عصر
سلام
الان سوالت خوب واضح شد.

ببین برای این کار باید ray picking انجام بدی. چون ماوس روی یک محیط 2 بعدی حرکت می کند و محیط تو سه بعدی هست و پس وقتی که کلیک می کنی باید یک خط بسازی که از مکان دوربین تا ته صحنه باشه.

بعد باید این خط رو با یک صفحه برخوردشو حساب کنی.

این کدی هست که یک خط بر اساس ماتریس projection می سازه.


void CalcPickingRay(int x, int y, sn::Camera* pCam)
{
Matrix m = pCam->GetProjectionMatrix();
core::RectI vp = pCam->GetViewPort();
float fx, fy;
fx = (2.0f * x / vp.Width - 1.0f) / m.m_fMat[0];//(vp.Width / 2.0f);//
fy = (-2.0f * y / vp.Height + 1.0f) / m.m_fMat[5];//(vp.Height / -2.0f);//

Position.set(0.0f, 0.0f, 0.0f);
Target.set(fx, fy, 1.0f);
Direction.set(fx, fy, 1.0f);

} // CalcPickingRay


بعد ماتریس view رو می فرستی و این خط رو به فضای دوربین می بری.



void TransformRayInverse(Matrix* mat)
{
mat->Inverse();
mat->TranslateVec(Position);
mat->RotateVec(Target);
mat->TranslateVec(Target);
Direction = Target - Position;
Target = Target + (Direction * 2000.0f);
Direction = Target - Position;

} // TransformRayInverse



این هم کدی هست که برخورد یک خط رو با یک مثلث حساب می کنه می تونی یه صفحه با دو تا مثلث بسازی و مکعبت رو بر روی ان صفحه با حرکت ماوس تکون بدی.

من کد برخورد خط با صفحه رو ننوشتم و بلد هم نیستم ولی راحتتر و سریع تر از برخورد با یک مثلث هست.



//! Checks if the ray and triangle intersects and store the intersection point in the Out parameter.
CollisionType IntersectRay(Ray* pRay, kge::math::Vector& Out)
{
Edge1 = (*Point2) - (*Point1);
Edge2 = (*Point3) - (*Point1);
Normal.Cross(Edge1, Edge2);
float fGama = -(pRay->Direction * Normal);

if (fGama < fEpsilon)
return ECT_NotIntersect;

Vector b = pRay->Position - (*Point1);
float fLanda = (b * Normal) / fGama;

if (fLanda >= 0.0f && fLanda <= 1.0f)
{
Vector u;
u.Cross(b, pRay->Direction);
float u1, u2;
u1 = (Edge2.ToVector() * u) / fGama;
u2 = (-(Edge1.ToVector() * u)) / fGama;
if (u1 + u2 <= 1.0f && u1 >= 0.0f && u2 >= 0.0f)
{
Out = pRay->Position + (pRay->Direction * fLanda);
return ECT_Intersect;
}
}

return ECT_NotIntersect;

} // IntersectRay

1485159
چهارشنبه 07 بهمن 1388, 17:37 عصر
سلام
الان سوالت خوب واضح شد.

ببین برای این کار باید ray picking انجام بدی. چون ماوس روی یک محیط 2 بعدی حرکت می کند و محیط تو سه بعدی هست و پس وقتی که کلیک می کنی باید یک خط بسازی که از مکان دوربین تا ته صحنه باشه.

بعد باید این خط رو با یک صفحه برخوردشو حساب کنی.

این کدی هست که یک خط بر اساس ماتریس projection می سازه.


void CalcPickingRay(int x, int y, sn::Camera* pCam)
{
Matrix m = pCam->GetProjectionMatrix();
core::RectI vp = pCam->GetViewPort();
float fx, fy;
fx = (2.0f * x / vp.Width - 1.0f) / m.m_fMat[0];//(vp.Width / 2.0f);//
fy = (-2.0f * y / vp.Height + 1.0f) / m.m_fMat[5];//(vp.Height / -2.0f);//

Position.set(0.0f, 0.0f, 0.0f);
Target.set(fx, fy, 1.0f);
Direction.set(fx, fy, 1.0f);

} // CalcPickingRay
بعد ماتریس view رو می فرستی و این خط رو به فضای دوربین می بری.



void TransformRayInverse(Matrix* mat)
{
mat->Inverse();
mat->TranslateVec(Position);
mat->RotateVec(Target);
mat->TranslateVec(Target);
Direction = Target - Position;
Target = Target + (Direction * 2000.0f);
Direction = Target - Position;

} // TransformRayInverse

این هم کدی هست که برخورد یک خط رو با یک مثلث حساب می کنه می تونی یه صفحه با دو تا مثلث بسازی و مکعبت رو بر روی ان صفحه با حرکت ماوس تکون بدی.

من کد برخورد خط با صفحه رو ننوشتم و بلد هم نیستم ولی راحتتر و سریع تر از برخورد با یک مثلث هست.



//! Checks if the ray and triangle intersects and store the intersection point in the Out parameter.
CollisionType IntersectRay(Ray* pRay, kge::math::Vector& Out)
{
Edge1 = (*Point2) - (*Point1);
Edge2 = (*Point3) - (*Point1);
Normal.Cross(Edge1, Edge2);
float fGama = -(pRay->Direction * Normal);

if (fGama < fEpsilon)
return ECT_NotIntersect;

Vector b = pRay->Position - (*Point1);
float fLanda = (b * Normal) / fGama;

if (fLanda >= 0.0f && fLanda <= 1.0f)
{
Vector u;
u.Cross(b, pRay->Direction);
float u1, u2;
u1 = (Edge2.ToVector() * u) / fGama;
u2 = (-(Edge1.ToVector() * u)) / fGama;
if (u1 + u2 <= 1.0f && u1 >= 0.0f && u2 >= 0.0f)
{
Out = pRay->Position + (pRay->Direction * fLanda);
return ECT_Intersect;
}
}

return ECT_NotIntersect;

} // IntersectRay

ممنون از جوابتون ولی من نفهمیدم!:افسرده:
اگه شما لطف کنی کدی بزاری که از نقطه 0و0و0یه خط به نقطه 50و50و0 بکشه من خودم بقیشو مینویسم..:لبخند:
ممنون.

kochol
چهارشنبه 07 بهمن 1388, 18:03 عصر
تو دیگه خیلی تنبلی اگه یه نگاهی به پارامتر های ورودی و خروجی بندازی می فهمی که چه طوری کار می کنه.

1485159
پنج شنبه 08 بهمن 1388, 01:28 صبح
چطوری برای یک تسکچر bmp خاصیت TransparentColor رو به وجود بیارم؟
ممنون.

kochol
شنبه 10 بهمن 1388, 17:57 عصر
کاش برای این بخش هم یه مدیر بزارن

این همه پست های چرت و پرت چیه میزنی

تو هنوز نمی دونی هر تاپیک برای یه سوال است

1485159
شنبه 10 بهمن 1388, 18:22 عصر
کاش برای این بخش هم یه مدیر بزارن

این همه پست های چرت و پرت چیه میزنی

تو هنوز نمی دونی هر تاپیک برای یه سوال است
بله حق با شماست!
ممنون.