从0开发游戏引擎之引擎Win32平台的Platform类实现

简介: WndProc函数是注册进操作系统的回调,监听了用户的鼠标键盘响应事件,收到后丢给场景管理器去处理了系统传过来的事件。

3.Run起来!初始化都完成之后,程序当然就要Run起来了,这个引擎其实只能说是一个Demo引擎,逻辑线程和渲染线程当时给放到一块儿了,Render函数里其实不光是做了DrawElement这件事儿,而且还做了逻辑的update这件事儿,所以现在要我做的话肯定要分两个线程来做,而且Render里面的Update函数也得拆出来。每次循环都会Clear颜色缓冲区和深度缓冲区,清理了前台缓冲区后,立马使用SwapBuffers把后台的缓冲区交换到前台来,这样可以保证画面不会出现闪屏的现象。


void CPlateForm::run()
{
  U3D::CEngineButton::getInstance()->InitAll();
  U3D::CResouceManage::getInstance()->Init();
  U3D::CResourceCompound::getInstance()->init();
  CEffects::getInstance()->init();
  label = new U3D::CUI_Label("A","宋体",24);
  //1:m_pos 2:m_ssssslook 3:m_up 4:m_right
  Vector3D pos[4] = {
  { Vector3D(0,500,0)},
  { Vector3D(0,0,1) },
  { Vector3D(0,1,0) },
  { Vector3D(1,0,0) } };
  godCamera = new freeCamera(pos);
  godCamera->rightRotate(90);
  LARGE_INTEGER nFreq;
  QueryPerformanceFrequency(&nFreq);
  LARGE_INTEGER nAnimationInterval;
  nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
  LARGE_INTEGER nLast;
  LARGE_INTEGER nNow;
  QueryPerformanceCounter(&nLast);
  ZeroMemory(&msg, sizeof(msg));
  while (msg.message != WM_QUIT)
  {
    if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
      QueryPerformanceCounter(&nNow);
      if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
      {
        nLast.QuadPart = nNow.QuadPart;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // 清除屏幕和深度缓存
        Render();
        SwapBuffers(hDC);                     // 交换缓存 (双缓存)
      }
      else { Sleep(0); }continue;
    }
    TranslateMessage(&msg);                             //翻译消息
    DispatchMessage(&msg);  
                            //分发消息
  }
}


3.1 这个Render不一般,里面既实现了不同的模式下对透视矩阵和正交矩阵的切换,也实现了引擎的update,还实现了输入控制器的刷新。


1.GLvoid CPlateForm::Render()
{
  if (Input::getKeyDown(VK_TAB))
    gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
  if (currentEnvironment == NIGHT)
    selectNight();
  else if (currentEnvironment == DAYTIME)
    selectDaytime();
  switch (gameMode)
  {
  case TIELEMODE:
  {
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else
      U3D::CSceneManage::getInstance()->pause(updateTime());
    select2DSpace();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  case EDITMODE:
  {
    glViewport(0, 0, 840, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    godCamera->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else
      U3D::CSceneManage::getInstance()->pause(updateTime());
    godCamera->drawFrustum();
    if (Fog)
      glEnable(GL_FOG);
    else
      glDisable(GL_FOG);
    /
    //右边2d
    glViewport(840, 0, 440, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, 440, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->drawDebug();
    U3D::CEngineButton::getInstance()->_draw();
    glPushMatrix();
    glLoadIdentity();
    label->setString("0l,2,3切换图片,右击存");
    label->setPosition(850, 0, 1);
    label->draw();
    label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
    label->setPosition(850, 30, 0);
    label->draw();
    label->setString("小键盘0开关线段模式");
    label->setPosition(850, 60, 0);
    label->draw();
    label->setString("当前渲染对象数量:%d", objNumber);
    label->setPosition(850, 90, 0);
    label->draw();
    label->setString("TAB:开/关编辑模式");
    label->setPosition(850, 120, 0);
    label->draw();
    label->setString("FPS:%f", getFPS());
    label->setPosition(850, 150, 0);
    label->draw();
    glColor4f(1,1,1,1);
    glPopMatrix();
    if (Input::getKeyDown(VK_F2))
      light = light == false ? 1 : 0;
    if (Input::getKeyDown(VK_F3))
      Fog = Fog == false ? 1 : 0;
    if (Input::getKeyDown(VK_NUMPAD0))
      lines = lines == false ? true : false;
    if (light)
    {
      glEnable(GL_LIGHTING);  glEnable(GL_LIGHT0);
    }
    else
    {
      glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
    }
    if (lines)
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    else
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }break; 
  case IN_SPACE:
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  case FALLING://陨落的场景
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
  }break;
  case PLAYING:
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    //partic->draw(0.2);
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
    label->setString("-FPS:%f", getFPS());
    label->setPosition(0, 920, 0);
    label->draw();
  }break;
  case FLY://逃离这个星球
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    label->setString("-FPS:%f", getFPS());
    label->setPosition(0, 920, 0);
    label->draw();
  }break;
  case END://结尾的场景
  {
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  }
  Input::flush();
}


4.WndProc函数是注册进操作系统的回调,监听了用户的鼠标键盘响应事件,收到后丢给场景管理器去处理了系统传过来的事件。


LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
  U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
  switch (message)
  {
  case WM_ACTIVATE:
  case WM_SIZE:
    switch (wParam)
    {
    case SIZE_MINIMIZED:
      break;
    }
    break;
  case WM_RBUTTONDOWN:
    oldMousePos.x= LOWORD(lParam);
    oldMousePos.y= HIWORD(lParam);
    _mouseIsDown = true;
    break;
  case WM_MOUSEMOVE:
  {
    mousePos.x = LOWORD(lParam);
    mousePos.y = HIWORD(lParam);
    if (_mouseIsDown)
    {
      offset= oldMousePos - mousePos;
    }
    oldMousePos = mousePos;
  }break;
  case WM_RBUTTONUP:
    _mouseIsDown = false;
    break;
  case WM_KEYDOWN:
  {
    switch (wParam)
    {
      break;
    case VK_F1:
      isDebug = true;
      break;
    case VK_F2:
      break;
    case VK_F3:break;
    case VK_F11:break;
    case VK_F12:break;
    }
  }break;
  case WM_CLOSE:
  {
    getInstance()->KillGLWindow();
    delete Instance;
    PostQuitMessage(0);
  }break;
  return DefWindowProc(hWnd, message, wParam, lParam);
}


完整代码(Platform.h)


#pragma once
#define _WINDOW_WID_ 1280.0f
#define _WINDOW_HEI_ 960.0f
enum ENVIRONMENT  //环境:白天和晚上
{
  DAYTIME,
  NIGHT
};
enum GameMode   //游戏模式:
{
  TIELEMODE,
  IN_SPACE,   //在宇宙里
  FALLING,    //落下
  PLAYING,    //在玩
  EDITMODE,   //编辑模式
  FLY,      //飞走(后面会是END)
  DEAD,     //死亡
  END       //结束(胜利以后的)
};
class CPlateForm
{
private:
  U3D::CUI_Label *label;
  GameMode gameMode;
  ENVIRONMENT currentEnvironment=DAYTIME;   //当前环境默认是白天
private:
  int AxisMode = 1;       //轴模式 拖动:1 缩放:3 旋转:3
  int objNumber = 0; 
private:
  const int FPS =120;   //FPS每一秒60帧
  HINSTANCE hInst;    // 当前实例
  HGLRC     hRC;      // 窗口着色描述表句柄
  HDC       hDC;      // OpenGL渲染描述表句柄
  HWND      hWnd;     // 保存我们的窗口句柄
  MSG     msg;      //消息
  static wchar_t IcoName; //Icona名字
  static bool isPause;    //游戏暂停
  static int windows_width;
  static int windows_height;
  static int window_x;
  static int window_y;
  bool isAutoSort = false;
  static bool isDebug;
  static bool _mouseIsDown;
  bool g_fVBOSupported = false;//是否支持顶点缓存 
  static CPlateForm*Instance;
public:
  CAudio4Bass m_Audio;
  int m_MusicIndex;
  static Vector2 mousePos;
  static Vector2 oldMousePos;
  static Vector2  offset;
  freeCamera *godCamera;
  ///Other/
  void  run();
  float updateTime();                       //时间差:秒
  void initObjNum() { objNumber = 0; }
  void Resume() { isPause = false; }  //恢复
  void Pause() { isPause = true; }  //暂停
  void InitGeometry();
  GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
  GLboolean InitGL(GLvoid);
  GLvoid KillGLWindow(GLvoid);
  GLvoid Render();
  ATOM MyRegisterClass();
  int getObjNumber() { return objNumber; }
  BOOL InitInstance();
  void OpenEditor();
  Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y);
  bool IsExtensionSupported(char* szTargetExtension);
  static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  ///Set/
  static void setIco(wchar_t ico) { IcoName = ico; }
  static void setWindowSize(int x, int y, int wid, int hei);
  void setGameMode(GameMode mode);
  void setObjNumber(int n) { this->objNumber = n; }
  void setAutoSort(bool autoSort);
  void setAxisMode(int Axis);
  void setEnvironment(ENVIRONMENT V){this->currentEnvironment=V;}
  ///Get///
  static CPlateForm *getInstance();
  float getFPS();
  HDC getHdc() { return hDC; }
  HWND getHwnd() { return hWnd; }
  UINT Get_win_width() { return windows_width; }
  UINT Get_win_height() { return windows_height; }
  bool getIsDebugMode();
  bool getAutoSort();
  CAudio4Bass getAudioBass() { return m_Audio; }
  bool getMouseIsDown();
  bool getfVBOSupported() { return g_fVBOSupported; }
  int getAxisMode();
  GameMode getGameMode();
  ENVIRONMENT getEnvironment(){return currentEnvironment;}
  void select2DSpace();
  void select3DSpace();
  sColor selectDaytime();
  sColor selectNight();
  CPlateForm();
  ~CPlateForm();
};


完整代码Platform.cpp


#include "Engine.h"
#include "resource.h"
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
bool CPlateForm::isPause = false;
int CPlateForm::windows_width = 1080;
int CPlateForm::windows_height = 720;
int CPlateForm::window_x = 0;
int CPlateForm::window_y = 0;
wchar_t CPlateForm::IcoName=NULL;
CPlateForm*CPlateForm::Instance = NULL;
bool CPlateForm::isDebug = false; 
bool CPlateForm::_mouseIsDown = false;
Vector2 CPlateForm::mousePos;
Vector2 CPlateForm::oldMousePos;
Vector2 CPlateForm::offset;
// 
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
CPlateForm::CPlateForm()
{
  hRC = NULL;
  hDC = NULL;
  hWnd = NULL;
  hInst = NULL;
  isPause = false;
  gameMode = PLAYING;
  ShowWindow(hWnd, SW_SHOWDEFAULT);
  UpdateWindow(hWnd);
  MyRegisterClass();// 执行应用程序初始化: 
  if (!InitInstance())
  {
    MessageBox(NULL, L"不能成功初始化", L"错误", MB_OK | MB_ICONEXCLAMATION);
  }
  HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(NULL));
  memset(&msg, 0, sizeof(MSG));
  /*char *MusicList[5] = { "res/小酒窝.mp3","res/爱.mp3","res/爱要怎么说出口.mp3"
      ,"res/江南.mp3","res/Where Them Girls At.mp3" };
    m_Audio.Initialize(0);
    for (int i = 0;i < 5;i++)
    {
      m_MusicIndex = m_Audio.LoadFile(MusicList[i], BASS_MUSIC_FLOAT);
    }
    MusicLen=m_Audio.ChannelBytes2Seconds(m_MusicIndex, m_Audio.GetChannelLength(m_MusicIndex, BASS_MUSIC_LOOP));
    m_Audio.ChannelPlay(m_MusicIndex, true);*/
  m_Audio.Initialize(hWnd);
  //m_MusicIndex = m_Audio.LoadFile("res/音效/主场景主被攻击.mp3", BASS_MUSIC_LOOP/*BASS_MUSIC_FX*/);
  //m_Audio.ChannelPlay(m_MusicIndex,false);
}
CPlateForm *CPlateForm::getInstance()
{
  if (Instance == NULL)
  {
    Instance = new CPlateForm;
  }
  return Instance;
}
void CPlateForm::setWindowSize(int x, int y, int wid, int hei)
{
  window_x = x;
  window_y = y;
  windows_width = wid;
  windows_height = hei;
}
float CPlateForm::updateTime()
{
  static float previousTime = GetTickCount() / 1000.0f;
  float currentTime = GetTickCount() / 1000.0f;
  float elapsedTime = currentTime - previousTime;
  previousTime = currentTime;
  return elapsedTime;
}
float CPlateForm::getFPS()
{
  static float timeNow = GetTickCount() / 1000.0f;
  static DWORD dwRenderedFrame = 0;
  float tFrame = GetTickCount() / 1000.0f - timeNow;
  timeNow += tFrame;
  static float fps = 0;
  if (fmodf(timeNow, 1) < tFrame)
  {
    fps = dwRenderedFrame + fmodf(timeNow, 1) / tFrame; //计算FPS
    dwRenderedFrame = 0;
  }
  dwRenderedFrame++;
  return fps;
}
GLboolean CPlateForm::InitGL(GLvoid)            // 此处开始对OpenGL进行所有设置
{
  static PIXELFORMATDESCRIPTOR pfd =    // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
  {
    sizeof(PIXELFORMATDESCRIPTOR),    // 上述格式描述符的大小
    1,                // 版本号
    PFD_DRAW_TO_WINDOW |      // 格式支持窗口
    PFD_SUPPORT_OPENGL |      // 格式必须支持OpenGL
    PFD_DOUBLEBUFFER,       // 必须支持双缓冲
    PFD_TYPE_RGBA,          // 申请 RGBA 格式
    24,               // 选定色彩深度
    0, 0, 0, 0, 0, 0,       // 忽略的色彩位
    0,                // 无Alpha缓存
    0,                  // 忽略Shift Bit
    0,                // 无累加缓存
    0, 0, 0, 0,           // 忽略聚集位
    16,               // 16位 Z-缓存 (深度缓存)
    1,                // 无蒙板缓存
    0,                // 无辅助缓存
    PFD_MAIN_PLANE,         // 主绘图层
    0,                // Reserved
    0, 0, 0             // 忽略层遮罩
  };
  if (!(hDC = GetDC(hWnd)))         // 取得设备描述表了么?
  {
    KillGLWindow();             // 重置显示区
    MessageBox(NULL, L"不能创建一种相匹配的像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;
    // 返回 FALSE
  }
  GLuint PixelFormat = ChoosePixelFormat(hDC, &pfd);  // Windows 找到相应的象素格式了吗?
  if (!SetPixelFormat(hDC, PixelFormat, &pfd))    // 能够设置象素格式么?
    return false;
  if (!(hRC = wglCreateContext(hDC)))     // 能否取得着色描述表?
    return false;
  if (!wglMakeCurrent(hDC, hRC))        // 尝试激活着色描述表
    return false;
  //GLuint  PixelFormat;
  if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))        // Windows 找到相应的象素格式了吗?
  {
    KillGLWindow();             // 重置显示区
    MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;             // 返回 FALSE
  }
  if (!SetPixelFormat(hDC, PixelFormat, &pfd))        // 能够设置象素格式么?
  {
    KillGLWindow();             // 重置显示区
    MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;             // 返回 FALSE
  }
  if (!(hRC = wglCreateContext(hDC)))         // 能否取得着色描述表?
  {
    KillGLWindow();             // 重置显示区
    MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;             // 返回 FALSE
  }
  if (!wglMakeCurrent(hDC, hRC))            // 尝试激活着色描述表
  {
    KillGLWindow();             // 重置显示区
    MessageBox(NULL, L"不能激活当前的OpenGL渲然描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;             // 返回 FALSE
  }
  glStencilMask(0);                 //蒙版缓冲区置为0
  glShadeModel(GL_SMOOTH);                // 启用阴影平滑
  glClearColor(0.0f,0.0f, 0.0f,1.0f);           // 背景
  glClearDepth(1.0f);                   // 设置深度缓存
  glEnable(GL_DEPTH_TEST);                // 启用深度测试
  glDepthFunc(GL_LEQUAL);                 // 所作深度测试的类型
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // 真正精细的透视修正,告诉系统对透视进行修正
  glFrontFace(GL_CCW);      //多边形逆时针方向为正面
  glClearStencil(0);                          
  glEnable(GL_CULL_FACE);                                 //只显示正面
  ReSizeGLScene(windows_width, windows_height);     //设置openGL窗口大小
  InitGeometry();
  return TRUE;                      // 初始化 OK
}
void CPlateForm::InitGeometry()
{
  //quadratic = gluNewQuadric();
  //gluQuadricNormals(quadratic, GLU_SMOOTH); // 使用平滑法线
  //gluQuadricTexture(quadratic, GL_TRUE);    // 使用纹理
  glEnable(GL_NORMALIZE);
  GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
  GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
  GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
  GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
  glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
  glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
  GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };    // 雾气的模式
  GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };   // 雾的颜色设为灰色
  glFogi(GL_FOG_MODE, GL_LINEAR);   // 设置雾气的模式
  glFogfv(GL_FOG_COLOR, fogColor);      // 设置雾的颜色
  glFogf(GL_FOG_DENSITY,0.05f);     // 设置雾的密度
  glHint(GL_FOG_HINT, GL_DONT_CARE);      // 设置系统如何计算雾气
  glFogf(GL_FOG_START,2000.0f);       // 雾气的开始位置
  glFogf(GL_FOG_END,4000.0f);       // 雾气的结束位置
}
GLvoid CPlateForm::ReSizeGLScene(GLsizei width, GLsizei height)
{
  //glPushMatrix();
  视口
  glViewport(0, 0, width, height);
  投影
  //glMatrixMode(GL_PROJECTION);
  glOrtho(0, windows_width, windows_height, 0, -1, 1);    //2D
  //glLoadIdentity();
  //gluPerspective(45.0f,1.0, 0.1f, 100.0f);  //3D
  视图
  //glMatrixMode(GL_MODELVIEW);           // 选择模型观察矩阵
  //glLoadIdentity();               // 重置模型观察矩阵
  //glPopMatrix();
}
bool CPlateForm::IsExtensionSupported(char* szTargetExtension)
{
  const unsigned char *pszExtensions = NULL;
  const unsigned char *pszStart;
  unsigned char *pszWhere, *pszTerminator;
  pszWhere = (unsigned char *)strchr(szTargetExtension, ' ');
  if (pszWhere || *szTargetExtension == '\0')
    return false;
  // 返回扩展字符串
  pszExtensions = glGetString(GL_EXTENSIONS);
  // 在扩展字符串中搜索
  pszStart = pszExtensions;
  for (;;)
  {
    pszWhere = (unsigned char *)strstr((const char *)pszStart, szTargetExtension);
    if (!pszWhere)
      break;
    pszTerminator = pszWhere + strlen(szTargetExtension);
    if (pszWhere == pszStart || *(pszWhere - 1) == ' ')
      if (*pszTerminator == ' ' || *pszTerminator == '\0')
        //如果存在返回True
        return true;
    pszStart = pszTerminator;
  }
  return false;
}
GLvoid CPlateForm::KillGLWindow(GLvoid)
{
  if (hRC)                // 我们拥有OpenGL渲染描述表吗?
  {
    if (!wglMakeCurrent(NULL, NULL))
    {
      MessageBox(NULL, L"释放DC或RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
    }
    if (!wglDeleteContext(hRC))         // 我们能否删除RC?
    {
      MessageBox(NULL, L"释放RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
    }
    hRC = NULL;
  }
  if (hDC && !ReleaseDC(hWnd, hDC))
  {
    MessageBox(NULL, L"释放DC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
    hDC = NULL;
  }
}
ATOM CPlateForm::MyRegisterClass()
{
  WNDCLASSEXW wcex;
  wcex.cbSize = sizeof(WNDCLASSEX);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = hInst;
  wcex.hIcon = LoadIcon(hInst,NULL);//托盘上的ICO图标
  //wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
  //wcex.hCursor=gameMode ==PLAYING ? LoadCursorFromFileA("res/color/Prcs_IcP.ani"):LoadCursor(nullptr, IDC_ARROW);
  wcex.hCursor = LoadCursorFromFileA("res/color/0081.ani");
  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wcex.lpszMenuName = NULL;
  wcex.lpszClassName = L"myClass";
  wcex.hIconSm = LoadIcon(wcex.hInstance,NULL);//窗口上的ICO图标
  return RegisterClassExW(&wcex);
}
BOOL CPlateForm::InitInstance()
{
  //hInst = hInstance; // 将实例句柄存储在全局变量中
  int nX = GetSystemMetrics(SM_CXFRAME) * 4;
  int nY = GetSystemMetrics(SM_CYFRAME) * 4 + GetSystemMetrics(SM_CYCAPTION);//+ GetSystemMetrics(SM_CYMENU);
  hWnd = CreateWindowW(L"myClass", L"荒岛求生_V1.1", WS_OVERLAPPEDWINDOW,
    window_x, window_y, windows_width + nX, windows_height + nY, nullptr, nullptr, NULL, nullptr);
  if (!hWnd)
  {
    return FALSE;
  }
  InitGL();
  glewInit();//初始化硬件获取纹理通道
  ShowWindow(hWnd, true);
  UpdateWindow(hWnd);
//顶点缓存上的,可是没有用到··
  //使用VBO查询字符串为
//#ifndef NO_VBOS
//  g_fVBOSupported = IsExtensionSupported("GL_ARB_vertex_buffer_object");
//  //返回1为支持.
//  //下面声明VBO扩展函数
//  // VBO Extension Function Pointers
//  PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
//  PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
//  PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
//  PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure
//              
//  if (g_fVBOSupported) //获取函数地址
//  {
//    // 获得函数的指针
//    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
//    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
//    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
//    glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
//  }
//#else 
//  g_fVBOSupported = false;
//#endif
  return TRUE;
}
LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
  U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
  //CMouseTrack::getInstance()->MsgProc(hWnd, message, wParam, lParam);
  switch (message)
  {
  case WM_ACTIVATE:
    switch (wParam)
    {
    case WA_CLICKACTIVE:
    case WA_ACTIVE:
      //isPause = false;
      break;
    case WA_INACTIVE:
      //isPause = true;
      break;
    }
    break;
  case WM_SIZE:
    switch (wParam)
    {
    case SIZE_MINIMIZED:
      break;
    }
    break;
  case WM_RBUTTONDOWN:
    oldMousePos.x= LOWORD(lParam);
    oldMousePos.y= HIWORD(lParam);
    _mouseIsDown = true;
    break;
  case WM_MOUSEMOVE:
  {
    mousePos.x = LOWORD(lParam);
    mousePos.y = HIWORD(lParam);
    if (_mouseIsDown)
    {
      offset= oldMousePos - mousePos;
    }
    oldMousePos = mousePos;
  }break;
  case WM_RBUTTONUP:
    _mouseIsDown = false;
    break;
  case WM_KEYDOWN:
  {
    switch (wParam)
    {
      break;
    case VK_F1:
      isDebug = true;
      break;
    case VK_F2:
      break;
    case VK_F3:break;
    case VK_F11:break;
    case VK_F12:break;
    }
  }break;
  case WM_CLOSE:
  {
    getInstance()->KillGLWindow();
    delete Instance;
    PostQuitMessage(0);
  }break;
  /*case WM_DESTROY:
  {
    if (MessageBox(hWnd, L"亲~要保存所有对象吗?", L"温馨提示", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
    {
      U3D::CSceneManage::getInstance()->getCurrentScene()->EngineSave();
      U3D::CSceneManage::getInstance()->getCurrentScene()->UserSaveData();
    }
    getInstance()->KillGLWindow();
    delete Instance;
    PostQuitMessage(0);
  }break;*/
    //LOWORD:取出无符号长整形的低16位
    //HIWORD:取出无符号长整形的高16位
    //WPARAM:word类型,    最早是16位通常用来存储小段信息  现在类型:unsigned int
    //LPARAM:long int类型  通常用于存储消息所需的对象      现在类型:long int
  case WM_MOUSEWHEEL: {}break;
  }
  return DefWindowProc(hWnd, message, wParam, lParam);
}
void CPlateForm::run()
{
  U3D::CEngineButton::getInstance()->InitAll();
  U3D::CResouceManage::getInstance()->Init();
  U3D::CResourceCompound::getInstance()->init();
  CEffects::getInstance()->init();
  label = new U3D::CUI_Label("A","宋体",24);
  //1:m_pos 2:m_ssssslook 3:m_up 4:m_right
  Vector3D pos[4] = {
  { Vector3D(0,500,0)},
  { Vector3D(0,0,1) },
  { Vector3D(0,1,0) },
  { Vector3D(1,0,0) } };
  godCamera = new freeCamera(pos);
  godCamera->rightRotate(90);
  LARGE_INTEGER nFreq;
  QueryPerformanceFrequency(&nFreq);
  LARGE_INTEGER nAnimationInterval;
  nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
  LARGE_INTEGER nLast;
  LARGE_INTEGER nNow;
  QueryPerformanceCounter(&nLast);
  ZeroMemory(&msg, sizeof(msg));
  while (msg.message != WM_QUIT)
  {
    if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
      QueryPerformanceCounter(&nNow);
      if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
      {
        nLast.QuadPart = nNow.QuadPart;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // 清除屏幕和深度缓存
        Render();
        SwapBuffers(hDC);                     // 交换缓存 (双缓存)
      }
      else { Sleep(0); }continue;
    }
    TranslateMessage(&msg);                             //翻译消息
    DispatchMessage(&msg);  
                            //分发消息
  }
}
static bool lines = 0;
static bool Fog = 1;
static bool light = 1;
GLvoid CPlateForm::Render()
{
  if (Input::getKeyDown(VK_TAB))
    gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
  if (currentEnvironment == NIGHT)
    selectNight();
  else if (currentEnvironment == DAYTIME)
    selectDaytime();
  switch (gameMode)
  {
  case TIELEMODE:
  {
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else
      U3D::CSceneManage::getInstance()->pause(updateTime());
    select2DSpace();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  case EDITMODE:
  {
    glViewport(0, 0, 840, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    godCamera->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else
      U3D::CSceneManage::getInstance()->pause(updateTime());
    godCamera->drawFrustum();
    if (Fog)
      glEnable(GL_FOG);
    else
      glDisable(GL_FOG);
    /
    //右边2d
    glViewport(840, 0, 440, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, 440, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->drawDebug();
    U3D::CEngineButton::getInstance()->_draw();
    glPushMatrix();
    glLoadIdentity();
    label->setString("0l,2,3切换图片,右击存");
    label->setPosition(850, 0, 1);
    label->draw();
    label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
    label->setPosition(850, 30, 0);
    label->draw();
    label->setString("小键盘0开关线段模式");
    label->setPosition(850, 60, 0);
    label->draw();
    label->setString("当前渲染对象数量:%d", objNumber);
    label->setPosition(850, 90, 0);
    label->draw();
    label->setString("TAB:开/关编辑模式");
    label->setPosition(850, 120, 0);
    label->draw();
    label->setString("FPS:%f", getFPS());
    label->setPosition(850, 150, 0);
    label->draw();
    glColor4f(1,1,1,1);
    glPopMatrix();
    if (Input::getKeyDown(VK_F2))
      light = light == false ? 1 : 0;
    if (Input::getKeyDown(VK_F3))
      Fog = Fog == false ? 1 : 0;
    if (Input::getKeyDown(VK_NUMPAD0))
      lines = lines == false ? true : false;
    if (light)
    {
      glEnable(GL_LIGHTING);  glEnable(GL_LIGHT0);
    }
    else
    {
      glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
    }
    if (lines)
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    else
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }break; 
  case IN_SPACE:
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  case FALLING://陨落的场景
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
  }break;
  case PLAYING:
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    //partic->draw(0.2);
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
    label->setString("-FPS:%f", getFPS());
    label->setPosition(0, 920, 0);
    label->draw();
  }break;
  case FLY://逃离这个星球
  {
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
    glLoadIdentity();
    gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    Camera::getInstance()->update();
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    label->setString("-FPS:%f", getFPS());
    label->setPosition(0, 920, 0);
    label->draw();
  }break;
  case END://结尾的场景
  {
    if (!isPause)
      U3D::CSceneManage::getInstance()->run(updateTime());
    else if (isPause)
      U3D::CSceneManage::getInstance()->pause(updateTime());
    glViewport(0, 0, windows_width, windows_height);
    glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
    glLoadIdentity();
    gluOrtho2D(0, windows_width, windows_height, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    U3D::CSceneManage::getInstance()->draw2D();
  }break;
  }
  Input::flush();
}
Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y)
{
  Vector3D pos;
  GLint    viewport[4];
  GLdouble modelview[16];
  GLdouble projection[16];
  GLfloat  winX, winY, winZ;
  GLdouble posX, posY, posZ;
  glPushMatrix();
  glGetIntegerv(GL_VIEWPORT, viewport); // 得到的是最后一个设置视口的参数
  glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
  glGetDoublev(GL_PROJECTION_MATRIX, projection);
  glPopMatrix();
  winX = (float)mouse_x;
  winY = viewport[3] - (float)mouse_y;
  glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
  gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
  //if (Input::getMouseWheel(&mouseNow))
  //{
  //  pos3D.z += mouseNow.scroll;
  //}
  pos.x = posX;
  pos.y = posY;
  pos.z = posZ;
  return pos;
}
void CPlateForm::OpenEditor() { gameMode = EDITMODE; }
bool CPlateForm::getMouseIsDown() { return _mouseIsDown; }
bool CPlateForm::getIsDebugMode() { return isDebug; }
void CPlateForm::setAutoSort(bool autoSort) { this->isAutoSort = autoSort; }
bool CPlateForm::getAutoSort() { return isAutoSort; }
int CPlateForm::getAxisMode() { return AxisMode; }
void CPlateForm::setAxisMode(int Axis) { this->AxisMode = Axis; }
void CPlateForm::setGameMode(GameMode mode) { this->gameMode = mode; }
GameMode CPlateForm::getGameMode() { return gameMode; }
void CPlateForm::select2DSpace()
{
  glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
  glMatrixMode(GL_PROJECTION);          // 选择投影矩阵
  glLoadIdentity();
  gluOrtho2D(0, _WINDOW_WID_, _WINDOW_HEI_, 0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
void CPlateForm::select3DSpace()
{
  glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
  glMatrixMode(GL_PROJECTION);  // 选择投影矩阵
  glLoadIdentity();
  gluPerspective(80.0f,1280.0f/960.0f, 0.1f, 5000.0f);//透视远近
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
sColor CPlateForm::selectDaytime()
{
  glEnable(GL_NORMALIZE);
  GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
  GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
  GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
  GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
  glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
  glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
  GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };    // 雾气的模式
  GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };   // 雾的颜色设为灰色
  glFogi(GL_FOG_MODE, GL_LINEAR);   // 设置雾气的模式
  glFogfv(GL_FOG_COLOR, fogColor);      // 设置雾的颜色
  glFogf(GL_FOG_DENSITY, 0.05f);      // 设置雾的密度
  glHint(GL_FOG_HINT, GL_DONT_CARE);      // 设置系统如何计算雾气
  glFogf(GL_FOG_START, 2000.0f);        // 雾气的开始位置
  glFogf(GL_FOG_END, 4000.0f);        // 雾气的结束位置
  currentEnvironment=DAYTIME;
  return sColor (1.0f, 1.0f, 1.0f, 1.0f);
}
sColor CPlateForm::selectNight()
{
  glEnable(GL_NORMALIZE);
  GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
  GLfloat LightAmb[] = { 0.1f,0.1f,0.1f,1.0f };
  GLfloat LightDif[] = { 0.1f,0.1f,0.1f,1.0f };
  GLfloat LightSpe[] = { 0.1f,0.1f,0.1f,1.0f };
  glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
  glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
  GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };    // 雾气的模式
  GLfloat fogColor[4] = { 0.15f, 0.15f, 0.15f, 1.0f };    // 雾的颜色设为灰色
  glFogi(GL_FOG_MODE, GL_LINEAR);   // 设置雾气的模式
  glFogfv(GL_FOG_COLOR, fogColor);      // 设置雾的颜色
  glFogf(GL_FOG_DENSITY, 0.05f);      // 设置雾的密度
  glHint(GL_FOG_HINT, GL_DONT_CARE);      // 设置系统如何计算雾气
  glFogf(GL_FOG_START,1600.0f);       // 雾气的开始位置
  glFogf(GL_FOG_END, 5000.0f);        // 雾气的结束位置
  currentEnvironment=NIGHT;
  return sColor(0.1f, 0.1f, 0.1f, 1.0f);
}
CPlateForm::~CPlateForm()
{
  if (hRC)
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
  }
  if (hDC)
  {
    ReleaseDC(hWnd, hDC);
  }
  U3D::CResouceManage::getInstance()->~CResouceManage();//析构时有错
  U3D::CEngineButton::getInstance()->~CEngineButton();
  CEffects::getInstance()->~CEffects();
  U3D::CSceneManage::getInstance()->~CSceneManage();
  m_Audio.Release();
  m_Audio.clear_allMusic();
}


ps:刚毕业的时候对工程的理解不深刻,代码里有很多不规范的地方,比如把游戏的具体逻辑给写道了引擎里去了,这些当时想拆出来的,但是后来工作一忙还没有拆干净也就不了了之了。


ps2:本来想从具体的引擎模块开始写起的,但是发现还是从主入口写会更好理解吧,所以就从平台类开始写了。准备文章写完后就把整个工程传到gitee上去,供大家学习。

相关文章
|
2月前
|
编译器 C# Android开发
Uno Platform 是一个用于构建跨平台应用程序的强大框架,它允许开发者使用 C# 和 XAML 来创建适用于多个平台的应用
Uno Platform 是一个用于构建跨平台应用程序的强大框架,它允许开发者使用 C# 和 XAML 来创建适用于多个平台的应用
258 8
|
3月前
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
286 0
|
3月前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
68 0
|
3月前
|
Android开发 iOS开发 C#
Xamarin.Forms:从零开始的快速入门指南——打造你的首个跨平台移动应用,轻松学会用C#和XAML构建iOS与Android通用界面的每一个步骤
【8月更文挑战第31天】Xamarin.Forms 是一个强大的框架,让开发者通过单一共享代码库构建跨平台移动应用,支持 iOS、Android 和 Windows。使用 C# 和 XAML,它简化了多平台开发流程并保持一致的用户体验。本指南通过创建一个简单的 “HelloXamarin” 应用演示了 Xamarin.Forms 的基本功能和工作原理。
79 0
|
3月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
246 0
|
Dart Linux 开发工具
使用Flutter构建桌面应用:一次开发,多平台支持
随着移动和桌面应用程序的需求不断增长,开发人员需要寻找一种高效的方法来构建多平台的应用程序。Flutter作为一个跨平台的UI框架,提供了一次编写、多平台运行的解决方案。在本文中,我们将探讨如何使用Flutter来构建桌面应用程序,并展示其多平台支持的优势。
1876 0
从0开发游戏引擎之引擎Win32平台的Platform类实现
首先是执行了Platform中的静态函数SetWindowSize,设置了Win32窗口的初始化xy位置,以及窗口大小。
|
IDE 开发工具 C#
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
1016 0
Visual Studio 2022 Preview 2 发布:扩展跨平台功能,支持实时预览,debug 更高效
|
Web App开发 JavaScript 前端开发
RISC-V生态开发套件解析(八):Waft模拟器和dep_tools网页版使用教程
随着RISC-V生态的蓬勃发展,相关开源开发套件也开始逐渐丰富。为了帮助开发者快速了解、玩转新推出的RISC-V开发套件,OCC推出RISC-V生态开发套件解析系列内容,详细讲解生态开发套件的功能特点与上手教程。
585 0
RISC-V生态开发套件解析(八):Waft模拟器和dep_tools网页版使用教程
|
编译器 C语言
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
206 0
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV