fix: OpenGL sphere test - correct perspective matrix, depth test, texture flip, and screenshot path
This commit is contained in:
@@ -11,7 +11,8 @@ uniform mat4 gProjectionMatrix;
|
||||
|
||||
void main() {
|
||||
vec4 positionWS = gModelMatrix * aPosition;
|
||||
positionWS.x = -positionWS.x;
|
||||
vec4 positionVS = gViewMatrix * positionWS;
|
||||
gl_Position = gProjectionMatrix * positionVS;
|
||||
vTexcoord = aTexcoord;
|
||||
vTexcoord = vec2(aTexcoord.x, 1.0 - aTexcoord.y);
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
using namespace XCEngine::Debug;
|
||||
using namespace XCEngine::Containers;
|
||||
@@ -65,12 +67,12 @@ void TranslationMatrix(float* m, float x, float y, float z) {
|
||||
void PerspectiveMatrix(float* m, float fov, float aspect, float nearZ, float farZ) {
|
||||
memset(m, 0, 16 * sizeof(float));
|
||||
float tanHalfFov = tanf(fov / 2.0f);
|
||||
m[0] = 1.0f / (aspect * tanHalfFov);
|
||||
m[5] = 1.0f / tanHalfFov;
|
||||
m[10] = -(farZ + nearZ) / (farZ - nearZ);
|
||||
m[11] = -1.0f;
|
||||
m[14] = -(2.0f * farZ * nearZ) / (farZ - nearZ);
|
||||
m[0] = 1.0f / (aspect * tanHalfFov); // m[0][0]
|
||||
m[5] = 1.0f / tanHalfFov; // m[1][1]
|
||||
m[10] = -(farZ + nearZ) / (farZ - nearZ); // m[2][2]
|
||||
m[14] = -(2.0f * farZ * nearZ) / (farZ - nearZ); // m[2][3]
|
||||
m[15] = 0.0f;
|
||||
m[11] = -1.0f; // m[3][2] = -1 for OpenGL clip space
|
||||
}
|
||||
|
||||
struct Vertex {
|
||||
@@ -236,10 +238,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
float aspect = 1280.0f / 720.0f;
|
||||
PerspectiveMatrix(projectionMatrix, 45.0f * 3.14159265f / 180.0f, aspect, 0.1f, 1000.0f);
|
||||
|
||||
shader.SetMat4("gModelMatrix", modelMatrix);
|
||||
shader.SetMat4("gViewMatrix", viewMatrix);
|
||||
shader.SetMat4("gProjectionMatrix", projectionMatrix);
|
||||
shader.SetInt("uTexture", 0);
|
||||
Log("[DEBUG] ProjectionMatrix:");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Log("[DEBUG] row%d: %.4f %.4f %.4f %.4f", i,
|
||||
projectionMatrix[i*4], projectionMatrix[i*4+1], projectionMatrix[i*4+2], projectionMatrix[i*4+3]);
|
||||
}
|
||||
Log("[DEBUG] ModelMatrix:");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Log("[DEBUG] row%d: %.4f %.4f %.4f %.4f", i,
|
||||
modelMatrix[i*4], modelMatrix[i*4+1], modelMatrix[i*4+2], modelMatrix[i*4+3]);
|
||||
}
|
||||
|
||||
OpenGLPipelineState pipelineState;
|
||||
OpenGLRasterizerState rasterizerState;
|
||||
@@ -247,8 +255,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
pipelineState.SetRasterizerState(rasterizerState);
|
||||
|
||||
OpenGLDepthStencilState depthStencilState;
|
||||
depthStencilState.depthTestEnable = false;
|
||||
depthStencilState.depthWriteEnable = false;
|
||||
depthStencilState.depthTestEnable = true;
|
||||
depthStencilState.depthWriteEnable = true;
|
||||
depthStencilState.depthFunc = ComparisonFunc::Less;
|
||||
pipelineState.SetDepthStencilState(depthStencilState);
|
||||
|
||||
ViewportState viewportState = { 0.0f, 0.0f, (float)gWidth, (float)gHeight, 0.0f, 1.0f };
|
||||
@@ -257,6 +266,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
pipelineState.AttachShader(shader.GetID());
|
||||
pipelineState.Apply();
|
||||
|
||||
Log("[DEBUG] Shader program ID: %u", shader.GetID());
|
||||
int modelLoc = shader.GetUniformLocation("gModelMatrix");
|
||||
int viewLoc = shader.GetUniformLocation("gViewMatrix");
|
||||
int projLoc = shader.GetUniformLocation("gProjectionMatrix");
|
||||
Log("[DEBUG] Uniform locations - gModelMatrix: %d, gViewMatrix: %d, gProjectionMatrix: %d", modelLoc, viewLoc, projLoc);
|
||||
shader.SetMat4("gModelMatrix", modelMatrix);
|
||||
shader.SetMat4("gViewMatrix", viewMatrix);
|
||||
shader.SetMat4("gProjectionMatrix", projectionMatrix);
|
||||
shader.SetInt("uTexture", 0);
|
||||
|
||||
OpenGLTexture texture;
|
||||
if (!texture.LoadFromFile("Res/Image/earth.png", true)) {
|
||||
Log("[ERROR] Failed to load texture");
|
||||
@@ -276,6 +295,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
int frameCount = 0;
|
||||
const int targetFrameCount = 30;
|
||||
|
||||
int renderCount = 0;
|
||||
while (frameCount < targetFrameCount) {
|
||||
if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT) {
|
||||
@@ -284,17 +304,30 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
} else {
|
||||
renderCount++;
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR) Log("[DEBUG] GL error before clear: 0x%x", err);
|
||||
|
||||
commandList.SetViewport(0, 0, gWidth, gHeight);
|
||||
commandList.Clear(0.0f, 0.0f, 1.0f, 1.0f, 1);
|
||||
commandList.Clear(0.0f, 0.0f, 1.0f, 1.0f, 1 | 2); // COLOR_BUFFER | DEPTH_BUFFER
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) Log("[DEBUG] GL error after clear: 0x%x", err);
|
||||
|
||||
pipelineState.Bind();
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) Log("[DEBUG] GL error after pipeline bind: 0x%x", err);
|
||||
|
||||
indexBuffer.Bind();
|
||||
vertexArray.Bind();
|
||||
|
||||
texture.Bind(0);
|
||||
sampler.Bind(0);
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) Log("[DEBUG] GL error before draw: 0x%x", err);
|
||||
|
||||
commandList.DrawIndexed(PrimitiveType::Triangles, (uint32_t)indices.size(), 0, 0);
|
||||
|
||||
swapChain.Present(0, 0);
|
||||
@@ -302,8 +335,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
}
|
||||
|
||||
Log("[INFO] Rendered %d frames (target was %d)", renderCount, targetFrameCount);
|
||||
Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount);
|
||||
OpenGLScreenshot::Capture(device, swapChain, "sphere.ppm");
|
||||
|
||||
char exePath[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, exePath, MAX_PATH);
|
||||
char* lastSlash = strrchr(exePath, '\\');
|
||||
if (lastSlash) *lastSlash = '\0';
|
||||
strcat_s(exePath, "\\sphere.ppm");
|
||||
OpenGLScreenshot::Capture(device, swapChain, exePath);
|
||||
|
||||
sampler.Shutdown();
|
||||
texture.Shutdown();
|
||||
|
||||
Reference in New Issue
Block a user