OpenGL接口的基本实现1[转]

OpenGL接口的基本实现1[转]

目录

绘制点

绘制直线

绘制颜色渐变直线

绘制线封装

贝塞尔曲线绘制

Windows API 参考:Windows 编程之路

绘制点

  • Raster.h
#pragma once
#include "CELLMath.hpp"

namespace   CELL
{
	class Raster
	{
	public:
		Rgba*   _buffer;
		int     _width;
		int     _height;
	public:
		Raster(int w, int h, void* buffer);
		~Raster(void);
		void    clear();
		void    drawPoint(int x, int y, Rgba color, int ptSize);
	public:
		inline  void    setPixel(unsigned x, unsigned y, Rgba color)
		{
			if (x >= _width || y >= _height)
			{
				return;
			}
			_buffer[y * _width + x] = color;
		}
	};
}
  • Raster.cpp

#include "Raster.h"

namespace   CELL
{
	Raster::Raster(int w, int h, void* buffer)
	{
		_width = w;
		_height = h;
		_buffer = (Rgba*)buffer;
	}
	Raster::~Raster(void)
	{
	}
	void Raster::clear()
	{
		memset(_buffer, 0, _width * _height * sizeof(Rgba));
	}
	void Raster::drawPoint(int x, int y, Rgba color, int ptSize)
	{
		switch (ptSize)
		{
		case 1:
			setPixel(x, y, color);
			break;
		case 2:
			setPixel(x + 0, y + 0, color);
			setPixel(x + 1, y + 0, color);
			setPixel(x + 0, y + 1, color);
			setPixel(x + 1, y + 1, color);
			break;
		}
	}
}
  • main.cpp
#include <windows.h>
#include <tchar.h>
#include "Raster.h"

LRESULT CALLBACK    windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_SIZE:
		break;
	case WM_CLOSE:
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		break;
	}

	return  DefWindowProc(hWnd, msg, wParam, lParam);
}

int     WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//  1   注册窗口类
	::WNDCLASSEXA winClass;
	winClass.lpszClassName = "Raster";
	winClass.cbSize = sizeof(::WNDCLASSEX);
	winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
	winClass.lpfnWndProc = windowProc;
	winClass.hInstance = hInstance;
	winClass.hIcon = 0;
	winClass.hIconSm = 0;
	winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
	winClass.lpszMenuName = NULL;
	winClass.cbClsExtra = 0;
	winClass.cbWndExtra = 0;
	RegisterClassExA(&winClass);

	//  2 创建窗口
	HWND    hWnd = CreateWindowExA(
		NULL,
		"Raster",
		"Raster",
		WS_POPUPWINDOW,
		200,
		200,
		256,
		256,
		0,
		0,
		hInstance,
		0
	);

	UpdateWindow(hWnd);
	ShowWindow(hWnd, SW_SHOW);

	//获取窗口大小
	RECT    rt = { 0 };
	GetClientRect(hWnd, &rt);

	int     width = rt.right - rt.left;
	int     height = rt.bottom - rt.top;
	void*   buffer = 0;

	HDC     hDC = GetDC(hWnd);
	HDC     hMem = ::CreateCompatibleDC(hDC);

	BITMAPINFO	bmpInfor;
	bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfor.bmiHeader.biWidth = width;
	bmpInfor.bmiHeader.biHeight = height;
	bmpInfor.bmiHeader.biPlanes = 1;
	bmpInfor.bmiHeader.biBitCount = 32;
	bmpInfor.bmiHeader.biCompression = BI_RGB;
	bmpInfor.bmiHeader.biSizeImage = 0;
	bmpInfor.bmiHeader.biXPelsPerMeter = 0;
	bmpInfor.bmiHeader.biYPelsPerMeter = 0;
	bmpInfor.bmiHeader.biClrUsed = 0;
	bmpInfor.bmiHeader.biClrImportant = 0;

	HBITMAP	hBmp = CreateDIBSection(hDC, &bmpInfor, DIB_RGB_COLORS, (void**)&buffer, 0, 0);
	SelectObject(hMem, hBmp);

	CELL::Raster raster(width, height, buffer);

	MSG     msg = { 0 };
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		if (msg.message == WM_DESTROY
			|| msg.message == WM_CLOSE
			|| msg.message == WM_QUIT)
		{
			break;
		}
		raster.clear();
		for (int i = 0; i < 100; ++i)
		{
			raster.drawPoint(rand() % 256, rand() % 256, CELL::Rgba(255, 0, 0), 2);
		}

		memcpy(buffer, raster._buffer, raster._width * raster._height * sizeof(CELL::Rgba));
		BitBlt(hDC, 0, 0, width, height, hMem, 0, 0, SRCCOPY);

	}

	return  0;
}

绘制直线

void    drawLine(float2 pt1, float2 pt2, Rgba color)
{
	float   xOffset = pt1.x - pt2.x;
	float   yOffset = pt1.y - pt2.y;

	if (xOffset == 0 && yOffset == 0)
	{
		setPixel(pt1.x, pt1.y, color);
	}

	if (fabs(xOffset) > fabs(yOffset))
	{
		float   slope = yOffset / xOffset;

		float   xMin;
		float   xMax;
		if (pt1.x < pt2.x)
		{
			xMin = pt1.x;
			xMax = pt2.x;
		}
		else
		{
			xMin = pt2.x;
			xMax = pt1.x;
		}

		for (float x = xMin; x <= xMax; x += 1.0f)
		{
			float   y = pt1.y + (x - pt1.x) * slope;
			setPixel(x, y, color);
		}
	}
	else
	{
		float   slope = xOffset / yOffset;

		float   yMin;
		float   yMax;
		if (pt1.y < pt2.y)
		{
			yMin = pt1.y;
			yMax = pt2.y;
		}
		else
		{
			yMin = pt2.y;
			yMax = pt1.y;
		}
		for (float y = pt1.y; y <= pt2.y; y += 1.0f)
		{
			float   x = pt1.x + (y - pt1.y) * slope;
			setPixel(pt2.x, y, color);
		}
	}
}
  • 调用:
raster.drawLine(CELL::float2(-11, 111), CELL::float2(666, 222), CELL::Rgba(255, 0, 0));

绘制颜色渐变直线

void Raster::drawLine( float2 pt1,float2 pt2,Rgba color1,Rgba color2 )
{
    float   xOffset =   pt1.x - pt2.x;
    float   yOffset =   pt1.y - pt2.y;

    if (xOffset == 0 && yOffset == 0)
    {
        setPixel(pt1.x,pt1.y,color1);
    }

    if (fabs(xOffset) > fabs(yOffset))
    {
        float   slope   =   yOffset / xOffset;

        float   xMin;
        float   xMax;
        if (pt1.x < pt2.x)
        {
            xMin    =   pt1.x;
            xMax    =   pt2.x;
        }
        else
        {
            xMin    =   pt2.x;
            xMax    =   pt1.x;
        }
        
        float   lenth   =   xMax - xMin;
        for (float x = xMin; x <= xMax ; x += 1.0f)
        {
            float   y       =   pt1.y + (x - pt1.x) * slope;
            float   scaler  =   (x - xMin)/lenth;
            Rgba    color   =   colorLerp(color1,color2,scaler);
            setPixel(x,y,color);
        }
    }
    else
    {
        float   slope   =   xOffset / yOffset;

        float   yMin;
        float   yMax;
        if (pt1.y < pt2.y)
        {
            yMin    =   pt1.y;
            yMax    =   pt2.y;
        }
        else
        {
            yMin    =   pt2.y;
            yMax    =   pt1.y;
        }

        float   lenth   =   yMax - yMin;
        for (float y = pt1.y; y <= pt2.y ; y += 1.0f)
        {
            float   x       =   pt1.x + (y - pt1.y) * slope;
            float   scaler  =   (y - yMin)/lenth;
            Rgba    color   =   colorLerp(color1,color2,scaler);
            setPixel(pt2.x,y,color);
        }
    }
}
  • 调用:
raster.drawLine(CELL::float2(1,100),CELL::float2(200,33),CELL::Rgba(255,0,0),CELL::Rgba(0,255,0));

绘制线封装

enum    DRAWMODE
{
    DM_POINTS       =   0,
    DM_LINES        =   1,
    DM_LINE_LOOP    =   2,
    DM_LINE_STRIP   =   3,
};

void    drawArrays(DRAWMODE mode, const float2* points, int count)
{
	switch (mode)
	{
	case DM_POINTS:
	{
		for (int i = 0; i < count; ++i)
		{
			drawPoints(points[i], _color);
		}
	}
	break;
	case DM_LINES:
	{
		count = count / 2 * 2;
		for (int i = 0; i < count - 1; ++i)
		{
			drawLine(points[i], points[i + 1], _color, _color);
		}
	}
	break;
	case DM_LINE_LOOP:
	{
		drawLine(points[0], points[1], _color, _color);
		for (int i = 2; i < count; ++i)
		{
			drawLine(points[i - 1], points[i], _color, _color);
		}
		drawLine(points[0], points[count - 1], _color, _color);
	}
	break;
	case DM_LINE_STRIP:
	{
		drawLine(points[0], points[1], _color, _color);
		for (int i = 2; i < count; ++i)
		{
			drawLine(points[i - 1], points[i], _color, _color);
		}
	}
	break;
	default:
		break;
	}
}
  • 调用:
CELL::float2    arPoints[] =
{
	CELL::float2(11,34),
	CELL::float2(33,66),
	CELL::float2(1,100),
	CELL::float2(22,88),
	CELL::float2(100,1),
};
raster.drawArrays(CELL::DM_LINE_STRIP, arPoints, sizeof(arPoints) / sizeof(arPoints[0]));


//绘制直线
CELL::float2    arPoints1[] =
{
	CELL::float2(0,0),
	CELL::float2(133,166),
};
raster.drawArrays(CELL::DM_LINES, arPoints1, 2);

//绘制圆
CELL::float2    center(100, 100);
float           radius = 80;
CELL::float2    arCircle[360];
for (int i = 0; i < 360; ++i)
{
	float   rad = DEG2RAD(i);
	arCircle[i].x = radius * cos(rad) + center.x;
	arCircle[i].y = radius * sin(rad) + center.y;
}
raster.drawArrays(CELL::DM_LINE_STRIP, arCircle, sizeof(arCircle) / sizeof(arCircle[0]));

贝塞尔曲线绘制

CELL::float2    points[] =
{
	CELL::float2(50,50),
	CELL::float2(20,360),
	CELL::float2(89,10),
	CELL::float2(159,100),
};

CELL::float2 prev[2];
for (float t = 0; t < 1.0f; t += 0.01f)
{
	float x = points[0].x * pow(1 - t, 3)
		+ 3 * points[1].x * t * pow(1 - t, 2)
		+ 3 * points[2].x * t*t * (1 - t)
		+ points[3].x * t * t * t;
	float y = points[0].y * pow(1 - t, 3)
		+ 3 * points[1].y * t * pow(1 - t, 2)
		+ 3 * points[2].y * t*t * (1 - t)
		+ points[3].y * t * t * t;
	if (t == 0)
	{
		prev[0] = CELL::float2(x, y);
	}
	else
	{
		prev[1] = CELL::float2(x, y);
		raster.drawArrays(CELL::DM_LINES, prev, 2);
		prev[0] = prev[1];
	}
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值