GLControl | WinForms control for OpenTK | Form library
kandi X-RAY | GLControl Summary
kandi X-RAY | GLControl Summary
This repo contains a WinForms control designed to wrap the OpenTK 4.x APIs into something WinForms can easily use. It is designed and built for .NET Core 3.1+.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of GLControl
GLControl Key Features
GLControl Examples and Code Snippets
Community Discussions
Trending Discussions on GLControl
QUESTION
I use OpenTK's GLControl in C# WinForm (.NET Framework) Application, but I don't know why my 20mm3 cube scaled alone with my form.
I inherit GLControl with DCGLControl and add GL.Viewport(ClientRectangle) when control resize :
...ANSWER
Answered 2021-Jan-19 at 13:52You cannot mix the fixed function matrices with the matrix transformations in 3.30 core shader. This means that the instruction GL.MatrixMode(MatrixMode.Projection);
has no effect (except an OpenGL error in a core profile context). You have to add a projection matrix to the shader:
QUESTION
I am trying to replace GDI+ with SkiaSharp for a data visualization framework that renders multi-layered pannable-zoomable graphs with real-time continuously changing engineering data.
In GDI+, the application did this:
- Created a collection of drawing layers with transparent backgrounds, typically a Grid Layer, one or more Data Layers, and an Overlay Layer for cursor info and highlighting, each backed by a separate bitmap.
- In a rendering loop background thread, only the layers (bitmaps) that needed to be updated for each rendering cycle were redrawn using GDI+. This could require many thousands of calculated and transformed lines, rectangles, and text to create heatmaps, waveforms, histogram plots, data labels, etc.
- Each drawing layer in the stack would then be BitBlt'd to a composite bitmap by the background thread
- The final composite bitmap would then be drawn to a WinForm PictureBox in the GUI thread at up to 30fps.
Everything up to the final image presentation was done in one or more background threads. The GUI thread was only involved to draw the finished image to the PictureBox. This is important because there are many other GUI controls that need to stay responsive. This worked great, except it is all CPU based. Small windows were no problem, but maximizing on a 4K screen would slow down the rendering enough to make the program pretty much unusable.
I would like to recreate this concept with GPU accelerated SkiaSharp.
I tried creating dozens of different test programs and I keep getting Cross-Thread access violations, or nothing showing on the screen, or hard crashes. Instead of posting code, let me ask some basic questions:
Questions:
- How would you approach creating this framework ? Can SkiaSharp even do this ?
- Should each of my layer classes maintain an SKSurface, SKCanvas, SKImage, or SKBitmap ? - Again, if a layer does not need to be redrawn for the current cycle, then the layer needs to maintain the previously drawn content for use in the next composite image.
- A GLControl and GRContext is needed on the GUI thread for showing the final composite image, but should there be another separate GRContext for the background rendering thread to use ? - How to create with GPU acceleration ?
- Are there any working examples of a similar concept that someone can point to ? ( GPU accelerating rendering from background thread to GLControl )
- Should I use SkiaSharp hidden in the background only, and GDI+ BitBlt with PictureBox to show the composite image on the screen ? - Would that solve some threading issues ?
Any help defining the approach and the dos and don'ts would be greatly appreciated !!
...ANSWER
Answered 2020-Nov-29 at 02:58I figured out how to get this to work using SKPicture objects to record the Draw Commands from each layer using a background rendering thread, then painting them back to an SKGLControl using the GUI thread. This satisfies all of my requirements: It allows for multiple drawing layers, renders with a background thread, renders only the layers that need updates, paints with GPU acceleration, and is extremely fast for a maximized 4K window.
Lessons LearnedThere are a few lessons that I learned along the way that were causing a lot of confusion for me...
There are examples online of using an OpenTK.GLControl with GPU acceleration, and there are examples using the SkiaSharp.Views.Desktop.SKGLControl which has built in GPU acceleration. The SKGLControl is definitely the correct control for this task. The GLControl was creating squares for DrawCircle and refusing to render any curves due to issues with the FramebufferBinding and StencilBits ?!? - I gave up on it. It is also slower than the SKGLControl for SKPicture objects.
The SKGLControl does not need nor like the use of SwapBuffers or Canvas.Flush, which are required for the GLControl. This was causing strobing and glitching of the drawings for SKGLControl, which is why I went off in the weeds fighting with the GLControl. When I rebuilt the project with SKGLControl and got rid of SwapBuffers and Canvas.Flush, everything started behaving.
References to Surfaces and Canvases should not be held past one PaintSurface cycle. The SKPicture is the magical object that will let you store the drawing commands for each layer and play them back again and again. This is different from an SKBitmap or SKImage which are generating pixel rasters instead of just recording the Draw commands. I couldn't get SKBitmap or SKImage to behave in a multithreaded environment and still be GPU accelerated. SKPicture works great for this.
There is a difference between the Paint event and the PaintSurface event for the SKGLControl. The PaintSurface event is what should be used and is by default GPU accelerated.
Below is fully functional demo of a multi-layer, multi-threaded, GPU accelerated SkiaSharp drawing
This example creates 4 drawing layers:
- Background Layer
- Grid Layer
- Data Layer
- Overlay Layer
The layers are drawn ( rendered ) using a background thread, then painted to an SKGLControl using the GUI thread. Each layer is only rendered when needed, but all layers are painted with each PaintSurface event.
To try the code:- Create a new C# WinForms project in Visual Studio.
- Add the NuGet Package: "SkiaSharp.Views.WindowsForms". This will automatically add "SkiaSharp", and "SkiaSharp.Views.Desktop.Common".
- Add a SkiaSharp.Views.Desktop.SKGLControl to Form1. Name it "skglControl1"
- Set Dock to "Fill" for skglControl1 so that it fills Form1.
- Copy the code below to Form1:
QUESTION
I am trying to create clipping planes to define sections at different points of my objects in a opentk glControl , for that I define a variable "elevActual" that indicates the distance that the clipping plane will be created. By clicking a button I advance my clipping plane. The problem is that as the clipping plane advances, the objects that are behind the clipping plane are still displayed and I only want the section defined at the "elevActual" distance to be displayed.
...ANSWER
Answered 2020-Nov-02 at 13:19If you only want to view a section of the geometry, you must define two clipping planes. One at the beginning of the section and one at the end of the section. In the following start
and to
defines the range of the section. start
must be smaller than end
:
QUESTION
I have a slider which have value ranges from zero to one. Now using the value of this slider , I want to crop the image from bottom to half of image And from top to half of image. I have done the first one (bottom crop) by resizing the height of GLControl. Not sure that this is the proper way to achieve this. But it is working fine. I have no idea for second option (cropping from top to half of image). Please help to get it. Attached is the outputs that I got when performing bottom crop with values 0,0.4,1.0 respectively.
...ANSWER
Answered 2020-Oct-27 at 07:31I assume that sSelectedCropVal
is in range [0.0, 1.0].
You can discard
the fragments depending on the v corodiante:
QUESTION
I want to rotate an image which is shown in my GLControl to 10 degree. For that I have rotated the bitmap using c# code and passed this rotated bitmap to opengl shader code. But the resulted image is seems like the rotated part is hiding/cut like below. Shall I need to do any changes on it's view port while rotating? or is it good to rotate the image in shader code itself?
...ANSWER
Answered 2020-Oct-22 at 10:45Do not rotate the image, but rotate and scale the vertex coordinates.
Add a transformation matrix to the vertex shader:
QUESTION
Hi so I'm starting out with OpenTK and just following the tutorials on this website and I'm on this tutorial and it says to write the code:
...ANSWER
Answered 2020-Sep-07 at 16:54As far as I know there are still gaps in which packages are fully realized/supported in the dotnet5 (a.k.a. .NetCore) and I also don't fully understand where to locate the comparison cheatsheet etc. I think .NET 4.8 or whatever was the last LTS Windows-only distro of .NET and in future they appear to be focusing a lot of cross-platform availability so it might take a while.
Other contributions by more seasoned .NET gurus may be able to shed some light on this.
QUESTION
I have three controls inside a panel like below. I have to arrange one at center of the panel. and other two should place just left and right side of center one. I have tried like below. But getting all three controls are aligned to left. Please help to correct.
...ANSWER
Answered 2020-Apr-30 at 18:23What if you put each WinForms control in its own host and then used WPF panels to for the layout? Something like this:
QUESTION
I've been experimenting with showing OpenGl graphics in C# winforms, and I stumbled upon a very useful NuGet package called OpenTK. I followed the introductory tutorial on OpenTK's Learn tab, and was able to render some simple shapes. The tutorial was super helpful, but it is predicated on showing the OpengGL graphics in a GameWindow (separate from the main Form). I found that it is possible to show OpenGL graphics directly in the main Form by using an OpenTK.GLControl control. To make with work, I installed the additional NuGet package OpenTK.GLControl. I added the control in the Form1.Designer.cs file and defined its necessary methods in Form1.cs. However, I'm not able to see the GLControl.
Am I missing a crucial step in my code, or do I have an issue with the packages/dll files?
Form1.Designer.cs:
...ANSWER
Answered 2020-Jan-30 at 20:43You've missed to add the control to the form:
QUESTION
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
namespace Snake
{
public partial class GameWindow : Form
{
private int glcontrolFieldWidth = 20, glcontrolFieldHeight = 20; //Playing Field
public int speedincr = 0; //Speed, Increase by 5% Check out GenerateFood()
public int GamePoints = -10; //Score
private int shaderProgram, color_attribute; //Shader Program
private int view, model, projection;//Shader Program
private Matrix4 ViewMatrix, ModelMatrix, ProjectionMatrix; // Matrix4
private List snake = new List() { new Point(1, 1) }; //Where the Snake Start off
private Point snakeDirection = new Point(1, 0);//Snake Direction
private Point mouse = new Point(); //Food
private Random random = new Random(); //Random Genereator
public bool bGameOver;
private static readonly Timer timer = new Timer();
public GameWindow()
{
//Form1.Designer
InitializeComponent();
// Centers the form on the current screen
CenterToScreen();
// Create a timer
//var timer = new Timer();
timer.Tick += new EventHandler(GameLoop);
timer.Interval = 150; // This is the snake inital speed
timer.Start();
// Generate an initial random position for the food
GenerateFood();
}
public void GameOver(bool bGameOver)
{
//Snake Collision with its own body
//for (int i = 0; i < snake.Count; i++)
//{
// //if Snake equal itself then snake hasn't touch any other parts of its body
// if (snake[0].X == snake[i].X || snake[0].Y == snake[i].Y)
// {
// this.bGameOver = false;
// //Console.WriteLine("Snake " + snake2[i].X + "," + snake2[i].Y);
// //Console.WriteLine("Snake2 " + snake[i].X + "," + snake[i].Y);
// }
// else
// {
// this.bGameOver = true;
// //Console.WriteLine(snake[i].X+","+snake[i].Y);
// }
//}
////---Display GameOver Message If Where Dead-- - //
//if (bGameOver == true)
//{
// Console.WriteLine("Game Over! Push Enter to Continue");
// if (bGameOver == false)
// {
// //Game Start Over
// }
//}
return;
} //GameOver Reset Game
public void GameLoop(object sender, System.EventArgs e)
{
// Update coordinates of game entities and check collisions
Update();
// UpdateWall check collisions with snake to bounce off wall
UpdateWall();
GameOver(bGameOver);
glControl.Invalidate();
} //Basic of the Game Loop
private void UpdateWall()
{
// Snake collison with Walls
if (snake[0].X < 1)
{
//snake[0].X = (glcontrolFieldWidth - 2) / 10; //Warp to right
//snakeDirection.X = (snake[0].X + glcontrolFieldWidth-2)/10;
//snakeDirection.X = (glcontrolFieldWidth-2)/10;
snakeDirection.X = (int)(glcontrolFieldWidth-0.5) / 10;
snakeDirection.Y = (int)(glcontrolFieldWidth-0.5) / 10;
Console.WriteLine("Snake hit left wall");
}
else if (snake[0].X > glcontrolFieldWidth - 2)
{
//snakeDirection.X = 0; //Warp to left
snakeDirection.X = (int)(glcontrolFieldWidth - 0.5) / -10;
snakeDirection.Y = (int)(glcontrolFieldWidth - 0.5) / -10;
Console.WriteLine("Snake hit right wall");
}
if (snake[0].Y < 1)
{
//snake.getFirst().y = windowHeight / 10; //Warp to bottom
//snakeDirection.Y = (snake[0].Y + glcontrolFieldWidth - 2)/10;
snakeDirection.X = (int)(glcontrolFieldHeight - 0.5)/10;
snakeDirection.Y = (int)(glcontrolFieldHeight - 0.5)/10;
Console.WriteLine("Snake hit Top wall");
}
else if (snake[0].Y > glcontrolFieldHeight - 2)
{
//snake.getFirst().y = 0; //Warp to top
snakeDirection.X = (int)(glcontrolFieldHeight - 0.5) / -10;
snakeDirection.Y = (int)(glcontrolFieldHeight - 0.5) / -10;
Console.WriteLine("Snake hit Bottom wall");
}
} //Wall Collision
private new void Update()
{
// Calculate a new position of the head of the snake
Point newHeadPosition = new Point(snake[0].X + snakeDirection.X, snake[0].Y + snakeDirection.Y);
// Insert new position in the beginning of the snake list
snake.Insert(0, newHeadPosition);
snake.RemoveAt(snake.Count - 1);
// Check snake collision with the food
if (snake[0].X != mouse.X || snake[0].Y != mouse.Y)
{
return;
}
else
{
//Snake Grow
snake.Add(new Point(mouse.X, mouse.Y));
}
Console.WriteLine();
//foreach (Point aPart in snake)
//{
// Console.WriteLine(aPart);
//}
// Generate a new food(mouse) position
GenerateFood();
}//...more code.
...ANSWER
Answered 2020-Feb-19 at 08:48It is sufficient to evaluate if the head of the snake hits its body. Test if snake[0]
hits any element from 1 to snake.Count-1
.
You have to verify if the x component and (&&
) the y component is equal:
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install GLControl
Convert all uses of Color to Color4.
Convert all calls to GL.Color() to GL.Color4().
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page