在c#中使用Opentk绘制XY和Z的方格。 现在如何使用光线投射方法在网格上选取一个点。 如何在方块上获得与鼠标坐标相关的点。 任何帮助将不胜感激。
视口如下:
private void SetupViewport()
{
int w = m_OpenTKGLControl_DrawingArea.Width;
int h = m_OpenTKGLControl_DrawingArea.Height;
// prevent divide by 0 error when minimised
if (w == 0)
h = 1;
GL.Viewport(0, 0, w, h);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
perspectiveGL(45, (double)w / h, 0.1, 10000);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
}
这是透视功能:
// Replaces gluPerspective. Sets the frustum to perspective mode.
// fovY - Field of vision in degrees in the y direction
// aspect - Aspect ratio of the viewport
// zNear - The near clipping distance
// zFar - The far clipping distance
void perspectiveGL(double fovY, double aspect, double zNear, double zFar)
{
const double pi = 3.1415926535897932384626433832795;
double fW, fH;
fH = System.Math.Tan((fovY / 2) / 180 * pi) * zNear;
fH = System.Math.Tan(fovY / 360 * pi) * zNear;
fW = fH * aspect;
GL.Frustum(-fW, fW, -fH, fH, zNear, zFar);
}
这是glcontrol的绘画功能
private void m_OpenTKGLControl_DrawingArea_Paint(object sender, PaintEventArgs e)
{
if (!loaded) // Play nice
return;
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
GL.LoadIdentity();
GL.Translate(0, 0, -zoom);
GL.Translate(tx, ty, 0);
GL.Rotate(rotx, 1, 0, 0);
GL.Rotate(roty, 0, 1, 0);
//if (m_pointT_current_cursor.X < 100)
{
GL.PushMatrix(); //set where to start the current object transformations
GL.Color3(1.0, 1.0, 0);
GL.Begin(BeginMode.Lines);
GL.Vertex3(0.0, 0.0, 0.0);
GL.Vertex3(0.0, 0.0, 10.0);//x axis
GL.End();
GL.PopMatrix();
}
double grid_width = 10.0;
// Draw a white grid "floor" for the tetrahedron to sit on.
GL.Color3(Color.FromArgb(68, 68, 68));
GL.Begin(BeginMode.Lines);
for (double i = -grid_width / 2.0; i <= grid_width / 2.0; i += 1.0)
{
if (i != 0.0)
{
GL.Vertex3(i, 0.0, grid_width / 2.0); GL.Vertex3(i, 0.0, -grid_width / 2.0);
GL.Vertex3(grid_width / 2.0, 0.0, i); GL.Vertex3(-grid_width / 2.0, 0.0, i);
}
}
GL.End();
GL.Color3(1.0, 0, 0);
GL.Begin(BeginMode.Lines);
GL.Vertex3(-grid_width / 2.0, 0, 0); GL.Vertex3(grid_width / 2.0, 0, 0);//x axis
GL.End();
GL.Color3(0, 1.0, 0);
GL.Begin(BeginMode.Lines);
GL.Vertex3(0, -grid_width / 2.0, 0); GL.Vertex3(0, grid_width / 2.0, 0);//y axis
GL.End();
GL.Color3(0, 0, 1.0);
GL.Begin(BeginMode.Lines);
GL.Vertex3(0, 0, -grid_width / 2.0); GL.Vertex3(0, 0, grid_width / 2.0);//z axis
GL.End();
GL.Begin(BeginMode.Points); // Draw The Cube Using quads
for (int i = 0; i < m_list_point_cloud.Count(); i++)
{
GL.Color3(Color.FromArgb(m_list_point_cloud[i].RED, m_list_point_cloud[i].GREEN, m_list_point_cloud[i].BLUE)); // Color
GL.Vertex3(m_list_point_cloud[i].X, m_list_point_cloud[i].Y, m_list_point_cloud[i].Z);
GL.PointSize(1);
}
GL.End(); // End Drawing The Point cloud
GL.Flush();
m_OpenTKGLControl_DrawingArea.SwapBuffers();
}
最后这是glcontrol的加载函数
private void m_OpenTKGLControl_DrawingArea_Load(object sender, EventArgs e)
{
loaded = true;
GL.CullFace(CullFaceMode.Back);
GL.ClearColor(Color.FromArgb(57, 57, 57));
GL.ClearDepth(1.0); // Enables Clearing Of The Depth Buffer
GL.DepthFunc(DepthFunction.Lequal); // The Type Of Depth Test To Do
GL.Enable(EnableCap.DepthTest); // Enables Depth Testing
GL.Enable(EnableCap.Multisample);
GL.ShadeModel(ShadingModel.Smooth); // Enables Smooth Color Shading
GL.Hint(HintTarget.PerspectiveCorrectionHint, // Really Nice Perspective Calculations
HintMode.Nicest);
SetupViewport();
}
答案 0 :(得分:0)
这是c中有一些变化的代码。 资料来源:{https://sites.google.com/site/vamsikrishnav/gluunproject}
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#define HEIGHT 580
#define WIDTH 1000
double objx = 0, objy=0, objz=0;
/*THE FUNCTION TO DRAW THE STUFF ON THE SCREEN*/
void display( )
{
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
glPushMatrix( );
//glScalef(2.0f,2.0f,2.0f);
glRotatef(90,1.0f,3.0f,2.0f); //rotating object continuously by 2 degree
//The big green floor like polygon
glBegin( GL_POLYGON );
glColor3f( 0, 1, 0 );
glVertex3f( -100, 0, 100 );
glVertex3f( -100, 0, -100 );
glVertex3f( 100, 0, -100 );
glVertex3f( 100, 0, 100 );
glEnd( );
glPopMatrix( );
//The red cube to be drawn at clicked position
glPushMatrix( );
glColor3f( 1, 0, 0 );
glTranslatef( objx, objy, objz );
glRotatef(90,1.0f,3.0f,2.0f); //rotating object continuously by 2 degree
glutSolidTeapot( 10 );
glPopMatrix( );
glFlush( );
glutSwapBuffers( );
}
void mouse( int button, int state, int x, int y)
{
double modelview[16], projection[16];
int viewport[4];
float z = 1;
/*Read the projection, modelview and viewport matrices
using the glGet functions.*/
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetIntegerv( GL_VIEWPORT, viewport );
//Read the window z value from the z-buffer
glReadPixels( x, viewport[3]-y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z );
//Use the gluUnProject to get the world co-ordinates of
//the point the user clicked and save in objx, objy, objz.
gluUnProject( x, viewport[3]-y, z, modelview, projection, viewport, &objx, &objy, &objz );
}
void keyboard( unsigned char key, int x, int y )
{
}
void init( int width, int height )
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective( 45, 1.33, 0.1, 400 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
gluLookAt( 0, 100, 200, 0, 0, 0, 0, 1, 0 );
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
//The most important part specify the things your
//glut window should provide
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize( 640, 480 );
glutCreateWindow("HI");
glClearColor( 0, 0, 0, 0 );
//enable z buffer
glEnable( GL_DEPTH_TEST );
//set the value in z-buffer as 1.0
glClearDepth( 1.0 );
init( 640, 480 );
glutDisplayFunc( display );
glutReshapeFunc( init );
glutIdleFunc( display );
glutMouseFunc( mouse );
glutKeyboardFunc( keyboard );
glutMainLoop( );
}