directx和opengl 电子白板
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了directx和opengl 电子白板相关的知识,希望对你有一定的参考价值。
画图板的几种方法
1 使用有界面的qt
2 使用mfc
3 c# winform
4 c# wpf
5 使用html5
6 使用opencv
1 是可以跨平台的
2 是不可以跨平台的,和3,4 一起说不清楚微软为什么不做跨平台的界面库
winform 和wpf 一样不能跨,但是在Visual Studio 2019 16.6版中,针对 .NET Core 平台推出 Winform 设计器,因此使用vs2019 c# 是可以跨平台的。
5 可以跨平台
6 可以跨平台
作为技术选型,如果考虑成熟度,还是先不要激进,做产品以成熟的东西为主。因此在windows平台上,可以选择directx 作为首选,他速度是最快的。同时主要平台上使用html5 制作了画板,但是要和有界面的同步,分别使用directx9 因此使用sdl 来画图 ,本质上来说,directx9和sdl 并没有多大区别,sdl 可以使用directx9 或者 opengl 来画。
需要和ffmpeg等联合画和编解码,最好的方式就是使用sdl 和 opencv。这其实应该是首选,opencv无论是成熟度还是处理图形图像都是高质量的,后面我们会补充这种方式来做
1、使用sdl来画
// testsdl2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <stdio.h>
#include <string.h>
#define __STDC_CONSTANT_MACROS
#define SDL_MAIN_HANDLED
extern "C"
{
#include "SDL2/SDL.h"
#include "SDL2/SDL_mouse.h"
#include "SDL2/SDL_surface.h"
#include <SDL2/SDL_opengl.h>
//if you want sdl image
//#include "SDL2/SDL_image.h"
};
#include "object.h"
#ifdef _WIN32
#pragma comment(lib,"sdl2.lib")
#pragma comment(lib,"opengl32")
#endif
class c_drawing {
SDL_Window *v_pWindow = NULL;
SDL_Renderer *v_pRender = NULL;
SDL_Texture * v_pTexture = NULL;
bool v_Run = false;
s_drawrop v_save;
//s_point v_end;
bool v_bstart = false;
s_canvas v_canvas;
public:
bool func_running()
{
return v_Run;
}
void draw_all_objs()
{
#define L(x) v_canvas.v_lines[i]
SDL_SetRenderDrawColor(v_pRender, 255, 255, 255, 0);
for (size_t i = 0; i < v_canvas.v_lines.size(); i++)
{
SDL_RenderDrawLine(v_pRender, L(i).x1, L(i).y1, L(i).x2, L(i).y2);
}
}
void eraselast()
{
if (v_save.draw == true)
{
SDL_SetRenderDrawColor(v_pRender, 0, 0, 0, 0);
SDL_RenderDrawLine(v_pRender, v_save.x1, v_save.y1, v_save.x2, v_save.y2);
}
}
void line()
{
SDL_SetRenderDrawColor(v_pRender, 255, 255, 255, 0);
SDL_RenderDrawLine(v_pRender, v_save.x1, v_save.y1, v_save.x2, v_save.y2);
}
int getMouseKeyEven(void *opaque) {
SDL_Event ev;
if (SDL_PollEvent(&ev))
{
if (SDL_KEYDOWN == ev.type) // SDL_KEYUP
{
if (SDLK_DOWN == ev.key.keysym.sym)
{
printf("SDLK_DOWN ...............\\n");
}
else if (SDLK_UP == ev.key.keysym.sym)
{
printf("SDLK_UP ...............\\n");
}
else if (SDLK_LEFT == ev.key.keysym.sym)
{
printf("SDLK_LEFT ...............\\n");
}
else if (SDLK_RIGHT == ev.key.keysym.sym)
{
printf("SDLK_RIGHT ...............\\n");
}
}
else if (SDL_MOUSEBUTTONDOWN == ev.type)
{
if (SDL_BUTTON_LEFT == ev.button.button)
{
v_save.x1 = ev.button.x;
v_save.y1 = ev.button.y;
v_bstart = true;
printf("mouse left x, y %d %d ...............\\n", ev.button.x, ev.button.y);
}
}
else if (SDL_MOUSEMOTION == ev.type)
{
if (v_bstart == true)
{
SDL_SetRenderDrawColor(v_pRender, 0, 0, 0, 0);
SDL_RenderFillRect(v_pRender, NULL);
eraselast();
v_save.x2 = ev.button.x;
v_save.y2 = ev.button.y;
draw_all_objs();
line();
v_save.draw = true;
SDL_RenderPresent(v_pRender);
}
}
else if (SDL_MOUSEBUTTONUP == ev.type)
{
s_line line;
line.x1 = v_save.x1;
line.y1 = v_save.y1;
line.x2 = v_save.x2;
line.y2 = v_save.y2;
v_bstart = false;
v_save.x2 = 0;
v_save.y2 = 0;
v_save.draw = false;
v_canvas.v_lines.push_back(line);
//SDL_RenderPresent(v_pRender);
}
else if (SDL_QUIT == ev.type)
{
v_Run = false;
printf("SDL_QUIT ...............\\n");
return 0;
}
}
return 0;
}
bool init(const char *title, int height, int width, int flags)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
//glEnable(GL_LINE_SMOOTH); //设置反走样
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); //设置反走样
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
//SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
v_pWindow = SDL_CreateWindow("OpenGL drawing", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480,
SDL_WINDOW_OPENGL);
if (!v_pWindow) {
fprintf(stderr, "Couldn't create window: %s\\n", SDL_GetError());
return -1;
}
//v_pWindow = SDL_CreateWindow(title, xpos, ypos, height, width, flags);
//SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_OPENGL , &v_pWindow, &v_pRender);
/* comment the following line for blended images */
//if (NULL == v_pWindow) return false;
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 2);
v_pRender = SDL_CreateRenderer(v_pWindow, -1, 0);
//SDL_SetRenderDrawColor(v_pRender, 128, 0, 255, 0);
// new
#if 0
SDL_Surface *pTmpSurface = SDL_LoadBMP("./sample.bmp"); // 按照实际更改图片名称及路径
if (NULL == pTmpSurface)
return false;
v_pTexture = SDL_CreateTextureFromSurface(v_pRender, pTmpSurface);
if (NULL == v_pTexture)
return false;
SDL_FreeSurface(pTmpSurface);
int w,h;
SDL_QueryTexture(v_pTexture, NULL, NULL, &w, &h);
#endif
//SDL_RenderDrawLine(v_pRender, 0, 0, 100, 100);
//SDL_RenderPresent(v_pRender);
v_Run = true;
return v_Run;
}
void func_update()
{
}
void func_clean()
{
}
void func_render()
{
}
};
int main()
{
c_drawing draw;
draw.init("drawing in SDL", 640, 480, SDL_WINDOW_OPENGL);
while (draw.func_running())
{
draw.getMouseKeyEven(NULL);
draw.func_update();
draw.func_render();
SDL_Delay(1);
}
draw.func_clean();
return 0;
}
2、使用directx来画
#pragma once
#include "d3d9.h"
#include <windows.h>
#include <map>
#include "Macros.h"
#include "Locks.h"
#include <string>
#include <vector>
//#include "OverlayManager.h"
#include "Vertex.h"
using namespace std;
enum SHAPE_3D
{
D_LINE,
D_RENTANGLE,
D_POLYGON,
D_TEXT,
};
class Overlay
{
public:
Overlay(IDirect3DDevice9* device, D3DCOLOR color, BYTE opacity,INT SWidth,INT SHeight)
{
m_device = device;
m_opacity = opacity;
m_color = (color & 0x00FFFFFF) | (opacity << 24);
m_width = SWidth; // 表面宽度
m_height = SHeight;
}
virtual ~Overlay(void)
{
}
virtual HRESULT Draw(void) = 0;
//重新创建目标
virtual HRESULT ReCreate(IDirect3DDevice9* device,int newWidth,int newHeight)
{
return S_FALSE;
}
virtual void ReleaseObject()
{
return ;
}
virtual void CopyData(Overlay* pOverlay,int width,int height)
{
return;
}
virtual void ReCalculate(Overlay* pOverlay,int newWidth,int newHeight)
{
return;
}
public:
IDirect3DDevice9* m_device;
D3DCOLOR m_color;
BYTE m_opacity;
int m_type; // 表明是什么类型
float m_width; //宽度
float m_height;//高度
INT m_lineWidth; //线宽
SHORT m_id; //id号码
};
//对于新的高度和宽度重新计算点位置
//#define CalcNewPt_x(num) m_vectors[num].x= ((float)Source->m_vectors[num].x)/(float)Source->m_width* (float)newWidth
//#define CalcNewPt_y(num) m_vectors[num].y= ((float)Source->m_vectors[num].y)/(float)Source->m_height*(float)newHeight
class LineOverlay : public Overlay
{
public:
LineOverlay(IDirect3DDevice9* device, POINT p1, POINT p2, INT width, D3DCOLOR color, BYTE opacity,INT SWidth,INT SHeight)
: Overlay(device, color, opacity,SWidth,SHeight)
{
HRESULT hr = D3DXCreateLine(m_device, &m_line);
m_lineWidth = width;
m_vectors[0].x = p1.x;
m_vectors[0].y = p1.y;
m_vectors[1].x = p2.x;
m_vectors[1].y = p2.y;
m_line->SetWidth(width);
m_line->SetAntialias(TRUE);
//m_per_x = (float)p1.x / m_width
m_type = D_LINE;
}
LineOverlay():Overlay(NULL, 0, 0,0,0)
{
}
//释放资源和占有的表面
void ReleaseObject()
{
SafeRelease(m_line);
}
HRESULT ReCreate(IDirect3DDevice9* device,int width,int height)
{
if(device!=NULL)
{
m_device = device;
//释放
SafeRelease(m_line);
HRESULT hr = D3DXCreateLine(m_device, &m_line);
m_line->SetWidth(m_lineWidth);
m_line->SetAntialias(TRUE);
m_type = D_LINE;
m_vectors[0].x= ((float)m_vectors[0].x)/(float)m_width * (float)width;
m_vectors[0].y= ((float)m_vectors[0].y)/(float)m_height* (float)height;
m_vectors[1].x= ((float)m_vectors[1].x)/(float)m_width * (float)width;
m_vectors[1].y= ((float)m_vectors[1].y)/(float)m_height* (float)height;
//CalcNewPt_x(1);
//CalcNewPt_y(1);
m_width = width;
m_height = height;
return S_OK;
}
return S_FALSE;
}
virtual ~LineOverlay()
{
SafeRelease(m_line);
}
virtual HRESULT Draw(void)
{
HR(m_line->Begin());
HR(m_line->Draw(m_vectors, 2, m_color));
return m_line->End();
}
private:
CComPtr<ID3DXLine> m_line;
public:
D3DXVECTOR2 m_vectors[2];
};
class RectangleOverlay : public Overlay
{
public:
RectangleOverlay(IDirect3DDevice9* device, RECT rectangle, INT width, D3DCOLOR color, BYTE opacity,INT SWidth,INT SHeight)
: Overlay(device, color, opacity,SWidth,SHeight)
{
D3DXCreateLine(m_device, &m_line);
m_lineWidth = width;
m_line->SetWidth(m_lineWidth);
m_line->SetAntialias(TRUE);
m_vectors[0].x = rectangle.left;
m_vectors[0].y = rectangle.top;
m_vectors[1].x = rectangle.right;
m_vectors[1].y = rectangle.top;
m_vectors[2].x = rectangle.right;
m_vectors[2].y = rectangle.bottom;
m_vectors[3].x = rectangle.left;
m_vectors[3].y = rectangle.bottom;
m_vectors[4].x = rectangle.left;
m_vectors[4].y = rectangle.top;
m_type = D_RENTANGLE;
}
void ReleaseObject()
{
SafeRelease(m_line);
}
HRESULT ReCreate(IDirect3DDevice9* device,int newWidth,int newHeight)
{
if(device!=NULL)
{
SafeRelease(m_line);
m_device = device;
D3DXCreateLine(m_device, &m_line);
m_line->SetWidth(m_lineWidth);
m_line->SetAntialias(TRUE);
for(int i =0;i<5;i++)
{
m_vectors[i].x= ((float)m_vectors[i].x)/(float)m_width 以上是关于directx和opengl 电子白板的主要内容,如果未能解决你的问题,请参考以下文章