[c++][SDL]图形学菜鸡的软渲染之路2-SDL环境配置

SDL配置

图形界面可以方便我们查看渲染结果,可以使用QT,GLFW,SDL等常见图形界面。本文使用的是SDL库,配置过程可以参考博客
从零开始软渲染0-从点开始

这里我将SDL窗口分装成一个类,和我们软渲染的核心逻辑分离,便于之后可能需要更换其他图像界面的情况发生。

//头文件SDLWindow.h
#pragma once

#include "SDL.h"
#include "SDL_revision.h"
#include "myVector.h"

class SDLWindow
{
	//The window we'll be rendering to
	SDL_Window* gWindow = NULL;
	//The window renderer
	SDL_Renderer* gRenderer = NULL;
	//初始换SDL并创建Window和renderer
	inline void init(const char* name, const int SCREEN_WIDTH, const int SCREEN_HEIGHT);
public:
	bool initSuccess;
	//构造函数调用init
	SDLWindow(const char* name,const int SCREEN_WIDTH, const int SCREEN_HEIGHT);
	//关闭SDL窗口
	void close();
	//更新窗口内容
	void refresh();
	//在窗口中绘制像素
	void drawPixel(int& x, int& y, const int& width, const int& height, ColorVec* drawBuffer);
};
//cpp文件SDLWindow.cpp
#include "SDLWindow.h"
#include <stdio.h>
#include <stdlib.h>

void SDLWindow::init(const char* name,const int  SCREEN_WIDTH, const int SCREEN_HEIGHT)
{
	//Initialization flag
	initSuccess = true;

	//Initialize SDL
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
		initSuccess = false;
	}
	else
	{
		//Set texture filtering to linear
		if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
		{
			printf("Warning: Linear texture filtering not enabled!");
		}

		//Create window
		gWindow = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
		if (gWindow == NULL)
		{
			printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
			initSuccess = false;
		}
		else
		{
			gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_SOFTWARE);
			if (gRenderer == NULL)
			{
				printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
				initSuccess = false;
			}
		}
	}
}

SDLWindow::SDLWindow(const char* name, const int SCREEN_WIDTH, const int SCREEN_HEIGHT)
{
	init(name, SCREEN_WIDTH, SCREEN_HEIGHT);
}

void SDLWindow::close()
{
	//Destroy window    
	SDL_DestroyRenderer(gRenderer);
	SDL_DestroyWindow(gWindow);

	//SDL_DestroyTexture(gTexture);
	gWindow = NULL;
	gRenderer = NULL;

	//Quit SDL subsystems
	SDL_Quit();
}

void SDLWindow::refresh()
{
	SDL_RenderPresent(gRenderer);
}

//SDL窗口默认坐标系远点为左上角,y轴朝下。我们通常使用的坐标系y轴向上坐标系在左下角。
//这里将坐标系翻转,方便我们理解。
void SDLWindow::drawPixel(int& x, int& y, const int& width, const int& height, ColorVec* drawBuffer)
{
	int bufferInd = x + y * width;
	SDL_SetRenderDrawColor(gRenderer, drawBuffer[bufferInd].x, drawBuffer[bufferInd].y, drawBuffer[bufferInd].z, drawBuffer[bufferInd].w);
	SDL_RenderDrawPoint(gRenderer, x, height - 1 - y);
}

主函数中需要手动创建双缓冲,缓存内容输出到屏幕上。具体使用流程类似:

	//创建视窗
	SDLWindow window("SoftRenderer",SCREEN_WIDTH, SCREEN_HEIGHT);
	
	//一些初始化操作...........
	
	//创建双缓存
	ColorVec* drawBuffer = new ColorVec[SCREEN_HEIGHT * SCREEN_WIDTH];
	ColorVec* showBuffer = new ColorVec[SCREEN_HEIGHT * SCREEN_WIDTH];
	ColorVec* temp = NULL;

	//绘制shadow map和ssao贴图.................
		
	//根据shadow map和SSAO绘制将数据绘制到drawBuffer
	draw(models, drawBuffer, shadowBuffer, zbuffer, SSAOTexture);

	//交换缓存
	temp = drawBuffer;
	drawBuffer = showBuffer;
	showBuffer = temp;

	//更新屏幕显示内容
	window.refresh(drawBuffer);

全部代码可以在GitHub上下载查看
SoftRenderer


版权声明:本文为weixin_43153753原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。