Есть сцена с несколькими сферами. Необходимо по клику на сфере менять ее цвет. В 3D новичок и глубоко погружаться времени нету. Наткнулся на статью: http://opengl.gamedev.ru/articles/?id=101 Переписал, получаю координаты отрезка. Вопрос, что дальше с ними делать -как выделить сферу? Если можно с примерами:)
Заранее огромное спасибо!
Понравилась публикация? Сохраните ее, чтобы вернуться к изучению материала!
Я столкнулся с той же проблемой, что и garnett91. Объекты находятся, но редко правильным образом. Так же подозреваю, что дело именно в координатах. Для выделения использую буфер цвета. Камера из урока esate.ru/blog/novye_uroki_opengl/250.html.
Далее я добавил обработчик щелчка мышью, где по началу просто забыл передать текущие координаты, думая, что myMouseYcoord и myMouseXcoord их содержат, оказалось нет.
Теперь передаю в класс, где у меня отрисовка, нужные данные и выполняю все требования, необходимые для выделения через буфер цвета.
/// <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;
/// <summary> /// Главная функция отрисовки всей сцены /// </summary> /// <returns> в режиме выбора возвращает номер выбранного объекта </returns> public int DrawGlScene() { int id = -1; switch (renderSelect) { case RenderSelect.select:
// очистка буфера цвета и буфера глубины 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);
//рисум помещение DrawRoom(); //рисуем препятствия DrawBarriers(renderSelect); //рисуем источник звука DrawSoundSource(renderSelect); //выделяем выбранный объект SelectObject();
if (drawGrid) { //если не вычислено максимальное значени rms... if (!invMaxRMSDetermined) { //вычисляем grid.DetermineInverseMaxRMS(); //устанавливаем флаг = true invMaxRMSDetermined = true; } //рисуем плотность звука grid.DrawGrid(time); } if (drawIndex) //указатель на точку прослушивания grid.DrawVisualIndex();
Вот и всё. Главное здесь, чтобы в режиме выбора все объекты рисовались без текстур, освещения и прочего, только с уникальными цветами, а потом осуществлялась обычная отрисовка. Важно правильно передать координаты мыши, и одинаково настроить матрицу для обоих режимов отрисовки. Отсюда вывод, что gluLookAt и собственно весь класс из урока про камеру не причём)
Стоит ли переходить на Windows 10?Windows 10 установлена на каждый 3-й компьютер. Какие плюсы от перехода? DirectX 12 работает только в Windows 10?
Как установить Windows 10?Как бесплатно и легально скачать? Как записать и установить с последними обновлениями?
Сохраните страницу!
Регистрация
Регистрируясь, вы принимаете правила сайта. Если вы не получили код подтв. регистрации - не
забудьте проверить папку спам.
×
Восстановление пароля
Пожалуйста, заполните поля, после чего вы получите код подтверждения на ваш Email. Если код не пришел в течении нескольких минут - проверьте папку спам.
×
Авторизация
Авторизуйтесь с помощью соц. сети или с помощью аккаунта на сайте:
Объекты на находятся, подозреваю что дело в координатах. В чем конкретно ошибка, не могу найти. Помоги, пожалуйста.
Собственно вот, хорошо известный код из урока про камеру
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 и собственно весь класс из урока про камеру не причём)