ورود

View Full Version : رسم 40 هزار خط



dorche
چهارشنبه 12 آبان 1389, 21:55 عصر
می خواستم دوستان OPENGL و ِDirectX یک تستی انجام دهند

من برای نمایش 40 هزار خط به مشکل برخوردم

در GDI+ کار کردم که وقتی می خواهم 40 هزار خط را که هر کدام با مختصات های مخصوص به خود و جدا از هم هستند رسم کنم برنامه کند کار می کند و دیگر کارایی لازم را ندارد

من خودم یه مقدمه از OpenGL خوندم و یه برنامه نوشتم نتیجه بدتر شد و مطمئن هستم از کد نویسی بد خودم بوده چون در زمینه OpenGL تخصص نداشتم

از دوستان OpenGL کار و DirectX کار میخواستم یه تست انجام دهند که من مسیر حرکتم یعنی تصمیم انتخاب OpenGL یا DirectX رو بگیرم و همچنین از نحوه صحیح کد نویسی در زمینه گرافیک آشنا شوم

برای هماهنگی هر کسی که می خواد تست کنه 40 هزار خط رندم رو در برنامه لود کنه
در ضمن برای تست سرعت رسم امکان جابجایی اشکال با صفحه کلید یا موس را قرار دهید با هر کدو باشه هیچ فرقی نمی کنه

amin1softco
جمعه 14 آبان 1389, 13:58 عصر
#include <windows.h>
#include <TIME.h>
#include <GL/glut.h>


typedef unsigned short word;
word *my_clock=(word *)0x0000046C; /* this points to the 18.2hz system
clock. */

void line_draw(int x1, int y1, int x2, int y2)
{
glColor3f((rand()%100)/0.10, 0.100,(rand()%100)/0.10); //line colour set to blue
glBegin(GL_LINES);
glVertex2i(x1,y1); glVertex2i(x2,y2); //line seg1
glEnd();
}
void init(void) //???? ????? ???????
{
glClearColor(1.0,1.0,1.0,0.0); //display window set to white ????? ?? ????? ?? ??? ????
glMatrixMode(GL_PROJECTION); //projection parameters ????? ????? ????
gluOrtho2D(0.0,200.0,0.0,150.0); //sets up WC extent ?? ???? ?? ?????? ??????
}
void lineSegments(void) // ???? ????? ?? ??
{
glClear(GL_COLOR_BUFFER_BIT); //clears display window ??? ???? ???? ?????
int x1,y1,x2,y2,color;
float t1;
word i,start;

srand(time(NULL)); /* seed the number generator. */
//start=*my_clock; /* record the starting time. */
for(i=0;i<40000;i++) /* randomly draw 5000 lines. */
{
x1=rand()%100;
y1=rand()%50;
x2=rand()%100;
y2=rand()%50;
line_draw(x1+10,y1+10,x2+50,y2+50);
}

// t1=(*my_clock-start)/18.2; /* calculate how long it took. */


//printf("line drawing took %f seconds.\n",t1);

glFlush(); //process all OGL functions immediately ???? ?? ???? ????
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //initialise GLUT
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100); //top left display window pos
glutInitWindowSize(400, 300); //display win width and height in pixel coords
glutCreateWindow(" lines"); //now create display win
init(); //run initilization procs
glutDisplayFunc(lineSegments); //call drawing func
glutMainLoop(); //display all and wait
return 0;
}

dorche
سه شنبه 18 آبان 1389, 11:03 صبح
خیلی ممنون از کدتون

کد دوستمون amin1softco کدی بسیار عالیست (البته دوستان OpenGL باید در مورد اون نظر بدهند)

دوست عزیز اگه میشه کد رو به شکل زیر تغییر دهید :

یک آرایه برای X و یکی برای Y در نظر بگیرید و در ابتدای برنامه این دو آرایه را با اعداد رندم پر کنید که برای هر بار رسم خط ها مقدار آنها محاسبه نشود دلیل این کار هم اینه که فقط زمان رسم خط ها رو بتونیم با هم مقایسه بکنیم

اگه دوستان عدد چهل هزار رو به چهار هزار تغییر بدهند و برنامه رو اجرا بکنند می بینند که رسم چهار هزار خط چقدر طول میکشه چه برسه به چهل هزار خط که مشکل اصلی همین جاست

از دوستان DirectX ی نمی خواند قدرتشون را نشون بدهند

amin1softco
چهارشنبه 19 آبان 1389, 19:46 عصر
من یادم نمیاد گفته باشم این کد رو من نوشتم و اینکه این 40 هزار خط خیلی سریع ترسیم می شه برنامه رو اجرا کنید ولی اگر بخواهیم منطقی تر مقایسه کنیم باید این امتحان بوسیله توابع openGL4.x و Direct3D11 تست بشه که در اون صورت اصلاً برنامه بالا برای اوپن جی ال قابل اجرا نیست چون شکل توابع (http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_%28C%2B%2B/Win%29) یکمی عوض شده........

dorche
پنج شنبه 20 آبان 1389, 07:56 صبح
منظورم از تست مقایسه کدهایی است که بچه های این سایت در کدهاشون استفاده می کنند و بیشتر با اونا سرو کله می زنند و اصلا قصد مقایسه OpenGL و DirectX رو ندارم چون اگه من بخوام تو یکی از این دو راه قدم بذارم پامو جایه پایه بچه های این سایت میذارم

خودتون اگه بخواهید در یک برنامه کاربردی این کار را انجام دهید چکار می کنید ؟

(من به دنبال این هستم و اومدم از بچه های سایت راهنمایی بگیرم)

amin1softco
پنج شنبه 20 آبان 1389, 12:44 عصر
ببین از نظر مهندسی نرم افزار چون OpenGL کروس پلاترفرمه یعنی شما اگه یک برنامه رو به زبان سی ++ و توابع این بسته بنویسید به راحتی می تونید اونو برای سیستم عامل های مختلف حتی گوشی آیفون منتشر کنید بهتر به نظر می رسه اما امکاناتی که در دایرکس وجود داره و مثال های خوب و یک حامی بزرگ مثل مایکروسافت آدم رو وسوسه می کنه دایرکس رو انتخاب کنه البته کتابخانه های رایگانی وجود داره که بیشتر امکانات دایرکس رو برای شما فراهم می کنه ولی آخر آخرش از نظر عقل و منطق بهترین راه استفاده از یک انجینه که اسمش UnReal هست

dorche
پنج شنبه 20 آبان 1389, 14:40 عصر
خیلی ممنون واقعا شگفت زده شدم خبر نداشتم که یه همچین موتوری مجانیه

اما به نظر شما برای یک برنامه کاربردی باید از موتور استفاده کنم

برنامه ای که فقط در حالت دو بعدی است و فقط خط و دایره لازم داره ؟

amin1softco
پنج شنبه 20 آبان 1389, 17:53 عصر
تازه این از اون موتور شاسی بلنداست :چشمک: من منظورم کتابخانه های رایگانی هست که امکاناتی که در کنار دایرکس عرضه می شه رو برای اوپن جی ال فراهم می کنه مثل OpenAL برا صوت
آخه خط رو که با همون توابع GDI هم می شه رسم کرد؟
مشکل رسم خطه یا مقایسه دوتا غول عرصه سه بعدی ؟؟؟

مطمئناً برای باز کردن یک مهره احتیاجی به آچار گیریبکس نیست .

dorche
پنج شنبه 20 آبان 1389, 23:08 عصر
100 در 100

جوفتمون میگیم چرا آچار گریبکس

دقیقا مشکل اصلی من هم تو عنوان تاپیک هست

خودم یه کدی با XNA پیدا کردم با کمی تغییرات 40 هزار خطو به راحتی رسم میکنه فقط نتونستم حرکتش بدم که ببینم خوب هست یا نه

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace DrawUserPrimitives
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
Matrix worldMatrix;
Matrix viewMatrix;
Matrix projectionMatrix;

BasicEffect basicEffect;
VertexDeclaration vertexDeclaration;
VertexPositionColor[] pointList;
VertexBuffer vertexBuffer;

int points = 80000;
short[] lineListIndices;

GraphicsDeviceManager graphics;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";

this.IsMouseVisible = true;
}

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
InitializeTransform();
InitializeEffect();
InitializePointList();
InitializeLineList();

base.Initialize();
}

/// <summary>
/// Initializes the transforms used by the game.
/// </summary>
private void InitializeTransform()
{
viewMatrix = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 1.0f),
Vector3.Zero,
Vector3.Up
);

projectionMatrix = Matrix.CreateOrthographicOffCenter(
0,
(float)GraphicsDevice.Viewport.Width,
(float)GraphicsDevice.Viewport.Height,
0,
1.0f, 1000.0f);
}

/// <summary>
/// Initializes the effect (loading, parameter setting, and technique selection)
/// used by the game.
/// </summary>
private void InitializeEffect()
{

vertexDeclaration = new VertexDeclaration(
GraphicsDevice,
VertexPositionColor.VertexElements
);

basicEffect = new BasicEffect(GraphicsDevice, null);
basicEffect.VertexColorEnabled = true;

worldMatrix = Matrix.CreateTranslation(GraphicsDevice.Viewport.W idth / 2f - 150,
GraphicsDevice.Viewport.Height / 2f - 50, 0);
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
}

/// <summary>
/// Initializes the point list.
/// </summary>
private void InitializePointList()
{
vertexDeclaration = new VertexDeclaration(
GraphicsDevice,
VertexPositionColor.VertexElements
);

pointList = new VertexPositionColor[points];

System.Random ran = new System.Random();

for (int i = 0; i < points / 2; i++)
{
pointList[i] = new VertexPositionColor(
new Vector3(ran.Next(0, 100) + 10, ran.Next(0, 50) + 10, 0), Color.White);

pointList[i] = new VertexPositionColor(
new Vector3(ran.Next(0, 100) + 50, ran.Next(0, 50) + 50, 0), Color.White);
}

// Initialize the vertex buffer, allocating memory for each vertex.
vertexBuffer = new VertexBuffer(GraphicsDevice,
VertexPositionColor.SizeInBytes * (pointList.Length),
BufferUsage.None);

// Set the vertex buffer data to the array of vertices.
vertexBuffer.SetData<VertexPositionColor>(pointList);
}

/// <summary>
/// Initializes the line list.
/// </summary>
private void InitializeLineList()
{
// Initialize an array of indices of type short.
lineListIndices = new short[(points)];

// Populate the array with references to indices in the vertex buffer
for (int i = 0; i < points; i++)
{
lineListIndices[i] = (short)(i);
//lineListIndices[(i * 2) + 1] = (short)(i + 1);
}
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.SteelBlue);
GraphicsDevice.VertexDeclaration = vertexDeclaration;

// The effect is a compiled effect created and compiled elsewhere
// in the application.
basicEffect.Begin();

foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Begin();
{
DrawLineList();

GraphicsDevice.RenderState.FillMode = FillMode.Solid;
}
pass.End();
}
basicEffect.End();

base.Draw(gameTime);
}

/// <summary>
/// Draws the line list.
/// </summary>
private void DrawLineList()
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
pointList,
0, // vertex buffer offset to add to each element of the index buffer
pointList.Length, // number of vertices in pointList
lineListIndices, // the index buffer
0, // first index element to read
pointList.Length / 2 // number of primitives to draw
);
}
}
}

اینم لینک کد اصلی برای رسم خط در XNA : لینک (http://msdn.microsoft.com/en-us/library/bb196414.aspx)

کسی می تونه تغییراتی تو کد بده که به حرکت در بیاد ؟

کسی راه دیگری یا زبان دیگری رو پیشنهاد می کنه ؟ لطفا با کد

amin1softco
جمعه 21 آبان 1389, 02:21 صبح
اینجا http://rbwhitaker.wikidot.com/simple-3d-animation (http://rbwhitaker.wikidot.com/simple-3d-animation) یک مثال برای انیمیشن هست
در ضمن بوسیله توابع خود سی شارپ یک مثال ضمیمه کردم البته اینو از همین سایت قبلاً دانلود کردم

dorche
جمعه 21 آبان 1389, 17:21 عصر
ممنون

اما نفهمیدم چرا این کد را ضمیمه کردید ! این همون GDI نیست !

از لینک اول هم استفاده کردم و کدهای زیر رو تو کدم قرار دادم

protected override void Update(GameTime gameTime)
{
position += new Vector3(0, 1.0f, 0);
worldMatrix = Matrix.CreateTranslation(position);


base.Update(gameTime);
}

اما بازم تکون نخورد نمیدونم چرا !

amin1softco
جمعه 21 آبان 1389, 19:08 عصر
این کد رو امتحان کن

/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{

Matrix worldMatrix;
Matrix viewMatrix;
Matrix projectionMatrix;

BasicEffect basicEffect;
VertexDeclaration vertexDeclaration;
VertexPositionColor[] pointList;
VertexBuffer vertexBuffer;

int points = 80;
short[] lineListIndices;

GraphicsDeviceManager graphics;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";

this.IsMouseVisible = true;
}

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
InitializeTransform();
InitializeEffect();
InitializePointList();
InitializeLineList();

base.Initialize();
}

/// <summary>
/// Initializes the transforms used by the game.
/// </summary>
private void InitializeTransform()
{
viewMatrix = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 1.0f),
Vector3.Zero,
Vector3.Up
);

projectionMatrix = Matrix.CreateOrthographicOffCenter(
0,
(float)GraphicsDevice.Viewport.Width,
(float)GraphicsDevice.Viewport.Height,
0,
1.0f, 1000.0f);
}

/// <summary>
/// Initializes the effect (loading, parameter setting, and technique selection)
/// used by the game.
/// </summary>
private void InitializeEffect()
{

vertexDeclaration = new VertexDeclaration(
GraphicsDevice,
VertexPositionColor.VertexElements
);

basicEffect = new BasicEffect(GraphicsDevice, null);
basicEffect.VertexColorEnabled = true;

worldMatrix = Matrix.CreateTranslation(GraphicsDevice.Viewport.W idth / 2f - 150,
GraphicsDevice.Viewport.Height / 2f - 50, 0);
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
}

/// <summary>
/// Initializes the point list.
/// </summary>
private void InitializePointList()
{
vertexDeclaration = new VertexDeclaration(
GraphicsDevice,
VertexPositionColor.VertexElements
);

pointList = new VertexPositionColor[points];

System.Random ran = new System.Random();

for (int i = 0; i < points / 2; i++)
{
pointList[i] = new VertexPositionColor(
new Vector3(ran.Next(0, 100) + 10, ran.Next(0, 50) + 10, 0), Color.White);

pointList[i] = new VertexPositionColor(
new Vector3(ran.Next(0, 100) + 50, ran.Next(0, 50) + 50, 0), Color.White);
}

// Initialize the vertex buffer, allocating memory for each vertex.
vertexBuffer = new VertexBuffer(GraphicsDevice,
VertexPositionColor.SizeInBytes * (pointList.Length),
BufferUsage.None);

// Set the vertex buffer data to the array of vertices.
vertexBuffer.SetData<VertexPositionColor>(pointList);
}

/// <summary>
/// Initializes the line list.
/// </summary>
private void InitializeLineList()
{
// Initialize an array of indices of type short.
lineListIndices = new short[(points)];

// Populate the array with references to indices in the vertex buffer
for (int i = 0; i < points; i++)
{
lineListIndices[i] = (short)(i);
//lineListIndices[(i * 2) + 1] = (short)(i + 1);
}
}
protected override void Update(GameTime gameTime)
{
points+=2;

base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.SteelBlue);
GraphicsDevice.VertexDeclaration = vertexDeclaration;

// The effect is a compiled effect created and compiled elsewhere
// in the application.
basicEffect.Begin();

foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Begin();
{
InitializePointList();
InitializeLineList();
DrawLineList();

GraphicsDevice.RenderState.FillMode = FillMode.Solid;
}
pass.End();
}
basicEffect.End();

base.Draw(gameTime);
}

/// <summary>
/// Draws the line list.
/// </summary>
private void DrawLineList()
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
pointList,
0, // vertex buffer offset to add to each element of the index buffer
pointList.Length, // number of vertices in pointList
lineListIndices, // the index buffer
0, // first index element to read
pointList.Length / 2 // number of primitives to draw
);
}
}


بله همون توابع gdi بود

dorche
یک شنبه 23 آبان 1389, 18:52 عصر
خیلی ممنون

اگر متغیر points رو روی 80 هزار بزاریم 40 هزار خطو برامون میکشه برا همین کد شما رو از 80 هزار گذاشتم شروع کنه با اینکه هر بار محاسبات نقاط که ایجاد اعداد رندم و مقدار دهی های دیگه رو داره بهش میاد سریع و خوب انجام بشه

کسی میتونه کد تغییر مکان با موس رو بهش اضافه کنه که صد در صد مطمئن شویم به خوبی جواب میده ؟

من از OpenGl و DirectX کارها بیشتر انتظار داشتم

dorche
پنج شنبه 04 آذر 1389, 06:55 صبح
با یه سری تغییرات امکانات زیر به برنامه اضافه شد :

جا به جایی با کلید راست موس
بزرگنمایی با اسکرول وسط موس

یه حرکت ناقصی هم با صفحه کلید داره

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

کسی در رابطه ساختار جدید پیشنهادی داره ؟

DirectX ی ها و OpenGL ی ها هنوز کد درست درمونی ندادندا

برنامه رو براتون ضمیمه کردم