21xrx.com
2024-12-22 22:47:21 Sunday
登录
文章检索 我的文章 写文章
C++ 中如何绘制图形?
2023-07-03 12:07:44 深夜i     --     --
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++在图形编程方面有着广泛的应用价值,而图形的绘制主要依赖于各种图形库的支持。掌握图形编程的技能不仅可以帮助我们更好地开发应用,而且还可以为我们提供更加美观、多样化的视觉体验。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复