软件渲染第一步,利用SDL搭建软件渲染

    xiaoxiao2021-03-25  155

    偶然间突然对计算机图形学有了兴趣,最后找到了《3D游戏编程大师》,试着照着书上所写的一步步实现软件渲染算法

    但是这本书的年代比较久远了,使用的是早已经淘汰了的DirectDraw,于是软件渲染算法的学习道路上有了障碍。这本书是从零开始实现软件渲染算法,最最基础的功能有两个:一是锁定显存并直接在显存中写入数据,实现绘制一个指定位置,指定颜色的点的功能;二是将位图复制到表面上,其他的较为高级的二维渲染算法,如画线算法,多边形光栅化等等均基于这两个功能,而三维的渲染算法则又基于二维的渲染算法,因此,只要实现前面所述的最基本的两个功能,就能够一步步的照着书中所写搭建软件渲染引擎。

    接下来就介绍一下如何利用SDL2.0实现第一个绘制点的功能,代码如下,共有三个文件:T3DLIB1.h, T3DLIB1.cpp,main.cpp

    每个文件的代码如下:

    //T3DLIB1.h

    #ifndef _T3DLIB1_H #define _T3DLIB1_H #include <Windows.h> #include <SDL\SDL.h> extern HWND g_hWnd; extern HINSTANCE g_hInstance; extern SDL_Window* g_pSDLWindow; extern SDL_Surface* g_pScreenSurface; extern SDL_Surface* g_pBackSurface; extern int screen_width; extern int screen_height; extern int screen_bpp; int SD_Init(); int SD_ClearBackSurface( UINT color ); int SD_Flip(); #endif

    //T3DLIB1.cpp

    #include "T3DLIB1.h" #include <Windows.h> #include <SDL\SDL.h> HWND g_hWnd = NULL; HINSTANCE g_hInstance = NULL; SDL_Window* g_pSDLWindow = NULL; SDL_Surface* g_pScreenSurface = NULL; SDL_Surface* g_pBackSurface = NULL; int screen_width = 0; int screen_height = 0; int screen_bpp = 32; int SD_Init() { SDL_Init( SDL_INIT_VIDEO ); g_pSDLWindow = SDL_CreateWindowFrom( g_hWnd ); if ( g_pSDLWindow == NULL ) { MessageBox( NULL, L"创建SDL窗口失败!", L"错误!", MB_ICONERROR ); return 0; } g_pScreenSurface = SDL_GetWindowSurface( g_pSDLWindow ); g_pBackSurface = SDL_CreateRGBSurface( 0, screen_width, screen_height, 32, 0, 0, 0, 0 ); return 1; } int SD_ClearBackSurface( UINT color ) { SDL_FillRect( g_pBackSurface, NULL, color ); return 1; } int SD_Flip() { SDL_BlitSurface( g_pBackSurface, NULL, g_pScreenSurface, NULL ); SDL_UpdateWindowSurface( g_pSDLWindow ); return 1; }

    // main.cpp

    #include <Windows.h> #include "T3DLIB1.h" TCHAR szAppName[] = L"T3DLIB"; TCHAR szWndName[] = L"DrawPixel"; HRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); int GameInit(); int GameMain(); int GameShutdown(); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE , PSTR lpCmdLine, int nCmdShow ) { WNDCLASS wndClass; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hbrBackground = ( HBRUSH ) GetStockObject( WHITE_BRUSH ); wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wndClass.hInstance = hInstance; g_hInstance = hInstance; wndClass.lpfnWndProc = WndProc; wndClass.lpszClassName = szAppName; wndClass.lpszMenuName = NULL; wndClass.style = CS_HREDRAW | CS_VREDRAW; if ( !RegisterClass( &wndClass ) ) { MessageBox( NULL, L"注册窗口类失败", L"错误!", MB_ICONERROR ); } g_hWnd = CreateWindow( szAppName, szWndName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, 0 ); if ( !g_hWnd ) { MessageBox( NULL, L"创建窗口失败!", L"错误!", MB_ICONERROR ); } ShowWindow( g_hWnd, nCmdShow ); UpdateWindow( g_hWnd ); MSG msg; GameInit(); while ( 1 ) { if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) break; TranslateMessage( &msg ); DispatchMessage( &msg ); } GameMain(); } return 0; } HRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static HDC hdc; static PAINTSTRUCT ps; switch ( uMsg ) { case WM_SIZE: hdc = BeginPaint( hWnd, &ps ); RECT rect; GetClientRect( hWnd, &rect ); screen_width = rect.right - rect.left; screen_height = rect.bottom - rect.top; EndPaint( hWnd, &ps ); return 0; case WM_DESTROY: PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } int GameInit() { SD_Init(); return 1; } int GameMain() { SD_ClearBackSurface( 0 ); SDL_LockSurface( g_pBackSurface ); int lpitch = ( g_pBackSurface->pitch >> 2 ); UINT* video_buffer = ( UINT* ) g_pBackSurface->pixels; for ( int i = 0; i < 1000; i++ ) { int x = rand() % screen_width; int y = rand() % screen_height; video_buffer[ x + y * lpitch ] = 0x00ff0000; } SDL_UnlockSurface( g_pBackSurface ); SD_Flip(); for ( int i = 0; i < 1000; i++ ) { } return 1; } int GameShutdown() { return 1; }

    代码量很小,就不写注释了

    最后达到的效果如图:

    有了这个就可以一步步照着书往下实现软件渲染引擎了

    转载请注明原文地址: https://ju.6miu.com/read-1795.html

    最新回复(0)