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版权协议,转载请附上原文出处链接和本声明。