Anonymous
Openentk - So drehen Sie das Objekt um gegebenen Winkel
Post
by Anonymous » 23 Sep 2025, 03:03
Ich habe das Tutorial unter
http://viewport3d.com/trackball.htm verwendet, um Trackball zu programmieren. Ich habe Achse und Winkel berechnet, aber weil ich nur Anfänger von Openentk und OpenGL bin, weiß ich nicht, wie man Rotation auf Objekt anwendet. Irgendwelche Hilfe bitte?
Code: Select all
using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
namespace _038trackball
{
public partial class Form1
{
#region Camera attributes
///
/// Current camera position.
///
private Vector3 eye = new Vector3( 0.0f, 0.0f, 10.0f );
///
/// Current point to look at.
///
private Vector3 pointAt = Vector3.Zero;
///
/// Current "up" vector.
///
private Vector3 up = Vector3.UnitY;
///
/// Vertical field-of-view angle in radians.
///
private float fov = 1.0f;
///
/// Camera's far point.
///
private float far = 200.0f;
#endregion
protected Vector3d v1 = new Vector3d(0, 0, 0);
protected Vector3d v2 = new Vector3d(0, 0, 0);
protected float theta = 0;
///
/// Sets up a projective viewport
///
private void SetupViewport ()
{
int width = glControl1.Width;
int height = glControl1.Height;
// 1. set ViewPort transform:
GL.Viewport( 0, 0, width, height );
// 2. set projection matrix
GL.MatrixMode( MatrixMode.Projection );
Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView( fov, (float)width / (float)height, 0.1f, far );
GL.LoadMatrix( ref proj );
}
///
/// Setup of a camera called for every frame prior to any rendering.
///
private void SetCamera ()
{
// !!!{{ TODO: add camera setup here
SetupViewport();
GL.MatrixMode( MatrixMode.Modelview );
Matrix4 modelview = Matrix4.CreateTranslation(-center) *
Matrix4.Scale(1.0f / diameter) *
Matrix4.CreateTranslation(0.0f, 0.0f, -1.5f);
GL.LoadMatrix( ref modelview );
// !!!}}
}
private void ResetCamera ()
{
// !!!{{ TODO: add camera reset code here
// !!!}}
}
///
/// Rendering of one frame.
///
private void Render ()
{
if ( !loaded ) return;
frameCounter++;
GL.Clear( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit );
GL.ShadeModel( ShadingModel.Flat );
GL.PolygonMode( MaterialFace.Front, PolygonMode.Fill );
GL.Enable( EnableCap.CullFace );
SetCamera();
RenderScene();
glControl1.SwapBuffers();
}
public void glControl1_MouseDown ( object sender, MouseEventArgs e )
{
Cursor.Current = Cursors.Hand;
double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2);
double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2);
x = x - 1;
y = 1 - y;
double z2 = 1 - x * x - y * y;
double z = z2 > 0 ? Math.Sqrt(z2) : 0;
v1 = new Vector3d(x, y, z);
v1.Normalize();
//labelFile.Text = String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", x, y, z, MousePosition.X, MousePosition.Y, glControl1.Width, glControl1.Height);
}
private void glControl1_MouseUp ( object sender, MouseEventArgs e )
{
Cursor.Current = Cursors.Default;
double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2);
double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2);
x = x - 1;
y = 1 - y;
double z2 = 1 - x * x - y * y;
double z = z2 > 0 ? Math.Sqrt(z2) : 0;
v2 = new Vector3d(x, y, z);
v2.Normalize();
Vector3d axis = Vector3d.Cross(v1, v2);
float theta = (float) Vector3d.CalculateAngle(v1, v2);
// Here sholud be smoething
//labelFile.Text = String.Format("{0}, {1}", axis, theta);
}
private void glControl1_MouseMove ( object sender, MouseEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void glControl1_MouseWheel ( object sender, MouseEventArgs e )
{
// !!!{{ TODO: add the event handler here
// HINT: for most mouses, e.delta / 120 is the number of wheel clicks, +/- indicated the direction
// !!!}}
}
private void glControl1_KeyDown ( object sender, KeyEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void glControl1_KeyUp ( object sender, KeyEventArgs e )
{
// !!!{{ TODO: add the event handler here
// !!!}}
}
private void buttonReset_Click ( object sender, EventArgs e )
{
// !!!{{ TODO: add the event handler here
ResetCamera();
// !!!}}
}
}
}
< /code>
und Form1.cs < /p>
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using Scene3D;
namespace _038trackball
{
public partial class Form1 : Form
{
///
/// Scene read from file.
///
protected SceneBrep scene = new SceneBrep();
///
/// Scene center point.
///
protected Vector3 center = Vector3.Zero;
///
/// Scene diameter.
///
protected float diameter = 3.5f;
///
/// GLControl guard flag.
///
bool loaded = false;
///
/// Are we allowed to use VBO?
///
bool useVBO = true;
#region OpenGL globals
private uint[] VBOid = new uint[ 2 ]; // vertex array (colors, normals, coords), index array
private int stride = 0; // stride for vertex array
#endregion
#region FPS counter
long lastFpsTime = 0L;
int frameCounter = 0;
long triangleCounter = 0L;
#endregion
public Form1 ()
{
InitializeComponent();
}
private void glControl1_Load ( object sender, EventArgs e )
{
loaded = true;
// OpenGL init code:
GL.ClearColor( Color.DarkBlue );
GL.Enable( EnableCap.DepthTest );
GL.ShadeModel( ShadingModel.Flat );
// VBO init:
GL.GenBuffers( 2, VBOid );
if ( GL.GetError() != ErrorCode.NoError )
useVBO = false;
SetupViewport();
Application.Idle += new EventHandler( Application_Idle );
comboTrackballType.SelectedIndex = 0;
}
private void glControl1_Resize ( object sender, EventArgs e )
{
if ( !loaded ) return;
SetupViewport();
glControl1.Invalidate();
}
private void glControl1_Paint ( object sender, PaintEventArgs e )
{
Render();
}
private void buttonOpen_Click ( object sender, EventArgs e )
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open Scene File";
ofd.Filter = "Wavefront OBJ Files|*.obj" +
"|All scene types|*.obj";
ofd.FilterIndex = 1;
ofd.FileName = "";
if ( ofd.ShowDialog() != DialogResult.OK )
return;
WavefrontObj objReader = new WavefrontObj();
objReader.MirrorConversion = false;
StreamReader reader = new StreamReader( new FileStream( ofd.FileName, FileMode.Open ) );
int faces = objReader.ReadBrep( reader, scene );
reader.Close();
scene.BuildCornerTable();
diameter = scene.GetDiameter( out center );
scene.GenerateColors( 12 );
ResetCamera();
//labelFile.Text = String.Format("{0}: {1} faces, {2}, {3}, {4}, {5}", ofd.SafeFileName, faces, theta, v1.X, x, y);
PrepareDataBuffers();
glControl1.Invalidate();
}
///
/// Prepare VBO content and upload it to the GPU.
///
private void PrepareDataBuffers ()
{
if ( useVBO &&
scene != null &&
scene.Triangles > 0 )
{
GL.EnableClientState( ArrayCap.VertexArray );
if ( scene.Normals > 0 )
GL.EnableClientState( ArrayCap.NormalArray );
GL.EnableClientState( ArrayCap.ColorArray );
// Vertex array: color [normal] coord
GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] );
int vertexBufferSize = scene.VertexBufferSize( true, false, true, true );
GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.StaticDraw );
IntPtr videoMemoryPtr = GL.MapBuffer( BufferTarget.ArrayBuffer, BufferAccess.WriteOnly );
unsafe
{
stride = scene.FillVertexBuffer( (float*)videoMemoryPtr.ToPointer(), true, false, true, true );
}
GL.UnmapBuffer( BufferTarget.ArrayBuffer );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
// Index buffer
GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] );
GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)(scene.Triangles * 3 * sizeof( uint )), IntPtr.Zero, BufferUsageHint.StaticDraw );
videoMemoryPtr = GL.MapBuffer( BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly );
unsafe
{
scene.FillIndexBuffer( (uint*)videoMemoryPtr.ToPointer() );
}
GL.UnmapBuffer( BufferTarget.ElementArrayBuffer );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
}
else
{
GL.DisableClientState( ArrayCap.VertexArray );
GL.DisableClientState( ArrayCap.NormalArray );
GL.DisableClientState( ArrayCap.ColorArray );
if ( useVBO )
{
GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] );
GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] );
GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
}
}
}
}
}
1758589390
Anonymous
Ich habe das Tutorial unter http://viewport3d.com/trackball.htm verwendet, um Trackball zu programmieren. Ich habe Achse und Winkel berechnet, aber weil ich nur Anfänger von Openentk und OpenGL bin, weiß ich nicht, wie man Rotation auf Objekt anwendet. Irgendwelche Hilfe bitte?[code]using System; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace _038trackball { public partial class Form1 { #region Camera attributes /// /// Current camera position. /// private Vector3 eye = new Vector3( 0.0f, 0.0f, 10.0f ); /// /// Current point to look at. /// private Vector3 pointAt = Vector3.Zero; /// /// Current "up" vector. /// private Vector3 up = Vector3.UnitY; /// /// Vertical field-of-view angle in radians. /// private float fov = 1.0f; /// /// Camera's far point. /// private float far = 200.0f; #endregion protected Vector3d v1 = new Vector3d(0, 0, 0); protected Vector3d v2 = new Vector3d(0, 0, 0); protected float theta = 0; /// /// Sets up a projective viewport /// private void SetupViewport () { int width = glControl1.Width; int height = glControl1.Height; // 1. set ViewPort transform: GL.Viewport( 0, 0, width, height ); // 2. set projection matrix GL.MatrixMode( MatrixMode.Projection ); Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView( fov, (float)width / (float)height, 0.1f, far ); GL.LoadMatrix( ref proj ); } /// /// Setup of a camera called for every frame prior to any rendering. /// private void SetCamera () { // !!!{{ TODO: add camera setup here SetupViewport(); GL.MatrixMode( MatrixMode.Modelview ); Matrix4 modelview = Matrix4.CreateTranslation(-center) * Matrix4.Scale(1.0f / diameter) * Matrix4.CreateTranslation(0.0f, 0.0f, -1.5f); GL.LoadMatrix( ref modelview ); // !!!}} } private void ResetCamera () { // !!!{{ TODO: add camera reset code here // !!!}} } /// /// Rendering of one frame. /// private void Render () { if ( !loaded ) return; frameCounter++; GL.Clear( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit ); GL.ShadeModel( ShadingModel.Flat ); GL.PolygonMode( MaterialFace.Front, PolygonMode.Fill ); GL.Enable( EnableCap.CullFace ); SetCamera(); RenderScene(); glControl1.SwapBuffers(); } public void glControl1_MouseDown ( object sender, MouseEventArgs e ) { Cursor.Current = Cursors.Hand; double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2); double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2); x = x - 1; y = 1 - y; double z2 = 1 - x * x - y * y; double z = z2 > 0 ? Math.Sqrt(z2) : 0; v1 = new Vector3d(x, y, z); v1.Normalize(); //labelFile.Text = String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", x, y, z, MousePosition.X, MousePosition.Y, glControl1.Width, glControl1.Height); } private void glControl1_MouseUp ( object sender, MouseEventArgs e ) { Cursor.Current = Cursors.Default; double x = MousePosition.X * 1.0 / (glControl1.Width * 1.0 / 2); double y = MousePosition.Y * 1.0 / (glControl1.Height * 1.0 / 2); x = x - 1; y = 1 - y; double z2 = 1 - x * x - y * y; double z = z2 > 0 ? Math.Sqrt(z2) : 0; v2 = new Vector3d(x, y, z); v2.Normalize(); Vector3d axis = Vector3d.Cross(v1, v2); float theta = (float) Vector3d.CalculateAngle(v1, v2); // Here sholud be smoething //labelFile.Text = String.Format("{0}, {1}", axis, theta); } private void glControl1_MouseMove ( object sender, MouseEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void glControl1_MouseWheel ( object sender, MouseEventArgs e ) { // !!!{{ TODO: add the event handler here // HINT: for most mouses, e.delta / 120 is the number of wheel clicks, +/- indicated the direction // !!!}} } private void glControl1_KeyDown ( object sender, KeyEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void glControl1_KeyUp ( object sender, KeyEventArgs e ) { // !!!{{ TODO: add the event handler here // !!!}} } private void buttonReset_Click ( object sender, EventArgs e ) { // !!!{{ TODO: add the event handler here ResetCamera(); // !!!}} } } } < /code> und Form1.cs < /p> using System; using System.Drawing; using System.IO; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; using Scene3D; namespace _038trackball { public partial class Form1 : Form { /// /// Scene read from file. /// protected SceneBrep scene = new SceneBrep(); /// /// Scene center point. /// protected Vector3 center = Vector3.Zero; /// /// Scene diameter. /// protected float diameter = 3.5f; /// /// GLControl guard flag. /// bool loaded = false; /// /// Are we allowed to use VBO? /// bool useVBO = true; #region OpenGL globals private uint[] VBOid = new uint[ 2 ]; // vertex array (colors, normals, coords), index array private int stride = 0; // stride for vertex array #endregion #region FPS counter long lastFpsTime = 0L; int frameCounter = 0; long triangleCounter = 0L; #endregion public Form1 () { InitializeComponent(); } private void glControl1_Load ( object sender, EventArgs e ) { loaded = true; // OpenGL init code: GL.ClearColor( Color.DarkBlue ); GL.Enable( EnableCap.DepthTest ); GL.ShadeModel( ShadingModel.Flat ); // VBO init: GL.GenBuffers( 2, VBOid ); if ( GL.GetError() != ErrorCode.NoError ) useVBO = false; SetupViewport(); Application.Idle += new EventHandler( Application_Idle ); comboTrackballType.SelectedIndex = 0; } private void glControl1_Resize ( object sender, EventArgs e ) { if ( !loaded ) return; SetupViewport(); glControl1.Invalidate(); } private void glControl1_Paint ( object sender, PaintEventArgs e ) { Render(); } private void buttonOpen_Click ( object sender, EventArgs e ) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open Scene File"; ofd.Filter = "Wavefront OBJ Files|*.obj" + "|All scene types|*.obj"; ofd.FilterIndex = 1; ofd.FileName = ""; if ( ofd.ShowDialog() != DialogResult.OK ) return; WavefrontObj objReader = new WavefrontObj(); objReader.MirrorConversion = false; StreamReader reader = new StreamReader( new FileStream( ofd.FileName, FileMode.Open ) ); int faces = objReader.ReadBrep( reader, scene ); reader.Close(); scene.BuildCornerTable(); diameter = scene.GetDiameter( out center ); scene.GenerateColors( 12 ); ResetCamera(); //labelFile.Text = String.Format("{0}: {1} faces, {2}, {3}, {4}, {5}", ofd.SafeFileName, faces, theta, v1.X, x, y); PrepareDataBuffers(); glControl1.Invalidate(); } /// /// Prepare VBO content and upload it to the GPU. /// private void PrepareDataBuffers () { if ( useVBO && scene != null && scene.Triangles > 0 ) { GL.EnableClientState( ArrayCap.VertexArray ); if ( scene.Normals > 0 ) GL.EnableClientState( ArrayCap.NormalArray ); GL.EnableClientState( ArrayCap.ColorArray ); // Vertex array: color [normal] coord GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] ); int vertexBufferSize = scene.VertexBufferSize( true, false, true, true ); GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.StaticDraw ); IntPtr videoMemoryPtr = GL.MapBuffer( BufferTarget.ArrayBuffer, BufferAccess.WriteOnly ); unsafe { stride = scene.FillVertexBuffer( (float*)videoMemoryPtr.ToPointer(), true, false, true, true ); } GL.UnmapBuffer( BufferTarget.ArrayBuffer ); GL.BindBuffer( BufferTarget.ArrayBuffer, 0 ); // Index buffer GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] ); GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)(scene.Triangles * 3 * sizeof( uint )), IntPtr.Zero, BufferUsageHint.StaticDraw ); videoMemoryPtr = GL.MapBuffer( BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly ); unsafe { scene.FillIndexBuffer( (uint*)videoMemoryPtr.ToPointer() ); } GL.UnmapBuffer( BufferTarget.ElementArrayBuffer ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 ); } else { GL.DisableClientState( ArrayCap.VertexArray ); GL.DisableClientState( ArrayCap.NormalArray ); GL.DisableClientState( ArrayCap.ColorArray ); if ( useVBO ) { GL.BindBuffer( BufferTarget.ArrayBuffer, VBOid[ 0 ] ); GL.BufferData( BufferTarget.ArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw ); GL.BindBuffer( BufferTarget.ArrayBuffer, 0 ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, VBOid[ 1 ] ); GL.BufferData( BufferTarget.ElementArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 ); } } } } } [/code]