Я работаю с OpenGL, используя C # (используя работу TaoFrame), дело в том, что я хочу рисовать
2 объекта на экране (например, прямоугольник), главная цель моего Вопроса в том, как нажать кнопку мыши, чтобы я мог выбрать один объект, чтобы он двигался.
В основном мне просто нужно знать, как выбрать один объект, вот и все:
Информация о моем проекте:
Я использую рабочие библиотеки taoframe, порт просмотра opengl - это просто небольшая панель в главном окне управления, она не полноэкранная.
эта функция является основной функцией рисования opengl:
private void draw()
{
//Gl.glInitNames(); is this function invoked here ?
Gl.glMatrixMode(Gl.GL_PROJECTION);
GC.Collect();
simpleOpenGlControl1_Resize(new object(), new EventArgs());
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity(); // Reset The Current Modelview M
//Gl.glPushName(table);
//Gl.glPushName(room);
Gl.glPushMatrix();
Gl.glLoadName(table);
Gl.glTranslatef(-2, 0,-13);
Gl.glRects(0, 0, 2, 2);
Gl.glLoadName(obj1); // obj1 is a const int =1
Gl.glTranslatef(-5, 0, -13);
Gl.glRects(0, 0, 2, 2);
Gl.glPopMatrix();
simpleOpenGlControl1.Draw();
}
эта функция является обработчиком мыши:
private void simpleOpenGlControl1_MouseClick(object sender, MouseEventArgs e)
{
//this code here is to supposed to select object from select Function
if (e.Button == MouseButtons.Left)
{
uint selected = Select(e.X, e.Y);
if (selected == obj1)
label1.Text = "object 1";
else if (selected == obj2)
label1.Text = " object 2";
else label1.Text = "nothing";
}
}
Фактический выбор Водо делается здесь:
public uint Select(int x, int y)
{
int[] viewport = new int[4]; //Current Viewport
uint[] selectBuf = new uint[512]; // will hold the id's of selected objects
//1) Get Current Viewport
Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);
// 2 , selection buffer and selection mode
Gl.glSelectBuffer(512, selectBuf); // Assign a selection buffer
Gl.glRenderMode(Gl.GL_SELECT); // switch to selection mode
Gl.glInitNames(); // Init Name Stack
// go ahead and put a name in
Gl.glPushName(obj1);
Gl.glPushName(obj2);
// 4 matrix mode and initialize
Gl.glMatrixMode(Gl.GL_PROJECTION); // Change Matrix Mode to projection
Gl.glPushMatrix(); // Don't disturb other things
Gl.glLoadIdentity(); // Reset the axis
// 6 - create pick matrix around current point
// Main function! Thiss make a virtual clipping region with
// center x, y and width and height 1 each w.r.t the current viewport.
// Note the "viewport[3]-y" parameter instead of y!
Glu.gluPickMatrix(
(double)x, (double)(viewport[3] - y),
//Specify the center of a picking region in window coordinates.
4.0, 5.0, // delx, dely
viewport // current viewport
);
Gl.glOrtho(0.0f, (double)Size.Width, 0.0f, (double)Size.Height, -0.5f, 2.5f);
//Call our Render function to load object with names.
// Note that since our Render mode is GL_SELECT nothing will be drawn
// on the screen due to this function call!
simpleOpenGlControl1.Draw();
Gl.glPopMatrix(); // Don't disturb other things
//Switch back to default mode!
//This time the "glRenderMode" function returns the no.
// of objects that were found to be drawn in the clipping region made by glPickMatrix.
int hits = Gl.glRenderMode(Gl.GL_RENDER);
System.Console.WriteLine("Select, number of hits:" + hits.ToString());
return ProcessHits(hits, selectBuf);
}
Эта функция ProcessHits, чтобы я мог получить имя объекта
private static uint ProcessHits(int hits, uint[] buffer)
{
uint i, j;
uint names;
uint[] ptr;
uint result = 666;
Console.WriteLine("ProcessHits hits = {0}", hits);
ptr = buffer;
for (i = 0; i < hits; i++)
{ // For Each Hit
names = ptr[i];
Console.WriteLine(" number of names for hit = {0}", names);
i++;
Console.WriteLine(" z1 is {0}", (float)ptr[i] / 0x7fffffff);
i++;
Console.WriteLine(" z2 is {0}", (float)ptr[i] / 0x7fffffff);
i++;
Console.Write(" the name is ");
for (j = 0; j < names; j++)
{ // For Each Name
Console.Write("{0} ", ptr[i]);
result = ptr[i]; // if there are multiple selections, this is an ERROR, but at least for the time being, return something
i++;
}
Console.Write("\n");
}
Console.Write("\n");
return result;
}
1-значение Result в функции ProcessHits всегда равно 1, которое предпочитает object1, поэтому, если я нажимаю в пробеле, у меня есть объект 1, хотя там нечего выбирать, так что мне не хватает некоторого кода? .
2 - значение попаданий в функции выбора всегда равно 2? я не знаю почему?