地月系3D-OPENGL

本文介绍如何使用CSGL开源框架构建一个简单的3D地球模型,并演示了纹理加载、光照设置及基本几何体绘制的过程。
2
使用CSGL开源框架来做这个系统,主要需要注意一些基本调用。这里都已经封装了起来。
此外注意Drawtexture(int index) ,如果里边的GL.glTexParameteri参数不适当,也可能引起无法正常显示的情况。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using CsGL.OpenGL;


namespace USTC
{
    class OpenGlTool
    {

        private uint[] texture;
        private uint[] Textures_dispList;

        public OpenGlTool(int n)
        {
         
            texture = new uint[n];
            Textures_dispList = new uint[n];
            GL.glGenTextures(1, texture);
        }
    
        /// 
        /// 载?入?第?几?个?索?引?图?
        /// 
        /// 文?件?名?
        /// 绑?定?UNIT指?针?索?引?,?代?表?第?几?幅?素?材?图?
        /// 
  
        public void loadBit(int index, string fileName)
        {

            //string fileName = "image/earth.bmp";
            GL.glNewList(Textures_dispList[index] = GL.glGenLists(1), GL.GL_COMPILE_AND_EXECUTE);
            GL.glBindTexture(GL.GL_TEXTURE_2D, texture[index]);
            Bitmap img = new Bitmap(fileName);
            Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
            BitmapData tex = img.LockBits(rect, ImageLockMode.ReadOnly,
                System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, (int)GL.GL_RGB8,
                img.Width, img.Height,
                0, GL.GL_BGRA_EXT, GL.GL_UNSIGNED_BYTE, tex.Scan0);
            img.UnlockBits(tex);
            GL.glEndList();

            //     GL.glTexParameteri(GL.GL_TEXTURE_2D,   GLTexParamPName.TextureMinFilter, GLTextureFilter.Linear);
            //     GL.glTexParameteri(GL.GL_TEXTURE_2D,   GLTexParamPName.TextureMagFilter,  GLTextureFilter.Linear);
            //绑?定?我?们?之?前?定?义?好?的?纹?理?

            //用?于?自?动?纹?理?映?射?的?二?次?曲?面?对?象?

            //绘?制?半?径?为?.3 的?球?体?,?同?时?使?用?



        }

        /// 
        /// 绑?定?UNIT指?针?索?引?,?代?表?第?几?幅?素?材?图?
        /// 
        /// 
        public void Drawtexture(int index)
        {
            GL.glBindTexture(GL.GL_TEXTURE_2D, texture[index]);
            //GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
            // GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            //  GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            //   GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
        }
        public void sunshare()
        {
            //开?启?光?照?渲?染?
            GL.glEnable(GL.GL_LIGHTING);
            //设?置?光?源?属?性?
            float[] light_ambient = { 0.7F, 0.0F, 0.0F, 1.0F };//R,G,B,ALPHA
            float[] light_diffuse = { 0.5F, 0F, 0F, 0.5F };
            //指?定?光?源?的?位?置?
            float[] light_position = { 0.0F, 0.0F, 10.0F, 1.0F };
            //用?定?义?好?的?光?源?属?性?给?指?定?光?源?GL_LIGHT0 进?行?设?置?
            GL.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient);
            GL.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_diffuse);
            GL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position);
            //开?启?设?置?的?光?源?GL_LIGHT0
            GL.glEnable(GL.GL_LIGHT0);
            //镜?面?反?射?
            // float[] planet_specular  = { 0.5F , 0.5F , 0.5F , 0.5F };
            // GL.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, planet_specular);
            //打?开?全?局?光?照?
            // GL.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, light_ambient);

        }
        #region 画?几?何?体?
        /// 
        /// 画?正?方?体?
        /// 
        public void Esquare()
        {

            GL.glBegin(GL.GL_QUAD_STRIP);//
            GL.glVertex3f(0.0f, 0.0f, 0.0f);//a0点?
            GL.glVertex3f(0.0f, 1.0f, 0.0f);//a1点?
            GL.glVertex3f(1.0f, 0.0f, 0.0f);//b0点?
            GL.glVertex3f(1.0f, 1.0f, 0.0f);//b1点?
            GL.glVertex3f(1.0f, 0.0f, -1.0f);//c0点?
            GL.glVertex3f(1.0f, 1.0f, -1.0f);//c1点?
            GL.glVertex3f(0.0f, 0.0f, -1.0f);//d0点?
            GL.glVertex3f(0.0f, 1.0f, -1.0f);//d1点?
            GL.glVertex3f(0.0f, 0.0f, 0.0f);//a0点?
            GL.glVertex3f(0.0f, 1.0f, 0.0f);//a1点?
            GL.glEnd();

            GL.glBegin(GL.GL_POLYGON);//
            GL.glVertex3f(0.0f, 0.0f, 0.0f);//a0点?
            GL.glVertex3f(1.0f, 0.0f, 0.0f);//b0点?
            GL.glVertex3f(1.0f, 0.0f, -1.0f);//c0点?
            GL.glVertex3f(0.0f, 0.0f, -1.0f);//d0点?
            GL.glVertex3f(0.0f, 1.0f, 0.0f);//a1点?
            GL.glVertex3f(1.0f, 1.0f, 0.0f);//b1点?
            GL.glVertex3f(1.0f, 1.0f, -1.0f);//c1点?
            GL.glVertex3f(0.0f, 1.0f, -1.0f);//d1点?
            GL.glEnd();
        }
        #endregion
    }
}
 
调用类:
using System;
using System.Collections.Generic;
using System.Text;
using CsGL.OpenGL;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Exocortex;

namespace Solar_system
{
    class SolarSystemView : OpenGLControl
    {
        private static int year = 0, day = 0, day1 = 0;
        USTC.OpenGlTool tool;
        GLUquadric g_text = GL.gluNewQuadric();

        protected override void InitGLContext()
        {
            GLU.gluQuadricNormals(g_text, GLU.GLU_SMOOTH);
            GLU.gluQuadricOrientation(g_text, GLU.GLU_OUTSIDE);
            GLU.gluQuadricTexture(g_text, (byte)GL.GL_TRUE);
            GLU.gluQuadricDrawStyle(g_text, GLU.GLU_FILL);
            base.InitGLContext();
            GL.glEnable(GL.GL_DEPTH_TEST);
            GL.glDepthFunc(GL.GL_LESS);

            GL.glEnable(GL.GL_BLEND);
            GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
            //GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glEnable(GL.GL_TEXTURE_2D);
             tool = new USTC.OpenGlTool(1);
            //如?果?是?多?个?贴?图?,?下?边?将?是?多?个?载?入?loadBit
            tool.loadBit(0, "image/earth.bmp");
            //sunshare();
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            //得?到?当?前?屏?幕?尺?寸?
            GL.glViewport(0, 0, Size.Width, Size.Height);
            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();
            GL.gluPerspective(60, Size.Width / Size.Height, 1, 30);
            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();
            GL.gluLookAt(0, 5, 15, 0, 0, 0, 0, 2, 0);
        }

        public override void glDraw()
        {
            base.glDraw();
          

            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
          
            GL.glEnable(GL.GL_BLEND);
           
            tool.Drawtexture(0);
            GL.gluSphere(g_text, 2, 30, 30);//半?径?为?
            //绘?制?地?月?系?
           
            GL.glPushMatrix();
            GL.glRotated(year, 0, 1, 0);//绕?y轴?转?动?
            GL.glTranslated(5, 0, 0);//平?移?个?单?位?
            //绘?制?地?球?
 
            GL.glPushMatrix();
            GL.glRotated(day, 0, 1, 0);//绕?y轴?转?动?
           // GL.glColor3f(0, 0, 1);
            tool.Drawtexture(0);
           
           
            GL.gluSphere(g_text,0.6, 12, 12);
            GL.glPopMatrix();
           
            //绘?制?月?球?
            GL.glRotated(day1, 0, 1, 0);//绕?y轴?转?动?
            GL.glTranslated(1, 0, 0);
            GL.glRotated(day1, 0, 1, 0);//绕?y轴?转?动?
       
            GL.glutWireSphere(0.1, 6, 6);
            GL.glPopMatrix();
            GL.glDisable(GL.GL_BLEND);
        


            year = year > 360 ? (year % 360 + 1) : (year + 1);
            day = day > 360 ? (day % 360 + 5) : (day + 5);
            day1 = day1 > 360 ? (day1 % 360 + 20) : (day1 + 20);
            OnSizeChanged(null);//使?显?示?更?加?流?畅?


        }
     
    }
}

调用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using CsGL.OpenGL;
using Solar_system;

namespace test2
{
    public partial class Form1 : Form
    {
        private static Thread thrDraw;
        private SolarSystemView view;

        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            this.view = new SolarSystemView();
            this.view.Parent = this;

            this.view.Dock = System.Windows.Forms.DockStyle.Fill;
           

            //this.Controls.Add(this.view);

        }

        private void OpenGL_Start()
        {
            while (true)
            {
                this.view.Refresh();
                Thread.Sleep(80);
            }
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadStart start = new ThreadStart(OpenGL_Start);
            thrDraw = new Thread(start);
            thrDraw.Start();
        }

   
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值