C
Also, ich habe die Lösung. Der Fehler liegt in Zeile 69 bei dem Code der Userform, welchen ich in meinem letzten Post beschrieben habe. Hier darf NICHT in Z-Richtung transformiert werden.
Also, falscher Code:
Gl.glTranslatef((float)px - _dragPosX, (float)py - _dragPosY, (float)pz - _dragPosZ);
...und so ist es richtig:
Gl.glTranslatef((float)px - _dragPosX, (float)py - _dragPosY, (float).0);
Das Resultat sieht dann so aus:
https://youtu.be/7KsHYcBXCIM
Da solche eine Problemstellung scheinbar öfters auftaucht, hier nochmal der Code.
Userform:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tao.OpenGl;
using Tao.Platform.Windows;
namespace OwnExample
{
public unsafe partial class Form1 : Form
{
private static float _dragPosX = (float).0, _dragPosY = (float).0, _dragPosZ = (float).0;
public Form1()
{
InitializeComponent();
this.simpleOpenGlControl1.InitializeContexts();
C_OGL.AssociateOGL(this.simpleOpenGlControl1);
C_OGL.InitializeOGL();
C_OGL.ReShapeOGL();
C_OGL.Render();
}
private void simpleOpenGlControl1_SizeChanged(object sender, EventArgs e)
{
C_OGL.ReShapeOGL();
C_OGL.Render();
}
private void simpleOpenGlControl1_MouseWheel(object sender, MouseEventArgs e)
{
double s = System.Math.Exp((double)e.Delta * 0.001);
double px, py, pz;
C_OGL.UpdateOGLMatrix();
C_OGL.pos(&px, &py, &pz, e.X, e.Y, C_OGL.ViewPort);
Gl.glScalef((float)s, (float)s, (float)s);
C_OGL.Render();
C_OGL.OGL.Refresh();
}
private void simpleOpenGlControl1_MouseMove(object sender, MouseEventArgs e)
{
double px, py, pz;
int x = e.X, y = e.Y;
int dx = x - C_OGL.MouseX;
int dy = y - C_OGL.MouseY;
C_OGL.UpdateOGLMatrix();
C_OGL.pos(&px, &py, &pz, x, y, C_OGL.ViewPort);
toolStripStatusLabel1.Text = "Cursor-position (x/y/z): " + px.ToString() + " / " + py.ToString() + " / " + pz.ToString();
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
//Gl.glTranslatef((float)px - _dragPosX, (float)py - _dragPosY, (float)pz - _dragPosZ); Hier lag der Fehler!
Gl.glTranslatef((float)px - _dragPosX, (float)py - _dragPosY, (float).0);
Gl.glMultMatrixd(C_OGL.ModelViewMatrix);
}
else if (e.Button == System.Windows.Forms.MouseButtons.Left){
double ax, ay, az;
double bx, by, bz;
double angle;
double[] _MatrixInverse = new double[16];
C_OGL.InvertMatrixd(C_OGL.ModelViewMatrix, _MatrixInverse);
ax = dy;
ay = dx;
az = 0.0;
angle = C_OGL.vlen(ax, ay, az) / (double)(C_OGL.ViewPort[2] + 1) * 180.0;
bx = _MatrixInverse[0] * ax + _MatrixInverse[4] * ay + _MatrixInverse[8] * az;
by = _MatrixInverse[1] * ax + _MatrixInverse[5] * ay + _MatrixInverse[9] * az;
bz = _MatrixInverse[2] * ax + _MatrixInverse[6] * ay + _MatrixInverse[10] * az;
Gl.glRotatef((float)angle, (float)bx, (float)by, (float)bz);
}
_dragPosX = (float)px;
_dragPosY = (float)py;
_dragPosZ = (float)pz;
C_OGL.Render();
C_OGL.OGL.Refresh();
C_OGL.MouseX = x;
C_OGL.MouseY = y;
}
}
}
Klasse C_OLG:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tao.OpenGl;
using Tao.Platform.Windows;
namespace OwnExample
{
public static unsafe class C_OGL
{
public static int w = 0, h = 0;
public static SimpleOpenGlControl OGL = null;
private static double xMin = -.75, xMax = .75;
private static double yMin = -.5, yMax = 1.2;
private static double zMin = -1.0, zMax = 0.5;
public static double OGLleft = .0, OGLright = .0, OGLtop = .0, OGLbottom = .0;
public static double OGLzNear = -10.0, OGLzFar = 10.0;
public static double[] ModelViewMatrix = new double[16];
public static double[] ProjectionMatrix = new double[16];
public static double[] InvModelViewMatrix = new double[16];
public static int[] ViewPort = new int[4];
public static int MouseX = 0, MouseY = 0;
public static void AssociateOGL(SimpleOpenGlControl fOGL)
{
OGL = fOGL;
}
public static void ClearScreen()
{
Gl.glClearColor((float)1.0, (float)1.0, (float)1.0, (float)1.0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
}
public static void Render()
{
double[] ColRed = new double[4] { 1.0, 0.0, 0.0, 1.0 };
double[] ColGreen = new double[4] { 0.0, 1.0, 0.0, 1.0 };
double[] ColBlue = new double[4] { 0.0, 0.0, 1.0, 1.0 };
ClearScreen();
#region DrawCube
Gl.glColor4dv(ColRed);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMin, yMin, zMin);
Gl.glVertex3d(xMin, yMin, zMax);
Gl.glVertex3d(xMin, yMax, zMax);
Gl.glVertex3d(xMin, yMax, zMin);
Gl.glEnd();
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMax, yMin, zMin);
Gl.glVertex3d(xMax, yMin, zMax);
Gl.glVertex3d(xMax, yMax, zMax);
Gl.glVertex3d(xMax, yMax, zMin);
Gl.glEnd();
Gl.glColor4dv(ColGreen);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMin, yMax, zMin);
Gl.glVertex3d(xMin, yMax, zMax);
Gl.glVertex3d(xMax, yMax, zMax);
Gl.glVertex3d(xMax, yMax, zMin);
Gl.glEnd();
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMin, yMin, zMin);
Gl.glVertex3d(xMin, yMin, zMax);
Gl.glVertex3d(xMax, yMin, zMax);
Gl.glVertex3d(xMax, yMin, zMin);
Gl.glEnd();
Gl.glColor4dv(ColBlue);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMin, yMax, zMin);
Gl.glVertex3d(xMax, yMax, zMin);
Gl.glVertex3d(xMax, yMin, zMin);
Gl.glVertex3d(xMin, yMin, zMin);
Gl.glEnd();
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(xMin, yMax, zMax);
Gl.glVertex3d(xMax, yMax, zMax);
Gl.glVertex3d(xMax, yMin, zMax);
Gl.glVertex3d(xMin, yMin, zMax);
Gl.glEnd();
#endregion DrawCube
Gl.glFinish();
}
public static void UpdateOGLMatrix()
{
Gl.glGetIntegerv(Gl.GL_VIEWPORT, ViewPort);
Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, ModelViewMatrix);
Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, ProjectionMatrix);
}
public static void InitializeOGL()
{
Gl.glEnable(Gl.GL_DOUBLEBUFFER);
Gl.glEnable(Gl.GL_DEPTH_TEST);
}
public static void ReShapeOGL()
{
Gl.glViewport(0, 0, OGL.Size.Width, OGL.Size.Height);
OGLtop = 1.0;
OGLbottom = -1.0;
OGLleft = -(double)OGL.Size.Width / (double)OGL.Size.Height;
OGLright = -OGLleft;
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(OGLleft, OGLright, OGLbottom, OGLtop, OGLzNear, OGLzFar);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
}
public static void pos(double *px,double *py,double *pz, int x, int y, int[] viewport)
{
*px = (double)(x-viewport[0])/(double)(viewport[2]);
*py = (double)(y-viewport[1])/(double)(viewport[3]);
*px = OGLleft + (*px)*(OGLright-OGLleft);
*py = OGLtop + (*py)*(OGLbottom-OGLtop);
*pz = OGLzNear;
}
public static double vlen(double x, double y, double z) { return System.Math.Sqrt(x * x + y * y + z * z); }
public static bool InvertMatrixd(double[] m, double[] invOut)
{
double[] inv = new double[16];
double det;
int i;
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15]
+ m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15]
- m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15]
+ m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14]
- m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15]
- m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15]
+ m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15]
- m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14]
+ m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15]
+ m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15]
- m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15]
+ m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14]
- m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11]
- m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11]
+ m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11]
- m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10]
+ m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
invOut[i] = inv[i] * det;
return true;
}
}
}
Und wer das einfach kopieren will: Ihr müsst natürlich noch einen Verweis auf Tao.OpenGl und Tao.Platform.Window erstellen.