Add OpenGL test framework with logging and screenshot comparison
- Unified resolution to 1280x720 (same as D3D12) - Added XCEngine Logger integration for debug output - Added screenshot capture at frame 30 (glReadPixels -> PPM) - Added run.bat test script - Added compare_ppm.py for screenshot comparison - Added GT.ppm reference image - Added README.md documentation - Updated CMakeLists.txt to link XCEngine library Test: OpenGL rendering test passed (screenshot comparison 100% match)
This commit is contained in:
@@ -11,6 +11,7 @@ endif()
|
|||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/include/)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/include/)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/glm/)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/glm/)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/engine/include)
|
||||||
|
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/lib/)
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/package/lib/)
|
||||||
|
|
||||||
@@ -20,6 +21,18 @@ file(COPY ${copyResources} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
|
|||||||
file(GLOB assimpDll "${CMAKE_CURRENT_SOURCE_DIR}/package/dll/assimp-vc143-mt.dll")
|
file(GLOB assimpDll "${CMAKE_CURRENT_SOURCE_DIR}/package/dll/assimp-vc143-mt.dll")
|
||||||
file(COPY ${assimpDll} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
|
file(COPY ${assimpDll} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
|
||||||
|
|
||||||
|
add_custom_command(TARGET XCRender POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/compare_ppm.py
|
||||||
|
$<TARGET_FILE_DIR:XCRender>/compare_ppm.py
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(TARGET XCRender POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
|
||||||
|
$<TARGET_FILE_DIR:XCRender>/GT.ppm
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
XCRender
|
XCRender
|
||||||
main.cpp
|
main.cpp
|
||||||
@@ -30,4 +43,5 @@ target_link_libraries(XCRender
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
glfw3.lib
|
glfw3.lib
|
||||||
assimp-vc143-mt.lib
|
assimp-vc143-mt.lib
|
||||||
|
XCEngine
|
||||||
)
|
)
|
||||||
44212
tests/OpenGL/GT.ppm
Normal file
44212
tests/OpenGL/GT.ppm
Normal file
File diff suppressed because one or more lines are too long
149
tests/OpenGL/README.md
Normal file
149
tests/OpenGL/README.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
# OpenGL 测试文档
|
||||||
|
|
||||||
|
> **版本**: 1.0
|
||||||
|
> **日期**: 2026-03-16
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 概述
|
||||||
|
|
||||||
|
OpenGL 测试是 XCEngine 渲染硬件接口 (RHI) 的集成测试,用于验证 OpenGL 渲染管线的正确性。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 测试内容
|
||||||
|
|
||||||
|
### 2.1 渲染管线测试
|
||||||
|
|
||||||
|
| 测试项 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 窗口初始化 | GLFW 窗口、OpenGL 上下文创建 |
|
||||||
|
| GLAD 初始化 | OpenGL 函数加载 |
|
||||||
|
| 着色器编译 | 顶点着色器、片段着色器编译 |
|
||||||
|
| 模型加载 | 使用 Assimp 加载背包模型 |
|
||||||
|
| 纹理加载 | 加载 diffuse/specular 纹理 |
|
||||||
|
| 渲染输出 | PBR 渲染到屏幕 |
|
||||||
|
|
||||||
|
### 2.2 截图测试
|
||||||
|
|
||||||
|
程序在第 30 帧自动截图,并与基准图 `GT.ppm` 进行像素级对比。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 构建与运行
|
||||||
|
|
||||||
|
### 3.1 构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建构建目录
|
||||||
|
mkdir build && cd build
|
||||||
|
|
||||||
|
# 配置 CMake
|
||||||
|
cmake .. -A x64
|
||||||
|
|
||||||
|
# 编译
|
||||||
|
cmake --build . --config Debug --target XCRender
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 方式一:直接运行可执行文件
|
||||||
|
./build/tests/OpenGL/Debug/XCRender.exe
|
||||||
|
|
||||||
|
# 方式二:运行测试脚本(自动截图并对比)
|
||||||
|
./build/tests/OpenGL/Debug/run.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 测试流程
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 初始化 GLFW
|
||||||
|
├── 创建窗口
|
||||||
|
└── 创建 OpenGL 上下文
|
||||||
|
|
||||||
|
2. 初始化 GLAD
|
||||||
|
└── 加载 OpenGL 函数
|
||||||
|
|
||||||
|
3. 加载资源
|
||||||
|
├── 编译着色器
|
||||||
|
├── 加载模型 (Assimp)
|
||||||
|
└── 加载纹理 (stb_image)
|
||||||
|
|
||||||
|
4. 渲染循环
|
||||||
|
├── 清空帧缓冲
|
||||||
|
├── 设置 Uniforms
|
||||||
|
├── 绘制模型
|
||||||
|
└── 交换缓冲区
|
||||||
|
|
||||||
|
5. 截图验证 (第 30 帧)
|
||||||
|
├── 读取帧缓冲 (glReadPixels)
|
||||||
|
├── 保存为 PPM 格式
|
||||||
|
└── 与 GT.ppm 对比
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
tests/OpenGL/
|
||||||
|
├── CMakeLists.txt # 构建配置
|
||||||
|
├── main.cpp # 测试程序入口
|
||||||
|
├── run.bat # 运行脚本
|
||||||
|
├── compare_ppm.py # 图片对比脚本
|
||||||
|
├── Res/ # 资源目录
|
||||||
|
│ ├── models/ # 模型文件 (backpack)
|
||||||
|
│ └── shaders/ # 着色器
|
||||||
|
└── package/ # 第三方库
|
||||||
|
├── include/ # 头文件 (GLFW, GLAD, Assimp, GLM, stb_image)
|
||||||
|
└── lib/ # 库文件
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 基准图
|
||||||
|
|
||||||
|
- **GT.ppm**: 正确渲染的参考截图 (1280x720)
|
||||||
|
- **screenshot.ppm**: 程序渲染的实际截图
|
||||||
|
- **对比阈值**: 5 (像素差异容忍度)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 调试
|
||||||
|
|
||||||
|
### 7.1 日志输出
|
||||||
|
|
||||||
|
程序使用 XCEngine Logger 系统,日志输出到:
|
||||||
|
- 控制台 (ConsoleLogSink)
|
||||||
|
- 文件 (FileLogSink): `OpenGL_engine_log.txt`
|
||||||
|
|
||||||
|
### 7.2 常见问题
|
||||||
|
|
||||||
|
| 问题 | 原因 | 解决方案 |
|
||||||
|
|------|------|----------|
|
||||||
|
| 黑色画面 | 着色器编译失败 | 检查着色器错误日志 |
|
||||||
|
| 无纹理 | 纹理路径错误 | 确认 res/models/ 目录 |
|
||||||
|
| 模型未显示 | Assimp 加载失败 | 检查模型文件是否存在 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 技术细节
|
||||||
|
|
||||||
|
- **分辨率**: 1280x720
|
||||||
|
- **OpenGL 版本**: 3.3 Core Profile
|
||||||
|
- **依赖库**: GLFW, GLAD, Assimp, GLM, stb_image
|
||||||
|
- **平台**: Windows
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 与 D3D12 测试对比
|
||||||
|
|
||||||
|
| 特性 | D3D12 | OpenGL |
|
||||||
|
|------|-------|--------|
|
||||||
|
| 分辨率 | 1280x720 | 1280x720 |
|
||||||
|
| 截图帧 | 30 | 30 |
|
||||||
|
| 模型 | Sphere.lhsm | backpack.obj |
|
||||||
|
| 日志系统 | XCEngine Logger | XCEngine Logger |
|
||||||
75
tests/OpenGL/compare_ppm.py
Normal file
75
tests/OpenGL/compare_ppm.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def read_ppm(filename):
|
||||||
|
with open(filename, "rb") as f:
|
||||||
|
header = f.readline()
|
||||||
|
if header != b"P6\n":
|
||||||
|
raise ValueError(f"Not a P6 PPM file: {filename}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
line = f.readline()
|
||||||
|
if not line.startswith(b"#"):
|
||||||
|
break
|
||||||
|
|
||||||
|
dims = line.split()
|
||||||
|
width, height = int(dims[0]), int(dims[1])
|
||||||
|
|
||||||
|
line = f.readline()
|
||||||
|
maxval = int(line.strip())
|
||||||
|
|
||||||
|
data = f.read()
|
||||||
|
return width, height, data
|
||||||
|
|
||||||
|
|
||||||
|
def compare_ppm(file1, file2, threshold):
|
||||||
|
w1, h1, d1 = read_ppm(file1)
|
||||||
|
w2, h2, d2 = read_ppm(file2)
|
||||||
|
|
||||||
|
if w1 != w2 or h1 != h2:
|
||||||
|
print(f"ERROR: Size mismatch - {file1}: {w1}x{h1}, {file2}: {w2}x{h2}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
total_pixels = w1 * h1
|
||||||
|
diff_count = 0
|
||||||
|
|
||||||
|
for i in range(len(d1)):
|
||||||
|
diff = abs(d1[i] - d2[i])
|
||||||
|
if diff > threshold:
|
||||||
|
diff_count += 1
|
||||||
|
|
||||||
|
diff_percent = (diff_count / (total_pixels * 3)) * 100
|
||||||
|
|
||||||
|
print(f"Image 1: {file1} ({w1}x{h1})")
|
||||||
|
print(f"Image 2: {file2} ({w2}x{h2})")
|
||||||
|
print(f"Threshold: {threshold}")
|
||||||
|
print(f"Different pixels: {diff_count} / {total_pixels * 3} ({diff_percent:.2f}%)")
|
||||||
|
|
||||||
|
if diff_percent <= 1.0:
|
||||||
|
print("PASS: Images match!")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("FAIL: Images differ!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
print("Usage: python compare_ppm.py <file1.ppm> <file2.ppm> <threshold>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
file1 = sys.argv[1]
|
||||||
|
file2 = sys.argv[2]
|
||||||
|
threshold = int(sys.argv[3])
|
||||||
|
|
||||||
|
if not os.path.exists(file1):
|
||||||
|
print(f"ERROR: File not found: {file1}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not os.path.exists(file2):
|
||||||
|
print(f"ERROR: File not found: {file2}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
result = compare_ppm(file1, file2, threshold)
|
||||||
|
sys.exit(0 if result else 1)
|
||||||
@@ -13,9 +13,28 @@
|
|||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "XCEngine/Debug/Logger.h"
|
||||||
|
#include "XCEngine/Debug/ConsoleLogSink.h"
|
||||||
|
#include "XCEngine/Debug/FileLogSink.h"
|
||||||
|
|
||||||
const unsigned int SCR_WIDTH = 800;
|
using namespace XCEngine::Debug;
|
||||||
const unsigned int SCR_HEIGHT = 600;
|
|
||||||
|
#pragma comment(lib, "opengl32.lib")
|
||||||
|
#pragma comment(lib, "gdi32.lib")
|
||||||
|
|
||||||
|
const unsigned int SCR_WIDTH = 1280;
|
||||||
|
const unsigned int SCR_HEIGHT = 720;
|
||||||
|
|
||||||
|
void Log(const char* format, ...) {
|
||||||
|
char buffer[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
Logger::Get().Debug(LogCategory::Rendering, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
{
|
{
|
||||||
@@ -42,7 +61,7 @@ public:
|
|||||||
}
|
}
|
||||||
catch (std::ifstream::failure& e)
|
catch (std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
Log("ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* vShaderCode = vertexCode.c_str();
|
const char* vShaderCode = vertexCode.c_str();
|
||||||
@@ -102,7 +121,7 @@ private:
|
|||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR: " << type << std::endl;
|
Log("ERROR::SHADER_COMPILATION_ERROR: %s - %s", type.c_str(), infoLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -111,7 +130,7 @@ private:
|
|||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
glGetProgramInfoLog(ID, 1024, NULL, infoLog);
|
glGetProgramInfoLog(ID, 1024, NULL, infoLog);
|
||||||
std::cout << "ERROR::PROGRAM_LINKING_ERROR" << std::endl;
|
Log("ERROR::PROGRAM_LINKING_ERROR: %s", infoLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,10 +236,12 @@ unsigned int TextureFromFile(const char* path, const std::string& directory)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
Log("Texture loaded: %s (%dx%d)", filename.c_str(), width, height);
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Log("Failed to load texture: %s", filename.c_str());
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
return textureID;
|
return textureID;
|
||||||
@@ -251,8 +272,10 @@ private:
|
|||||||
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
|
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
|
||||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
{
|
{
|
||||||
|
Log("Failed to load model: %s", path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Log("Model loaded: %s", path.c_str());
|
||||||
directory = path.substr(0, path.find_last_of('/'));
|
directory = path.substr(0, path.find_last_of('/'));
|
||||||
processNode(scene->mRootNode, scene);
|
processNode(scene->mRootNode, scene);
|
||||||
}
|
}
|
||||||
@@ -333,8 +356,9 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Model* model;
|
Model* model = nullptr;
|
||||||
Shader* shader;
|
Shader* shader = nullptr;
|
||||||
|
int frameCount = 0;
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
@@ -349,9 +373,43 @@ void Initialize()
|
|||||||
exeDir = exeDir.substr(0, exeDir.find_last_of("\\/"));
|
exeDir = exeDir.substr(0, exeDir.find_last_of("\\/"));
|
||||||
SetCurrentDirectoryA(exeDir.c_str());
|
SetCurrentDirectoryA(exeDir.c_str());
|
||||||
|
|
||||||
|
Log("OpenGL Test Application Started");
|
||||||
|
|
||||||
model = new Model("res/models/backpack/backpack.obj");
|
model = new Model("res/models/backpack/backpack.obj");
|
||||||
shader = new Shader("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
shader = new Shader("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
Log("Initialization complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveScreenshot(const char* filename)
|
||||||
|
{
|
||||||
|
Log("Saving screenshot: %s", filename);
|
||||||
|
|
||||||
|
int width = SCR_WIDTH;
|
||||||
|
int height = SCR_HEIGHT;
|
||||||
|
|
||||||
|
std::vector<unsigned char> pixels(width * height * 3);
|
||||||
|
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
|
||||||
|
|
||||||
|
FILE* fp = fopen(filename, "wb");
|
||||||
|
if (!fp) {
|
||||||
|
Log("Failed to open file for screenshot: %s", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "P6\n%d %d\n255\n", width, height);
|
||||||
|
|
||||||
|
std::vector<unsigned char> flippedPixels(width * height * 3);
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
memcpy(&flippedPixels[y * width * 3], &pixels[(height - 1 - y) * width * 3], width * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(flippedPixels.data(), 1, width * height * 3, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
Log("Screenshot saved successfully");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render()
|
void Render()
|
||||||
@@ -380,6 +438,12 @@ void Render()
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
Logger::Get().AddSink(std::make_unique<FileLogSink>("OpenGL_engine_log.txt"));
|
||||||
|
Logger::Get().SetMinimumLevel(LogLevel::Debug);
|
||||||
|
|
||||||
|
AllocConsole();
|
||||||
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
@@ -388,7 +452,7 @@ int main()
|
|||||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", NULL, NULL);
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create GLFW window" << std::endl;
|
Log("Failed to create GLFW window");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -398,10 +462,13 @@ int main()
|
|||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
Log("Failed to initialize GLAD");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log("OpenGL Version: %s", glGetString(GL_VERSION));
|
||||||
|
Log("Renderer: %s", glGetString(GL_RENDERER));
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
@@ -412,8 +479,19 @@ int main()
|
|||||||
Render();
|
Render();
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
|
if (frameCount == 30) {
|
||||||
|
Log("Saving screenshot at frame %d", frameCount);
|
||||||
|
SaveScreenshot("screenshot.ppm");
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log("Application closed");
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
Logger::Get().Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
7
tests/OpenGL/run.bat
Normal file
7
tests/OpenGL/run.bat
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
cd /d "%~dp0..\..\..\..\build\tests\OpenGL\Debug"
|
||||||
|
if exist "OpenGL_engine_log.txt" del "OpenGL_engine_log.txt"
|
||||||
|
if exist "screenshot.ppm" del "screenshot.ppm"
|
||||||
|
XCRender.exe
|
||||||
|
python "%~dp0compare_ppm.py" "screenshot.ppm" "GT.ppm" 5
|
||||||
|
pause
|
||||||
Reference in New Issue
Block a user