Выделение объекта мышью в 3D сцене

Есть сцена с несколькими сферами. Необходимо по клику на сфере менять ее цвет.
В 3D новичок и глубоко погружаться времени нету.
Наткнулся на статью: http://opengl.gamedev.ru/articles/?id=101
Переписал, получаю координаты отрезка.
Вопрос, что дальше с ними делать -как выделить сферу? Если можно с примерами:)


Заранее огромное спасибо!
0       2262        07.03.2011        10

0  
08.03.2011 00:00:00
Попробуй изменить этот код, что бы вместо сообщения изменяло переменную с цветом данной фигуры.
0  
08.03.2011 00:00:00
это просто отлично! спасибо, с заменой цвета думаю придумаю что-нибудь
0  
08.03.2011 00:00:00
Не подскажешь, в чем может быть проблема: пытаюсь связать выделение мышью в случае, когда в сцене есть камера из урока

Объекты на находятся, подозреваю что дело в координатах. В чем конкретно ошибка, не могу найти. Помоги, пожалуйста.
0  
08.03.2011 00:00:00
Я столкнулся с той же проблемой, что и garnett91. Объекты находятся, но редко правильным образом. Так же подозреваю, что дело именно в координатах. Для выделения использую буфер цвета. Камера из урока esate.ru/blog/novye_uroki_opengl/250.html.
0  
08.03.2011 00:00:00
Я со своей проблемой разобрался. Неправильно передавал координаты мыши в glReadPixels, а точнее не обновлял их значения.
0  
08.03.2011 00:00:00
можно твой исходник, либо хотя бы ту часть, в которой была ошибка?
0  
08.03.2011 00:00:00
лучше весь исходник, так как я использую не буфер цвета для выделения)
0  
08.03.2011 00:00:00
На самом деле лучше часть, так легче будет разобраться))

Собственно вот, хорошо известный код из урока про камеру


private void OpenGlControl_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
mouseRotate = true;

if (e.Button == MouseButtons.Right)
mouseMove = true;

myMouseYcoord = e.X;
myMouseXcoord = e.Y;

mouse_Events();
cam.update();

ReDrawGlScene();
}

private void OpenGlControl_MouseMove(object sender, MouseEventArgs e)
{
myMouseXcoordVar = e.Y;
myMouseYcoordVar = e.X;
mouse_Events();
cam.update();
ReDrawGlScene();
}

private void OpenGlControl_MouseUp(object sender, MouseEventArgs e)
{
mouseRotate = false;
mouseMove = false;
mouse_Events();
cam.update();
ReDrawGlScene();
}


Далее я добавил обработчик щелчка мышью, где по началу просто забыл передать текущие координаты, думая, что myMouseYcoord и myMouseXcoord их содержат, оказалось нет.

private void OpenGlControl_MouseClick(object sender, MouseEventArgs e)
{
ProcessColorBuffer(e.X, e.Y);
}


Теперь передаю в класс, где у меня отрисовка, нужные данные и выполняю все требования, необходимые для выделения через буфер цвета.

/// <summary>
/// Выбор объектов через буфер цвета
/// </summary>
private void ProcessColorBuffer(int x, int y)
{
drawing.SetMouseXCoord = x;
drawing.SetMouseYCoord = OpenGlControl.Height - y;
drawing.SetPickingObject = picking;
drawing.SetCameraObject = cam;
drawing.SetRenderOrSelectMode = Drawing.RenderSelect.select;
int id = drawing.DrawGlScene();
if (id != -1)
SelectObject.SelectedIndex = id;

drawing.SetRenderOrSelectMode = Drawing.RenderSelect.render;
ReDrawGlScene();
}


И наконец отрисовка


/// <summary>
/// Главная функция отрисовки всей сцены
/// </summary>
/// <returns> в режиме выбора возвращает номер выбранного объекта </returns>
public int DrawGlScene()
{
int id = -1;
switch (renderSelect)
{
case RenderSelect.select:

Gl.glDisable(Gl.GL_DITHER);
Gl.glDisable(Gl.GL_DEPTH_TEST);
Gl.glDisable(Gl.GL_TEXTURE_2D);
Gl.glDisable(Gl.GL_LIGHTING);
Gl.glClearColor(0, 0, 0, 1f);

// очистка буфера цвета и буфера глубины
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
// очищение текущей матрицы
Gl.glLoadIdentity();

cam.Look(); //Обновляем взгляд камеры

pixels = new byte[3];

picking.InitNames();
for (int i = 0; i < listBarriers.Count; i++)
picking.LoadName(i, listBarriers[i].color);
//for (int i = 0; i < listSoundSources.Count; i++)
//picking.LoadName(i, listSoundSources[i].color);

DrawBarriers(renderSelect);
//DrawSoundSource(renderSelect);

Gl.glReadPixels(mouseXcoord, mouseYcoord, 1, 1, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, pixels);
id = picking.GetSelectedColorObject(pixels);

if (listBarriers.Count > 0)
PrintText3D((float)cam.getViewX(), (float)cam.getViewY(), (float)cam.getViewZ(), "id = " + id + " selectedObject " + (selectedObjectId).ToString() + " color " + pixels[0] + " " + pixels[1] + " " + pixels[2] + " object real color: " +
listBarriers[selectedObjectId].color[0] + " " +
listBarriers[selectedObjectId].color[1] + " " +
listBarriers[selectedObjectId].color[2]);

Gl.glClearColor(r, g, b, 1f);
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glEnable(Gl.GL_DITHER);

break;
case RenderSelect.render:

// очистка буфера цвета и буфера глубины
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
// очищение текущей матрицы
Gl.glLoadIdentity();

cam.Look(); //Обновляем взгляд камеры

//Включаем шейдеры
//if (usingGLSL)
//glslAdapter.Bind();

//рисум помещение
DrawRoom();
//рисуем препятствия
DrawBarriers(renderSelect);
//рисуем источник звука
DrawSoundSource(renderSelect);
//выделяем выбранный объект
SelectObject();

if (drawGrid)
{
//если не вычислено максимальное значени rms...
if (!invMaxRMSDetermined)
{
//вычисляем
grid.DetermineInverseMaxRMS();
//устанавливаем флаг = true
invMaxRMSDetermined = true;
}
//рисуем плотность звука
grid.DrawGrid(time);
}
if (drawIndex)
//указатель на точку прослушивания
grid.DrawVisualIndex();

//Отключаем шейдеры
//if (usingGLSL)
//glslAdapter.Unbind();

break;
}
return id;
}



Вот и всё. Главное здесь, чтобы в режиме выбора все объекты рисовались без текстур, освещения и прочего, только с уникальными цветами, а потом осуществлялась обычная отрисовка. Важно правильно передать координаты мыши, и одинаково настроить матрицу для обоих режимов отрисовки. Отсюда вывод, что gluLookAt и собственно весь класс из урока про камеру не причём)
0  
08.03.2011 00:00:00
Спасибо! Проблема действительно была в координатах мыши
0  
09.03.2011 00:00:00
Для изменения цвета можно сделать массив для каждой сферы с ячейками r,g,b. Перед рисованием сделать цвет материала как в массиве.
^