public static void Trans3D(SharpGL.OpenGL gl_object, int x, int y) { //Console.Write(_RoX + ", " + _RoY + ", " + " => "); // Create an array that will be the viewport. //3D顯示大小 int[] viewport = new int[4]; // Get the viewport, then convert the mouse point to an opengl point. gl_object.GetInteger(OpenGL.GL_VIEWPORT, viewport); double[] modelview = new double[16]; gl_object.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, modelview); double[] projection = new double[16]; gl_object.GetDouble(OpenGL.GL_PROJECTION_MATRIX, projection); float winX, winY; winX = (x - viewport[2] / 2); winY = (y - viewport[3] / 2); //與範例不同的是 圖形原點是左上角 //Console.Write(winX + ", " + winY + ", " + " => "); //(posX, posY, posZ) 轉換之前的座標 /* double[] posX = new double[4]; * double[] posY = new double[4]; * double[] posZ = new double[4];*/ double posX = new double(); double posY = new double(); double posZ = new double(); gl_object.UnProject(x, y, 0, modelview, projection, viewport, ref posX, ref posY, ref posZ); isNav = 1; if (_RoX >= 165 && _RoX <= 200) { //if (winX * posX[0] < 0 && winY * posY[0] < 0) isNav = -1; if (winX * posX < 0 && winY * posY < 0) { isNav = -1; } } else if (_RoX >= 45 && _RoX <= 315) { //if (winX * posX[0] > 0) isNav = -1; if (winX * posX > 0) { isNav = -1; } } return; }
/// <summary> /// Gets the texture matrix. /// </summary> /// <param name="gl">The gl.</param> /// <returns></returns> public static Matrix GetTextureMatrix(this OpenGL gl) { // Get the matrix. double[] matrix = new double[16]; gl.GetDouble(OpenGL.GL_TEXTURE_MATRIX, matrix); return(Matrix.FromColumnMajorArray(matrix, 4, 4)); }
/// <summary> /// Gets the projection matrix. /// </summary> /// <param name="gl">The gl.</param> /// <returns></returns> public static Matrix GetProjectionMatrix(this OpenGL gl) { // Get the matrix. double[] matrix = new double[16]; gl.GetDouble(OpenGL.GL_PROJECTION_MATRIX, matrix); return(Matrix.FromColumnMajorArray(matrix, 4, 4)); }
/// <summary> /// Gets the model view matrix. /// </summary> /// <param name="gl">The gl.</param> /// <returns></returns> public static Matrix GetModelViewMatrix(this OpenGL gl) { // Get the matrix. double[] matrix = new double[16]; gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, matrix); return(Matrix.FromColumnMajorArray(matrix, 4, 4)); }
/// <summary> /// This is a SharpGL helper version, that projects the vertex passed, using the /// current matrixes. /// </summary> /// <param name="gl">The gl.</param> /// <param name="vertex">The object coordinates.</param> /// <returns> /// The screen coords. /// </returns> public static Vertex Project(this OpenGL gl, Vertex vertex) { // THIS CODE MUST BE TESTED double[] modelview = new double[16]; double[] projection = new double[16]; int[] viewport = new int[4]; gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, modelview); gl.GetDouble(OpenGL.GL_PROJECTION_MATRIX, projection); gl.GetInteger(OpenGL.GL_VIEWPORT, viewport); double[] x = new double[1]; // kludgy double[] y = new double[1]; double[] z = new double[1]; gl.Project(vertex.X, vertex.Y, vertex.Z, modelview, projection, viewport, x, y, z); return(new Vertex((float)x[0], (float)y[0], (float)z[0])); }
/// <summary> /// Renders the specified scene. /// </summary> /// <param name="scene">The scene.</param> /// <param name="camera">The camera.</param> /// <returns> /// The scene rendered with raytracing. /// </returns> public Image Render(Scene scene, Camera camera) { // Useful references. OpenGL gl = scene.OpenGL; // First, we need the matricies and viewport. double[] modelview = new double[16]; double[] projection = new double[16]; int[] viewport = new int[4]; gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, modelview); gl.GetDouble(OpenGL.GL_PROJECTION_MATRIX, projection); gl.GetInteger(OpenGL.GL_VIEWPORT, viewport); int screenwidth = viewport[2]; int screenheight = viewport[3]; // From frustum data, we make a screen origin, and s/t vectors. Vertex s = new Vertex(0, 0.03f, 0); Vertex t = new Vertex(0, 0, 0.05f); Vertex vScreenOrigin = new Vertex(0, 0, 5); // Go through every pixel we have, and convert it into a screen pixel. ScreenPixel[] pixels = new ScreenPixel[viewport[2] * viewport[3]]; for (int y = 0; y < screenheight; y++) { for (int x = 0; x < screenwidth; x++) { // Get plane coordinates first of all. int planeX = x - (screenwidth / 2); int planeY = y - (screenwidth / 2); float worldX = vScreenOrigin.X + (planeX * t.X) + (planeY * s.X); float worldY = vScreenOrigin.Y + (planeX * t.Y) + (planeY * s.Y); float worldZ = vScreenOrigin.Z + (planeX * t.Z) + (planeY * s.Z); // Finally, pack all that data into a ScreenPixel. ScreenPixel pixel = new ScreenPixel(); pixel.x = x; pixel.y = y; pixel.worldpos = new Vertex(worldX, worldY, worldZ); pixel.ray.origin = camera.Position; pixel.ray.direction = pixel.worldpos - camera.Position; pixels[(y * viewport[2]) + x] = pixel; } } // Create the resulting bitmap. System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(viewport[2], viewport[3]); // Now go through every ray and test for intersections. int pixelcounter = 0; int pixelcount = viewport[2] * viewport[3]; foreach (ScreenPixel pix in pixels) { // Raytrace the polygons. Intersection closest = new Intersection(); foreach (var raytracable in scene.SceneContainer.Traverse(se => se is IRayTracable)) { Intersection i = ((IRayTracable)raytracable).Raytrace(pix.ray, scene); if (i.intersected && (closest.intersected == false || i.closeness < closest.closeness)) { closest = i; } } if (closest.intersected == true) { System.Console.WriteLine("i = {0}, only {1} left!\n", closest.closeness, pixelcount - pixelcounter); } bmp.SetPixel(pix.x, pix.y, pix.ray.light); pixelcounter++; } // Return the ray traced imag. return(bmp); }