21xrx.com
2025-03-29 07:28:52 Saturday
文章检索 我的文章 写文章
C++ 中如何绘制图形?
2023-07-03 12:07:44 深夜i     25     0
C++ 绘图 方法 窗口

C++ 作为一种强大的编程语言,在图形绘制方面也有着很高的应用价值。它提供了很多图形库,其中最常用的是OpenGL和DirectX,通过这些库,我们可以利用C++的编程特性,轻松地完成图形的生成。

OpenGL是一种跨平台的图形库,它可以在Linux、Windows、MacOS等各种操作系统中使用,并且它是免费的开源软件。OpenGL提供了一系列的API,用来调用各种基本图元,如点、线、矩形、多边形等,并提供了许多高级功能,如光照、纹理、透明度等。

下面是一个使用OpenGL绘制三角形的示例代码:

#include <GL/glut.h>
void Display()
{
  glClearColor(1.0,1.0,1.0,0.0);  //设置背景颜色为白色
  glClear(GL_COLOR_BUFFER_BIT);   //清除颜色缓冲区
  glColor3f(0.0,0.0,1.0);      //设置绘图颜色为蓝色
  glBegin(GL_TRIANGLES);      //开始绘制三角形
  glVertex2f(-0.5,-0.5);
  glVertex2f(0.5,-0.5);
  glVertex2f(0.0,0.5);
  glEnd();             //结束绘制三角形
  glFlush();            //将缓冲区的图像输出到屏幕
}
int main(int argc,char **argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);  //设置显示模式
  glutInitWindowSize(400,300);         //设置窗口大小
  glutCreateWindow("OpenGL Demo");       //创建窗口
  glutDisplayFunc(Display);           //注册回调函数
  glutMainLoop();                //进入循环
  return 0;
}

而在使用DirectX时,我们需要安装DirectX SDK,并在项目中引用相关的库文件。DirectX提供了一个D3D类,包含了大多数图形绘制相关的方法。下面是一个使用DirectX绘制矩形的示例代码:

#include <windows.h>
#include <d3d11.h>
#pragma comment(lib, "d3d11.lib")
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(_In_ HINSTANCE hInstance,
           _In_opt_ HINSTANCE hPrevInstance,
           _In_ LPWSTR lpCmdLine,
           _In_ int nCmdShow)
{
  HWND hWnd;
  WNDCLASSEX wc;
  ZeroMemory(&wc, sizeof(wc));
  wc.cbSize = sizeof(wc);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.hInstance = hInstance;
  wc.lpfnWndProc = WndProc;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wc.lpszClassName = L"DirectXWindow";
  RegisterClassEx(&wc);
  hWnd = CreateWindow(wc.lpszClassName, L"DirectX Window", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
  if (!hWnd)
  
    return 0;
  
  ShowWindow(hWnd, nCmdShow);
  ID3D11Device* pDevice = NULL;
  ID3D11DeviceContext* pContext = NULL;
  IDXGISwapChain* pSwapChain = NULL;
  D3D_FEATURE_LEVEL FeatureLevel;
  ZeroMemory(&FeatureLevel, sizeof(FeatureLevel));
  D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0,
    D3D11_SDK_VERSION, &sd, &pSwapChain, &pDevice, &FeatureLevel, &pContext);
  ID3D11RenderTargetView* pRTV = NULL;
  ID3D11Texture2D* pBackBuffer = NULL;
  pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
  pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRTV);
  pContext->OMSetRenderTargets(1, &pRTV, NULL);
  pBackBuffer->Release();
  D3D11_VIEWPORT vp;
  ZeroMemory(&vp, sizeof(vp));
  vp.Width = 800;
  vp.Height = 600;
  vp.MinDepth = 0.0f;
  vp.MaxDepth = 1.0f;
  pContext->RSSetViewports(1, &vp);
  D3D11_INPUT_ELEMENT_DESC ied[] =
  {
     D3D11_INPUT_PER_VERTEX_DATA
  };
  ID3D11InputLayout* pInputLayout = NULL;
  D3D11_INPUT_ELEMENT_DESC ied[] =
  {
     "POSITION"
  };
  D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0,
    D3D11_SDK_VERSION, &sd, &pSwapChain, &pDevice, &FeatureLevel, &pContext);
  ID3D11RenderTargetView* pRTV = NULL;
  ID3D11Texture2D* pBackBuffer = NULL;
  pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
  pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRTV);
  pContext->OMSetRenderTargets(1, &pRTV, NULL);
  pBackBuffer->Release();
  D3D11_VIEWPORT vp;
  ZeroMemory(&vp, sizeof(vp));
  vp.Width = 800;
  vp.Height = 600;
  vp.MinDepth = 0.0f;
  vp.MaxDepth = 1.0f;
  pContext->RSSetViewports(1, &vp);
  D3D11_INPUT_ELEMENT_DESC ied[] =
  {
     0
  };
  ID3D11InputLayout* pInputLayout = NULL;
  pDevice->CreateInputLayout(ied, 1, VS.data(), VS.size(), &pInputLayout);
  pContext->IASetInputLayout(pInputLayout);
  std::vector<float> Vertices =
   -0.5f;
  D3D11_BUFFER_DESC vbd;
  ZeroMemory(&vbd, sizeof(vbd));
  vbd.Usage = D3D11_USAGE_DEFAULT;
  vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  vbd.ByteWidth = sizeof(float) * 4 * 3;
  D3D11_SUBRESOURCE_DATA InitData;
  ZeroMemory(&InitData, sizeof(InitData));
  InitData.pSysMem = &Vertices[0];
  ID3D11Buffer* pVB = NULL;
  pDevice->CreateBuffer(&vbd, &InitData, &pVB);
  UINT stride = sizeof(float) * 3;
  UINT offset = 0;
  pContext->IASetVertexBuffers(0, 1, &pVB, &stride, &offset);
  std::string VS =
    "struct VertexInput"
    ""
    "  float3 Pos : POSITION;"
    ";"
    "struct PixelInput"
    ""
    "  float4 Pos : SV_POSITION;"
    ";"
    "PixelInput VS(VertexInput input)"
    "{"
    "  PixelInput output;"
    "  output.Pos = float4(input.Pos, 1.0f);"
    "  return output;"
    "}";
  std::string PS =
    "float4 PS() : SV_TARGET"
    "{"
    "  return float4(1.0f, 0.0f, 0.0f, 1.0f);"
    "}";
  ID3D11VertexShader* pVS;
  ID3D11PixelShader* pPS;
  pDevice->CreateVertexShader(VS.data(), VS.size(), NULL, &pVS);
  pDevice->CreatePixelShader(PS.data(), PS.size(), NULL, &pPS);
  pContext->VSSetShader(pVS, NULL, 0);
  pContext->PSSetShader(pPS, NULL, 0);
  MSG msg;
  ZeroMemory(&msg, sizeof(msg));
  while (msg.message != WM_QUIT)
  {
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else
    {
      pContext->ClearRenderTargetView(pRTV, DirectX::Colors::SkyBlue);
      pContext->Draw(4, 0);
      pSwapChain->Present(0, 0);
    }
  }
  pVS->Release();
  pPS->Release();
  pVB->Release();
  pInputLayout->Release();
  pRTV->Release();
  pSwapChain->Release();
  pContext->Release();
  pDevice->Release();
  return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return 0;
}

总体来说,C++在图形编程方面有着广泛的应用价值,而图形的绘制主要依赖于各种图形库的支持。掌握图形编程的技能不仅可以帮助我们更好地开发应用,而且还可以为我们提供更加美观、多样化的视觉体验。

  
  

评论区

请求出错了