الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تخزين بيكسالات مجسم 3d مرسوم بال opegl

بدأه hbate_allah في 9 يونيو 2010 · 20 رد · 1,986 مشاهدة · في OpenGL
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

لدي سؤال غريب شوي لا ادري هل انا التي لم اعرف صياغته او ان فكرتي ليست صحيحة ام انه غريب حقا

المهم

لدي كود رسم اسطوانة بالopengl

 void drawCylinder(double r,double height)
{
    double x=0,y=0;
    double pre=height/20;
    glPointSize(1);
    glBegin(GL_POINTS);
    for(double z=0;z<=height;z+=pre)
    {
        for(double t=0;t<=PI;t+=PI/20)
        {
            x=r*cos(t);
            y=r*sin(t);
            glVertex3d(x,z-height/2,y);
        }
    }
    glEnd();
    glLoadIdentity();
}

ما اريده هو انني لا ارسم الاسطوانة في الوقت الحالي اي في المكان الذي ناديت فيه هذا الكود انما اريد ان استخدم بيكسالات الاسطوانة فقط

اي ان اخزن بيكسالات الاسطوانة لاستخدامها فيما بعد اما رسمها فسيكون في مكان اخر

هل يمكنني ذلك ؟

#2

و عليكم السلام ورحمة الله

لا يوجد شيئ إسمه تخزين بكسلات الأسطوانة، لأن الأسطوانة ليست صورة Bitmap من أجل تخزين بكسلاتها. لكن الأسطوانة عبارة عن شكل هندسي و لرسم أي شكل هندسي نحن بحاجة إلى معادلة أو متغيرات تصف هذا الشكل.

لرسم الأسطوانة هنالك عدة متغيرات هي: إرتفاع الأسطوانة ، نصف قطر الإسطوانة. height و r حسب الكود السابق.

إذا قمت بتخزين هاتين القيمتين فقط سوف يكون بإمكانك وضع الكود الذي يقوم برسم الأسطوانة و من ثم رسمها في أي مكان و أي وقت.

الملخص لتخزين معلومات الأسطوانة و رسمها لاحقا، يلزم فقط متغيريين أحدهما يمثل إرتفاع الأسطوانة و الثاني يمثل نصف قطر الأسطوانة

تم تعديل هذه المشاركة بواسطة *خلدون خالد* في 9 يونيو 2010 في 20:25

1
#3

السلام عليكم

اقتباس
الملخص لتخزين معلومات الأسطوانة و رسمها لاحقا، يلزم فقط متغيريين أحدهما يمثل إرتفاع الأسطوانة و الثاني يمثل نصف قطر الأسطوانة

لكن عندما نريد ان نستخدم جميع البيكسالات اللي في الاسطوانة اكيد هالبيكسالات عندها x,y,z

يعني كيف اعرف احدتيات جميع البيكسالات

لانه height وr ما يبينونا الاحداثيات

#4
اقتباس
يعني كيف اعرف احدتيات جميع البيكسالات

لانه height وr ما يبينونا الاحداثيات

يتم حساب قيم ال x,y,z من خلال المعادلة الخاصة بالأسطوانة. حيث يتم إستخدام Loop من أجل حساب القيم مثلا.

كما هو في الكود التالي.

for(double z=0;z<=height;z+=pre)
{
	for(double t=0;t<=PI;t+=PI/20)
	{
		x=r*cos(t);
		y=r*sin(t);
		z=z;
	}
}

لاحظي أنه من خلال الكود يتم حساب قيمة X و Y و Z

#5

لقد فهمت الان شكرا لك

لكن لم افهم هذه

اقتباس
يتم إستخدام Loop

كيف هذا

كما انني لاحظت انك اضفت

 z=z

اي Z تقصد

فاانا ابحث عن هذه الاحداثية منذ وقت

قرات انني اجدها من البعد بين الاسطوانة و الكاميرا

لكن لم اعرف كيف

لاني لم دخل احداثيات الكاميرا

هل هذا يعني انني يجب ان ادخ glulookAt او ما شبه و يعني انني اعمل للاسطوانة glperspective بدل glOrtho اللي كنت استخدمها

#6

وضع z=z فقط من باب التوضيح (لا معنى لها عمليا)

ولكن كيف يتم الحصول على قيم Z؟؟ يتم ذلك من خلال ال Loop الواضح في الكود، الذي يبدأ صفر و ينتهي بإرتفاع الأسطوانة. أي أن قيم z أنت من يقوم بفرضها.

لتوضيح الموضوع بعض الشيئ، لرسم أي منحنى رياضي يكون لدينا معادلة y=x*x مثلا، و من ثم نقوم بأخذ قيم ثابته للمتغير x. مثلا x=0، x=1, x=2 , x=3 ... وبعدها نقوم بحساب قيم y بناء على المعادلة، ومن ثم نقوم برسم المنحنى حسب x و y المقابلة لها.

نفس المبدأ ينطبق هنا، فأنت تقوم بوضع قيم ثابته ل z من خلال التكرار. و من ثم تقوم بحساب قيم x و y بناء على معادلة الأسطوانة. و من ثم تقوم بالرسم من خلال أمر glVertex3d

أرجو أن يكون الأمر قد توضح

#7

اريد ان اعرف الان هل اذا حركنا الاسطوانة او قمنا بتدويره

(نضرب احداثيات جميع بيكسالات الاسطوانة في مصفوفة

543138178.jpg

كيف استطيع القيام بهذا ؟ هل يجب ان اضرب احداثية احداثية ثم ارسم ام توجد فانكشن تقوم بالامر و تعيد لي الرسم في المكان الجديد؟ و هل هنا يجب ان اعيد نداء الدالة

for(double z=0;z<=height;z+=pre)
{
        for(double t=0;t<=PI;t+=PI/20)
        {
                x=r*cos(t);
                y=r*sin(t);
                z=z;
        }
}

او هل يكفي اننا نقوم بالرسم فقط

و هنا بالتاكيد راح يتغير z

كما راح تتغير الزاوية بين الاسطوانة و وجميع المحاور

تم تعديل هذه المشاركة بواسطة hbate_allah في 9 يونيو 2010 في 22:24

#8

في هذه الحالة سوف يتوجب عليك فعلا تخزين قيم رؤوس الشكل المطلوب في مصفوفة ثنائية الأبعاد مثلا، و من ثم يتم تنفيذ عملية التحويل المطلوبة و من ثم إعادة الرسم:

double cyl[100][3];
c=0;
for(double z=0;z<=height;z+=pre)
{
        for(double t=0;t<=PI;t+=PI/20)
        {
                x=r*cos(t);
                y=r*sin(t);
				cyl[c][0]=x;
				cyl[c][1]=y;
				cyl[c][2]=z;
				c++;
        }
}

=============

أو الحل الذي يعتمد على التوضيح الذي وضعته في الردود السابقة، بالإمكان تمثيل موقع الأسطوانة بنقطة لها ثلاث قيم x,y,z. و من ثم يتم تنفيذ عميلة التحويل هذه النقطة و إعادة الرسم بإستخدام نفس الطريقة السابقة مع تعديل بسيط بحيث يتم أخذ موقع الشكل في عين الأعتبار، سيكون الكود شيئ شبيه بالتالي:

for(double z=0;z<=height;z+=pre)
    {
        for(double t=0;t<=PI;t+=PI/20)
        {
            x=r*cos(t);
            y=r*sin(t);
            glVertex3d(x+cx,(z-height/2)+cz,y+cy);
        }
    }

حيث ال cx,cy,cz يمثلان موقع الشكل.

ملاحظة أخيرة،

الكلام المذكور بشكل عام، إذا أردت شيئا خاصا بال OpenGL فعليك بالقراءه عن التحويلات Transformations في ال OpenGL للحصول على معلومات أكثر تفصيلا.

/index.php?showtopic=83823

والله أعلم

1
#9

السلام عليكم

شكرا لك اخي خلدون لقد افدتني جبيدا

اظن انني ساعمل بالكود الاول فهذا ما كنت اريده خصوصا اني كنت راح اسال كيف اعطي الاسطوانة ك parameter لفانكشن

لاني احتاج هذا

و اظن ان الطريقة الاولى توفر لي هذا بانها تضع احداثيات البيكسالات في مصفوفة

تم تعديل هذه المشاركة بواسطة hbate_allah في 9 يونيو 2010 في 23:54

#10
اقتباس
في هذه الحالة سوف يتوجب عليك فعلا تخزين قيم رؤوس الشكل المطلوب في مصفوفة ثنائية الأبعاد مثلا، و من ثم يتم تنفيذ عملية التحويل المطلوبة و من ثم إعادة الرسم:

+1

اقتباس
و اظن ان الطريقة الاولى توفر لي هذا بانها تضع احداثيات البيكسالات في مصفوفة

كما ذكر الاخ خلدون ، أنت لا تتعاملين مع بيكسلات .. إنما رؤوس vertex / vertices .

فقط أريد إضافة شيء وهو أنه من الأفضل أن يتم تخزين رؤوس الشكل في مصفوفة أو كائن Object ، بحيث يمكن لاحقاً رسمه عن طريق Vertex Arrays ، في OpenGL ، يوجد شيء اسمه Vertex Arrays بحيث :

1- يتم تخزين الرؤوس في مصفوفة أو Object أو std:vector أو أي شيء ..

2- يمكن في أي لحظة أن تتعاملي مع المصفوفة للحصول على قيم رؤوس الشكل ، والقيام بأي حسابات تريدين ،

3- الرسم يتم باستدعاء دالة واحدة ، بدلاً من عمل loop والرسم باستخدام glBegin و glEnd .

يوجد في فهرس القسم ، مقال قديم يتكلم عن هذا .

/index.php?showtopic=118017&hl=Vertex+array

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#11

السلام عليكم

لقد قرات الشرح في الملف اخي الشمري و حاولت التطبيق مع اسطوانتي

لكني لم استطع ان املا المصفوفة في حالتي

فمثلا في مثالك هنا

glBegin(GL_POINTS );
glVertex3fv ( -0.3, 0,0 );
glVertex3fv ( 0,0.3,0 );
glVertex3fv ( 0.3,0,0 );
glEnd();

من ثم وضعتهم في المصفوفة

 GLfloat vertex [] ={ -0.3,0,0 , 0,0.3,0 , 0.3,0,0};

يعني انت من البداية حطيت ارقام

حاولت احطها في الحلقة for اللي في وسط دالتي بس ما نجحت

  GLdouble cyl[100][3];
 GLuint d[100];
void drawCylinder(double r,double height)
{
    double x=0,y=0;
    double pre=height/20;
   // glPointSize(1);
//    glBegin(GL_POINTS);

int c=0;
for(double z=0;z<=height;z+=pre)
{
        for(double t=0;t<=PI;t+=PI/20)
        {
                x=r*cos(t);
                y=r*sin(t);
                                cyl[c][0]=x;
                                cyl[c][1]=y;
                                cyl[c][2]=z;
								d[c]=c;
                                c++;
        }
}
        }

void Render()
	{

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();
	glTranslatef(0,0,-6);

	glEnableClientState (GL_VERTEX_ARRAY);

	glVertexPointer(3 ,GL_DOUBLE,0,&/*vertex[0]*/cyl[0]);

drawCylinder(5,10);
glDrawElements(GL_POINTS, 4, GL_UNSIGNED_INT, &d[0]);



	glutSwapBuffers();
}

void changeSize(int w, int h) {


	if(h == 0)
		h = 1;

	float ratio = 1.0* w / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);
	gluPerspective(45,ratio,1,1000);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

}




void processNormalKeys(unsigned char key, int x, int y) {

	if (key == 27) 
		_exit(0);

}


void main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(400,400);
	glutCreateWindow("Vertex Arrays");
	glutDisplayFunc(Render);
//	glutIdleFunc(Render);
	glutReshapeFunc(changeSize);
	glutKeyboardFunc(processNormalKeys);
	glutMainLoop();
}

لكن ما ضبطت معي

ارى نقطة واحجة و ثم تاتيني راسلة خطا

تم تعديل هذه المشاركة بواسطة hbate_allah في 10 يونيو 2010 في 07:21

#12

يبدو المشكلة أن حجم المصفوفة لايكفي ، لذلك من الأفضل تكبير حجم المصفوفة حتى الانتهاء من التجارب ثم كتابة كود أفضل :

double cyl[1000][3];
double d[1000];

من الأفضل الاستعانة بـ std::vector أو أي كائن يسمح بإنشاء مصفوفة ديناميكية لتلافي مشاكل الحجز و الذاكرة .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#13

السلام عليكم

لقد استعنت بفيكتور لكن لم يعمل اذا ليس هناك اخطاء

#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include<math.h>
#include <vector>
using namespace std;
#include<stdlib.h>
#include<gl/glut.h>

#define PI       3.14159265358979323846


/*--------------------------------/
|Name : Render
|Aim : Draw Polygons using vertex arrays ...
|  
|    IMPORTANT-IMPORTANT-IMPORTANT
|
/--------------------------------*/

//GLfloat vertex[]={ 1,1,0 , 0,0,0 , -1,-1,0 , 1,-1,0}; 
// GLdouble cyl[100][3];
struct vertex

{

    double x,y,z;

};

 vector< GLuint> d;
 vector<vertex> vertexe;
 vertex v1;

void drawCylinder(double r,double height)
{
	int nbvertex=0;
    double x=0,y=0;
    double pre=height/20;
   // glPointSize(1);
//    glBegin(GL_POINTS);

int c=0;
for(double z=0;z<=height;z+=pre)
{
        for(double t=0;t<=PI;t+=PI/20)
        {
                x=r*cos(t);
                y=r*sin(t);
                               				v1.x=x;
				v1.y=y;
				v1.z=z;
				vertexe.resize(vertexe.size()+1);

			vertexe[vertexe.size()-1]=v1;
                 d.resize(d.size()+1);

				d[d.size()-1]=nbvertex;
				nbvertex++;


        }
}
        }

void Render()
	{

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();
	glTranslatef(0,0,-6);

	glEnableClientState (GL_VERTEX_ARRAY);

	glVertexPointer(3 ,GL_DOUBLE,0,&/*vertex[0]*/vertexe[0]);

drawCylinder(5,10);
glDrawElements(GL_POINTS, 4, GL_UNSIGNED_INT, &d[0]);



	glutSwapBuffers();
}

void changeSize(int w, int h) {


	if(h == 0)
		h = 1;

	float ratio = 1.0* w / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);
	gluPerspective(45,ratio,1,1000);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

}




void processNormalKeys(unsigned char key, int x, int y) {

	if (key == 27) 
		_exit(0);

}


void main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(400,400);
	glutCreateWindow("Vertex Arrays");
	glutDisplayFunc(Render);
//	glutIdleFunc(Render);
	glutReshapeFunc(changeSize);
	glutKeyboardFunc(processNormalKeys);
	glutMainLoop();
}

تم تعديل هذه المشاركة بواسطة hbate_allah في 10 يونيو 2010 في 10:41

#14

- في std::vector استخدمي الدالة push_back ، بدلاً من ان تعيدي حجز الذاكرة كل مرة ..

- بالنسبة للدالة glVertexPointer ، أهم شيء البارمتر الثالث والذي يعني ( حسب ما اذكر ) ، عدد البايتات من من آخر عنصر تم رسمه إلى العنصر التالي في المصفوفة ، أو الوعاء الذي يحمل البيانات ..

عموماً ، هذا الكود بعد التعديل وقد جربته وهو يعمل :

#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include<math.h>
#include <vector>
using namespace std;
#include<stdlib.h>
#include<gl/glut.h>

#define PI 	3.14159265358979323846


/*--------------------------------/
|Name : Render
|Aim : Draw Polygons using vertex arrays ...
| 
|	IMPORTANT-IMPORTANT-IMPORTANT
|
/--------------------------------*/

struct Vertex
{
	float x,y,z;
};

vector<GLuint> indexList;
vector<Vertex> vertexList;

void drawCylinder(double r,double height)
{
	int nbvertex=0;
	double x=0,y=0;
	double pre=height/20;
	int c=0;
	for(double z=0;z<=height;z+=pre)
	{
		for(double t=0;t<=PI;t+=PI/20)
		{
			x=r*cos(t);
			y=r*sin(t);
			Vertex v1;
			v1.x=x;
			v1.y=y;
			v1.z=z;
			vertexList.push_back(v1);
			indexList.push_back(nbvertex);
			nbvertex++;
		}
	}
}




void Render()
{
	drawCylinder(2,5);
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();
	glTranslatef(0,0,-26);
	glRotatef(45.0f,1,1,1);
	glEnableClientState (GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, &vertexList[0]);
	glDrawElements(GL_POINTS, indexList.size(), GL_UNSIGNED_INT, &indexList[0]);
	glutSwapBuffers();
}

void changeSize(int w, int h) {


	if(h == 0)
		h = 1;

	float ratio = 1.0* w / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);
	gluPerspective(45,ratio,0.1,1000);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

}




void processNormalKeys(unsigned char key, int x, int y) {

	if (key == 27) 
		_exit(0);

}


void main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(400,400);
	glutCreateWindow("Vertex Arrays");
	glutDisplayFunc(Render);
	glutReshapeFunc(changeSize);
	glutKeyboardFunc(processNormalKeys);
	glutMainLoop();
}

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#15

السلام عليكم

شكرا لك اخي الشمري المثال يعمل :lol:

بقي لدي سؤال واحد

لقد قرات عن focal length of camera

هل تعرف ما هو ؟

كما اريد ان اسالك عن كيفية ايجاد المسافة بين الكاميرا والصورة (او بكسالات الصورة)

كنت اعتقد في البداية انني انا التي احدده هل صحيح ما اعتقده؟ :P

و زوايا دوران هذه الاسطوانة بالنسبة ل x و y و z

هل نتحصل عليهم من glrotatef

اعرف انكم مليتم من اسالتي :P

بس باقيلي سؤال واحد

الان عندما حفظت رؤؤس الاسطوانة و اردت ان اضربها في المصفوفة التي ارفقتها في الصفحة الاولى و التي بها تتغير قيم الازاحة و الدوران

هل قيمة glrotatef ,gltranslatef راح تتغير اتوماتيكيا ام اني لازم اغيرها

تم تعديل هذه المشاركة بواسطة hbate_allah في 10 يونيو 2010 في 15:58

#16

وعليكم السلام .

ليست مشكلة الأسئلة أنها كثيرة :-) ولكن بعضها غير واضح .

اقتباس
لقد قرات عن focal length of camera

هل تعرف ما هو ؟

لا ، لا أعرف عنه شيء ..

اقتباس
كما اريد ان اسالك عن كيفية ايجاد المسافة بين الكاميرا والصورة (او بكسالات الصورة)

هل تقصدين الصورة أو الـVertex المرسوم ؟

في OpenGL لانهتم أبداً بالصورة الا في مراحل أخيرة ، نحن دائماً نتكلم عن رؤوس Vertex ..

عموماً لا اذكر الكثير عن هذا الموضوع فأنا منقطع من فترة طويلة عن هذا المجال .

اقتباس
بس باقيلي سؤال واحد

الان عندما حفظت رؤؤس الاسطوانة و اردت ان اضربها في المصفوفة التي ارفقتها في الصفحة الاولى و التي بها تتغير قيم الازاحة و الدوران

هل قيمة glrotatef ,gltranslatef راح تتغير اتوماتيكيا ام اني لازم اغيرها

خلاص ، بما أنك ضربتيها فلاداعي لعمل ذلك مرة أخرى ،

في OpenGL هناك دالة تغنينا عن translate و rotate التي تقدمهما OpenGL ، الدالة باسم glLoadMatrix ،

يمكنك اجراء عملية ضرب مصفوفة الازاحة بمصفوفة الدوران - أو أي مصفوفة مهما كان نوعها ( الضرب من اليمين لليسار في OpenGL ) ، ومن ثم تحميل المصفوفة في OpenGL باستخدام الدالة glLoadMatrix ، لأن glTranslate وأختها Rotate ، تقومان بهذه المهمة نيابة عنك .. ويمكن تجاهلهما .

بقي نقطة أخرى ،

عندما تريدين تحريك الكاميرا ، فإنه من الأفضل أن تتخيلي أو لنقول توجدي مصفوفة مسؤولة عن View ، والتي لها عملياتها .. مثل ازاحة الكاميرا أو تدويرها ..

وعندما تريدين تحريك شكل معين ، فإنه من الأفضل اجراء عمليات ضرب لمصفوفات ومن ثم تخزين الناتج في مصفوفة Model .. ( لاحظي .. كل شكل له مصفوفة ، الاسطوانة لها مصفوفة مستقلة ) .

وأخيراً يتم ضرب المصفوفتين View و Model ، ويجب الاخذ بالاعتبار اتجاه الضرب ،

الناتج يتم تحميله باستخدام glLoadMatrix ويجب التأكد أن glMatrixMode تشير إلى GL_MODELVIEW .

طبعاً يمكن الاستغناء عن gluPerspective بنفس الطريقة لأنها تنتج مصفوفة من نوع مصفوفة الاسقاط Projection ، ولكن لاداعي لهذه العملية .. فـ OpenGL بتحسبها وتضربها بمصفوفة ModelView .

اقتباس
و زوايا دوران هذه الاسطوانة بالنسبة ل x و y و z

هل نتحصل عليهم من glrotatef

لا أعلم بصراحة كيف نحسب زاوية الدوران الحالية ( لا أعلم مافائدة ذلك أصلاً ) ، ولكن الحل الذي أتخيله هو حساب زاوية الدوران الحالية حول المحور ( 60 درجة مثلاً ) ناقص زاوية الدوران الأصلية للشكل .. ولو فرضنا أن الشكل بدأ رسمه ودرجة ميلانه صفر .. فان زاوية الدوران الحالية == 60 .

طبعاً السطرين السابقين مجرد هلوسة وحديث مع النفس .. قد يكون كلام خاطئ :-) .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#17

شكرا لك اخي الشمري راح اقرا بتمعن ما قلته لي

#18

ماهو الاسرع vertex array او VBO او glList ؟ . اكيد VBO و الاضعف هو glvertex , لكن بعض بطاقات العرض لا تدعم VBO

vertex array يستخدم DMA للوصول الى الرؤوس المخزنة في RAM . بينما GLList يخزن الرؤس في VRAM

vertex array يتيح تعديل الرؤس في الوقت الفعلي real time بينما glList لايستطيع لكنه اسرع في rendering

.

#19
اقتباس
لقد قرات عن focal length of camera

هل تعرف ما هو ؟

قرات عنه انه يستعمل للتحصل على coordonate النقطة

مثلا اذا كانت لدينا نقط u و احداثياتها في 3d هي [x,y,z] عندما نعمل لها اسقاط perspective اي اننا سننتقل الى 2d

للتحصل على احداثيات النقطة u في ال 2d التي هي [x',y']

[x',y']=[x,y] * f/z

الان بمان انك لم تسمع بهذا f بصراحة الاكثرية لا يعلمون ما هو

كيف سنتحصل على [x',y'] بدون الطريقة السابقة

#20

السلام عليكم

و زوايا دوران هذه الاسطوانة بالنسبة ل x و y و z
هل نتحصل عليهم من glrotatef
.

بالطبع لا و لكن من جهة أخرى عن طريق الدالة glGetFloatv

GLdouble matrix[16];
        glTranslated(-2.4,1.2,-6);
        glRotatef(60,0.,0.,1.);
.......
/* وتحويلات أخرى*/
......
glGetFloatv( GL_MODELVIEW_MATRIX ,matrix);

يتم تخزين بيانات التحويل الحالي في المصفوفة matrix

الخانات 12و13و14 للتحويل translate

الخانات 0و5و10 للتحجيم

الخانات0و1و2و4 و5و6و9و8و10

إليك هده الشيفرة

static void display(void)
{
    const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
    const double a = t*90.0;
float matrix[16];

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0,0);

    glPushMatrix();
        glTranslated(-2.4,1.2,-6);

        glRotatef(60,0.,0.,1.);
        glGetFloatv( GL_MODELVIEW_MATRIX ,matrix);
        /*translation*/
        printf("x_Translate=%f  ",matrix[12]);
        printf("y_Translate=%f  ",matrix[13]);
        printf("z_Translate=%f\n\n\n",matrix[14]);
        /*scale*/
        printf("x_Scale=%f  ",matrix[0]);
        printf("y_Scale=%f  ",matrix[5]);
        printf("z_Scale=%f\n\n\n",matrix[10]);
        /*rotation by x*/
        printf("X_Rotate=%f  ",matrix[5]);
        printf("X_Rotate=%f  ",matrix[6]);
        printf("X_Rotate=%f  ",matrix[9]);
        printf("X_Rotate=%f\n\n\n",matrix[10]);
        /*rotation by y*/
        printf("y_Rotate=%f  ",matrix[0]);
        printf("y_Rotate=%f  ",matrix[2]);
        printf("y_Rotate=%f  ",matrix[8]);
        printf("y_Rotate=%f\n\n\n",matrix[10]);
        /*rotation by z*/
        printf("z_Rotate=%f  ",matrix[0]);
        printf("z_Rotate=%f  ",matrix[1]);
        printf("z_Rotate=%f  ",matrix[4]);
        printf("z_Rotate=%f\n\n\n",matrix[5]);


    glPopMatrix();

    glPushMatrix();

        glTranslated(matrix[3], matrix[7], matrix[11]);
        glTranslated(-2.4,1.2,-6);
        glRotated(a,0,0,1);
        glutSolidSphere(1,slices,stacks);
    glPopMatrix();


    glutSwapBuffers();
}

و لكن إدا ما غيرت التحويل x و y و z معا سيكون الناتج مختلف عما في الشيفرة السابقة و شرحها طويل

لدا أنصح بقراءة كتاب 3d game engine design لكثير من المعرفة ستجد فيه أغلب الأسس الخاصة بالتحريك و التصادم و وو.

تم تعديل هذه المشاركة بواسطة 3ds max2010 في 16 يونيو 2010 في 22:18

تخيل, هل سيكون مستقبل الأوبن جي أل مع البشرية هكذا

future.jpg
#21

شكرا لك اخي

انا الان اقوم بتحميل الكتاب

و ساقراه

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…