После того, как я закончил рисовать прямоугольники, я пытаюсь чтобы переместить их в другой GLControl, который находится внутри другой вкладки.
В настоящее время для первой вкладки я использую множество циклов for для каждого типа объектов что создано (для их соответствующего отображения); чтобы сделать код более аккуратным и эффективным, я хочу нарисовать все на первой вкладке в текстуре, связанной с фреймбуфером, а позже использовать эту текстуру в других GLControls для рисуйте поверх него, не повреждая первый макет прямоугольников.
Для отладки после записи в текстуру я преобразовал текстуру в растровое изображение, и сохранил растровое изображение в формате JPG и просмотрел результат с помощью встроенного визуализатора изображений Windows.
Проблема в том, что только то, что находится внутри Область просмотра рисуется в изображении, поэтому половина некоторых прямоугольников и прямоугольники за пределами области просмотра не рисуются, а все, что находится за пределами области просмотра, представляет собой просто нули (обнаружено используя отладчик Visual Studio, скопировав и вставив изображение в PowerPoint).
Я уже повозился с областью просмотра x, y, шириной и height, но ничего не изменилось, только фон стал оттягиваться дальше, но прямоугольники, выходящие за границы, не прорисовываются в изображение.
Это результаты, которые я получаю на данный момент:
Этот хорошо работает, когда он находится внутри области просмотра:

Это происходит, когда изображение находится в левом нижнем углу (как видите, там являются прозрачными пикселями, поскольку все их значения RGBA равны нулю:

И это происходит, когда изображение находится в правом верхнем углу:
Такое поведение обусловлено моим подходом к созданию текстуры/изображения; поскольку к синим точкам будут прикреплены объекты, я считываю только те пиксели, которые находятся близко к группе прямоугольников, создавая обрезанный вид (вместо считывания всех пикселей всей текстуры).
Если неясно, что я хочу сделать, я хочу визуализировать все мои объекты, находящиеся внутри и за пределами области просмотра, чтобы я мог использовать текстуру в других GLControls.
Это мой код:
Событие кнопки для создания фреймбуфера и выполнения дополнительных действий:
private void buttonLoadFrameBuffer_Click(object sender, EventArgs e)
{
this.Enabled = false;
if (V.tunnelList.Count > 0)
{
CalculateTextureSize(
out V.FrameBufferMáxX,
out V.FrameBufferMínX,
out V.FrameBufferMáxY,
out V.FrameBufferMínY,
V.tunnelList
);
V.FrameBuffer = new FrameBuffer(
V.FrameBufferMáxX,
V.FrameBufferMínX,
V.FrameBufferMáxY,
V.FrameBufferMínY
);
RenderScene();
CaptureFramebufferData();
}
this.Enabled = true;
}
Мой код для рендеринга сцены:
private void RenderScene()
{
int width= glControlLayout.Width;
int height= glControlLayout.Height;
GL.BindFramebuffer(FramebufferTarget.Framebuffer, V.FrameBuffer.FramebufferHandle);
GL.Viewport(
0, //x
0, //y
width,
height
);
GL.ClearColor(245f / 255f, 244f / 255f, 239f / 255f, 1f);
GL.Clear(ClearBufferMask.ColorBufferBit);
D.Matrix4 projectionMatrix = D.Matrix4.CreateOrthographicOffCenter(
0,
width,
0,
height,
-1.0f,
1.0f
);
this.ShaderProgram.SetUniform("Transformation", true, projectionMatrix);
DrawObjects();
V.FrameBuffer.Finalized = true;
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
glControlLayout.Refresh();
}
Мой код для получения данных фреймбуфера:
private void CaptureFramebufferData()
{
int width= V.FrameBufferMáxX - V.FrameBufferMínX;
int heigth = V.FrameBufferMáxY - V.FrameBufferMínY;
GL.BindFramebuffer(FramebufferTarget.Framebuffer, V.FrameBuffer.FramebufferHandle);
byte[] pixels = new byte[width * height * 4];
GL.ReadPixels(
V.FrameBufferMínX,
V.FrameBufferMínY,
width,
height,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
PixelType.UnsignedByte,
pixels
);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
UpdateTexture(pixels, width, height);
}
Мой код для преобразования текстуры в растровое изображение, а затем в JPG:
private void UpdateTexture(byte[] pixels, int width, int height)
{
GL.BindTexture(TextureTarget.Texture2D, V.FrameBuffer.TextureColorHandle);
Bitmap bitmap = new Bitmap(
width,
height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb
);
BitmapData bitmapData = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.WriteOnly,
bitmap.PixelFormat
);
IntPtr ptr = bitmapData.Scan0;
Marshal.Copy(pixels, 0, ptr, pixels.Length);
bitmap.UnlockBits(bitmapData);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
bitmap.Save("D:\\some\\folder\\image.jpg");
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... rs-texture