c++ - Drawing a circle in directx 9 -


i'm having hard time figuring out how draw circle in directx. i'm able draw triangle, imagined might able draw 1 rotating triangle in circle. however, i'm absolutely stumped. i've been scouring net hours no luck. can me out? here's code:

main.cpp

#include "engine.h" #include "box2d.h" #include "triangle2d.h"  class myapp : public engine { public:      box2d box2d;     triangle2d triangle2d;      void onstartup() override {         box2d.new(10.0f, 10.0f, 100.0f, 100.0f, d3dcolor_argb(0xff, 0x00, 0x00, 0xff));          triangle2d.new(150.0f, 10.0f, 100.0f, 100.0f, d3dcolor_argb(0xff, 0xff, 0x00, 0x00));     }      void onshutdown() override {         box2d.delete();         triangle2d.delete();     }      void ondraw() override {         box2d.draw();         triangle2d.draw();     }      void onmousedown(int x, int y) {         debug("%d %d\n", x, y);     }  };  int winapi winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow) {     myapp app;     app.run();     return 0; } 

engine.cpp

#include "engine.h"  // initialize classes static variables engine* engine::_engine = null;  // returns current instance of class engine* engine::getinstance() {     return _engine; }  // constructor engine::engine() : _exit(false) , _window(null) , _directx(null) , _device(null) {     _engine = this; }  // deconstructor engine::~engine() {     _engine = null; }  // run core main event loop, start finish bool engine::run() {      // create windows class     wndclassex wc;     zeromemory(&wc, sizeof(wc));     wc.cbsize = sizeof(wndclassex);     wc.style = cs_vredraw | cs_hredraw | cs_dblclks | cs_classdc;     wc.lpfnwndproc = _wnd_proc;     wc.hinstance = getmodulehandle(null);     wc.hcursor = loadcursor(null, idc_arrow);     wc.hbrbackground = (hbrush)getstockobject(white_brush);     wc.lpszclassname = _getmodulename();     registerclassex(&wc);      // adjust window rect flags     rect rect;     setrect(&rect, 0, 0, _width, _height);     const dword windowflags = ws_overlapped | ws_caption | ws_clipchildren | ws_sysmenu | ws_minimizebox;     adjustwindowrectex(&rect, windowflags, false, 0);      // create window     _window = createwindowex(0, _getmodulename(), _getmodulename(), windowflags, 0, 0, rect.right - rect.left, rect.bottom - rect.top, null, null, getmodulehandle(null), null);     if (_window == null)         return false;      // move window center of screen     rect system;     systemparametersinfo(spi_getworkarea, 0, &system, 0);     movewindow(_window, (system.right - system.left) / 2 - (rect.right - rect.left) / 2, (system.bottom - system.top) / 2 - (rect.bottom - rect.top) / 2, rect.right - rect.left, rect.bottom - rect.top, true);      // startup direct x     if (_directxstartup() == false)         return false;      // call our startup callback     onstartup();      // show window     showwindow(_window, sw_shownormal);      // run event loop     msg msg;     ulonglong timer = gettickcount64();     while (!_exit) {          // handle normal system events         if (peekmessage(&msg, null, 0, 0, pm_remove)) {             translatemessage(&msg);             dispatchmessage(&msg);         }          // run timer @ framerate         if (timer + 1000 / _fps < gettickcount64()) {             timer = gettickcount64();              // clear buffer             _device->clear(0, null, d3dclear_target | d3dclear_zbuffer, d3dcolor_xrgb(0x00, 0xff, 0x00), 1.0f, null);              // call our draw callback every frame             ondraw();              // render screen             _device->present(null, null, null, null);         }      }      // hide window avoid flicker     showwindow(_window, sw_hide);      // call our shutdown callback     onshutdown();      // shutdown direct x     _directxshutdown();      // cleanup , destroy window     destroywindow(_window);     unregisterclass(_getmodulename(), getmodulehandle(null));      return true; }  // return directx device, needed other directx objects lpdirect3ddevice9 engine::getdevice() {     return _device; }  // return our width int engine::getwidth() {     return _width; }  // return our height int engine::getheight() {     return _height; }  // our own custom debug string void engine::debug(const char* message, ...) { #if _debug     if (message) {         va_list args;         va_start(args, message);         int size = vsnprintf(null, 0, message, args);         if (size > 0) {             char* string = new char[size + 1];             vsnprintf(string, size + 1, message, args);             outputdebugstringa(string);             delete[] string;         }         va_end(args);     } #endif }  // windows callback lresult callback engine::_wnd_proc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam) {      // if not have access instance of our engine, nothing     if (engine::_engine == null)         return  defwindowproc(hwnd, umsg, wparam, lparam);      // handle system messages     switch (umsg) {     case wm_lbuttondown:         engine::_engine->onmousedown(get_x_lparam(lparam), get_y_lparam(lparam));         return 0;     case wm_keydown:     case wm_syskeydown:         if ((lparam & (1 << 30)) == 0)             engine::_engine->onkeydown((int)wparam);         return 0;     case wm_char:         if ((int)wparam <= 127 && isprint((int)wparam) && (lparam & (1 << 30)) == 0)             engine::_engine->onasciidown((char)wparam);         return 0;     case wm_close:         engine::_engine->_exit = true;         return 0;     }      return defwindowproc(hwnd, umsg, wparam, lparam); }  // custom function getting our exe name wchar* engine::_getmodulename() {     static wchar* title = null;     static wchar buffer[max_path];     if (title != null)         return title;      // remove path     getmodulefilename(null, buffer, max_path);     title = wcsrchr(buffer, '\\');     if (title == null) {         wcscpy(buffer, l"application");         title = buffer;         return title;     }     title++;      // remove extension     wchar* ext = wcsrchr(buffer, '.');     if (ext)         *ext = 0;      return title; }  // startup directx here bool engine::_directxstartup() {      // startup direct x     _directx = direct3dcreate9(d3d_sdk_version);     if (_directx == null)         return false;      // create direct x device     d3dpresent_parameters d3dpp;     zeromemory(&d3dpp, sizeof(d3dpp));     d3dpp.windowed = true;     d3dpp.hdevicewindow = _window;     d3dpp.backbufferwidth = _width;     d3dpp.backbufferheight = _height;     d3dpp.backbuffercount = 1;     d3dpp.backbufferformat = d3dfmt_a8r8g8b8;     d3dpp.enableautodepthstencil = true;     d3dpp.autodepthstencilformat = d3dfmt_d24x8;     d3dpp.swapeffect = d3dswapeffect_copy;     hresult result = _directx->createdevice(d3dadapter_default, d3ddevtype_hal, _window, d3dcreate_hardware_vertexprocessing, &d3dpp, &_device);     if (failed(result))         result = _directx->createdevice(d3dadapter_default, d3ddevtype_ref, _window, d3dcreate_software_vertexprocessing, &d3dpp, &_device);     if (failed(result))         return false;      return true; }  // shutdown directx here bool engine::_directxshutdown() {     if (_device) {         _device->release();         _device = null;     }     if (_directx) {         _directx->release();         _directx = null;     }     return true; } 

engine.h

#ifndef _engine_h_ #define _engine_h_  #define _crt_secure_no_warnings #include <windows.h> #include <windowsx.h> #include <stdio.h> #include <d3d9.h> #include <d3dx9.h>  class engine { public:     // return current singleton of engine class     static engine* getinstance();      // constructor , deconstructor     engine();     virtual ~engine();      // run engine class     bool run();      // return useful information class     lpdirect3ddevice9 getdevice();     int getwidth();     int getheight();      // use debug output     static void debug(const char* message, ...);      // virtual callbacks     virtual void onstartup() {}     virtual void onshutdown() {}     virtual void onmousedown(int x, int y) {}     virtual void onkeydown(int key) {}     virtual void onasciidown(char key) {}     virtual void ondraw() {}  private:     static engine* _engine;     static const int _width = 854;     static const int _height = 480;     static const int _fps = 60;     bool _exit;     hwnd _window;     lpdirect3d9 _directx;     lpdirect3ddevice9 _device;      static lresult callback _wnd_proc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam);     wchar* _getmodulename();     bool _directxstartup();     bool _directxshutdown(); };  #endif // _engine_h_ 

triangle2d.h

#ifndef _triangle_2d_h_ #define _triangle_2d_h_  #include "engine.h"  class triangle2d { public:     triangle2d();     bool new(float x, float y, float width, float height, dword color);     void delete();     void draw();     void draw(float x, float y, float width, float height, dword color);  private:     struct customvertex {         float x, y, z, w;         dword color;     };     static const dword _fvf = d3dfvf_xyzrhw | d3dfvf_diffuse;     lpdirect3dvertexbuffer9 _vb; };  #endif // _box_2d_h_ 

triangle2d.cpp

#include "triangle2d.h"  triangle2d::triangle2d() : _vb(null) { }  bool triangle2d::new(float x, float y, float width, float height, dword color) {      if (failed(engine::getinstance()->getdevice()->createvertexbuffer(sizeof(customvertex)* 4, d3dusage_writeonly, _fvf, d3dpool_default, &_vb, null)))         return false;      customvertex* vertices;     _vb->lock(0, 0, (void**)&vertices, 0);     vertices[0].x = x;     vertices[0].y = y;     vertices[0].z = 0.0f;     vertices[0].w = 1.0f;     vertices[0].color = color;     vertices[1].x = x + width;     vertices[1].y = y;     vertices[1].z = 0.0f;     vertices[1].w = 1.0f;     vertices[1].color = color;     vertices[2].x = x;     vertices[2].y = y + height;     vertices[2].z = 0.0f;     vertices[2].w = 1.0f;     vertices[2].color = color;     _vb->unlock();      return true; }  void triangle2d::delete(){     if (_vb) {         _vb->release();         _vb = null;     } }  void triangle2d::draw() {     engine::getinstance()->getdevice()->beginscene();     engine::getinstance()->getdevice()->setfvf(_fvf);     engine::getinstance()->getdevice()->setstreamsource(0, _vb, 0, sizeof(customvertex));     engine::getinstance()->getdevice()->drawprimitive(d3dpt_trianglestrip, 0, 2);     engine::getinstance()->getdevice()->endscene(); }  void triangle2d::draw(float x, float y, float width, float height, dword color) {     customvertex* vertices;     _vb->lock(0, 0, (void**)&vertices, 0);     vertices[0].x = x;     vertices[0].y = y;     vertices[0].z = 0.0f;     vertices[0].w = 1.0f;     vertices[0].color = color;     vertices[1].x = x + width;     vertices[1].y = y;     vertices[1].z = 0.0f;     vertices[1].w = 1.0f;     vertices[1].color = color;     vertices[2].x = x;     vertices[2].y = y + height;     vertices[2].z = 0.0f;     vertices[2].w = 1.0f;     vertices[2].color = color;     _vb->unlock();      draw(); } 

direct3d not draw "circles". natively draws 3 fundamental primitives: points, lines, , triangles. there lots of options how draws things, that's can draw natively. same true of opengl (which can draw 'quads' well, can draw quad 2 triangles).

typically drawing circles , other smooth objects best done through "vector graphics" libraries. these can render high-quality approximations of smooth objects circles @ correct resolution. legacy gdi library did, , direct2d can do. can code own approximation circle, won't direct2d. these libraries generate points, lines, , triangles actual drawing operations performed direct3d.

for reason, if doing 'presentation' graphics, should @ using direct2d instead of direct3d. games never draw true circles. draw 2d sprites 2 textured triangles direct3d using image of circle drawn on artist in photoshop or paint.

if insistent on using direct3d, see directx tool kit direct3d 11 debugdraw helper can draw 'rings' (i.e. line-segment circles in 3d space). should give idea how done. code uses 32 segments form ring, 'vector graphics' library determine how many segments break down based on how many pixels it's going cover on screen:

void xm_callconv dx::drawring(primitivebatch<vertexpositioncolor>* batch,     fxmvector origin,     fxmvector majoraxis,     fxmvector minoraxis,     gxmvector color) {     static const size_t c_ringsegments = 32;      vertexpositioncolor verts[c_ringsegments + 1];      float fangledelta = xm_2pi / float(c_ringsegments);     // instead of calling cos/sin each segment calculate     // sign of angle delta , incrementally calculate sin     // , cosine on.     xmvector cosdelta = xmvectorreplicate(cosf(fangledelta));     xmvector sindelta = xmvectorreplicate(sinf(fangledelta));     xmvector incrementalsin = xmvectorzero();     static const xmvectorf32 s_initialcos =     {         1.f, 1.f, 1.f, 1.f     };     xmvector incrementalcos = s_initialcos.v;     (size_t = 0; < c_ringsegments; i++)     {         xmvector pos = xmvectormultiplyadd(majoraxis, incrementalcos, origin);         pos = xmvectormultiplyadd(minoraxis, incrementalsin, pos);         xmstorefloat3(&verts[i].position, pos);         xmstorefloat4(&verts[i].color, color);         // standard formula rotate vector.         xmvector newcos = incrementalcos * cosdelta - incrementalsin * sindelta;         xmvector newsin = incrementalcos * sindelta + incrementalsin * cosdelta;         incrementalcos = newcos;         incrementalsin = newsin;     }     verts[c_ringsegments] = verts[0];      batch->draw(d3d11_primitive_topology_linestrip, verts, c_ringsegments + 1); } 

direct3d 9 legacy , unless targeting windows xp, should using direct3d 11 or perhaps direct2d if doing 2d presentation graphics.


Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -