SDL2渲染立方体时所有三角形变为一条线的问题求助
3D渲染立方体显示为一条线的问题排查
我正在学习javidx9的《3D Graphics》系列教程,使用SDL2替代olcConsoleGameEngine进行开发,目前推进到旋转功能实现前的阶段,但渲染立方体时所有三角形都显示为屏幕中部附近的一条线。
代码
3D.h
#pragma once #include <vector> #include <cmath> #include "stdio.h" #include "SDL.h" struct Vector3 { float x, y, z; }; struct Triangle { Vector3 points[3]; }; struct Mesh { std::vector<Triangle> Triangles; }; struct Matrix4x4 { float m[4][4] = {0}; }; class Camera { public: Mesh cube; Matrix4x4 projectionMatrix; void init(int width, int height, float FOV, float nearPlane, float farPlane) { cube.Triangles = { { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, }; float fovRad = 1.0f / tanf(FOV * 0.5f / 180.0f * 3.14159f); projectionMatrix.m[0][0] = (float)(height/width)*fovRad; projectionMatrix.m[1][1] = fovRad; projectionMatrix.m[2][2] = farPlane / (farPlane - nearPlane); projectionMatrix.m[3][2] = (-farPlane * nearPlane) / (farPlane - nearPlane); projectionMatrix.m[2][3] = 1.0f; projectionMatrix.m[3][3] = 0.0f; } void renderTriangle(int width, int height, SDL_Renderer* renderer, Triangle tri) { Triangle triProjected, triTranslated; triTranslated = tri; triTranslated.points[0].z = tri.points[0].z + 3.0f; triTranslated.points[1].z = tri.points[1].z + 3.0f; triTranslated.points[2].z = tri.points[2].z + 3.0f; MultiplyMatrixVector(triTranslated.points[0], triProjected.points[0], projectionMatrix); MultiplyMatrixVector(triTranslated.points[1], triProjected.points[1], projectionMatrix); MultiplyMatrixVector(triTranslated.points[2], triProjected.points[2], projectionMatrix); triProjected.points[0].x += 1.0f; triProjected.points[0].y += 1.0f; triProjected.points[1].x += 1.0f; triProjected.points[1].y += 1.0f; triProjected.points[2].x += 1.0f; triProjected.points[2].y += 1.0f; triProjected.points[0].x *= 0.5f * (float)width; triProjected.points[0].y *= 0.5f * (float)height; triProjected.points[1].x *= 0.5f * (float)width; triProjected.points[1].y *= 0.5f * (float)height; triProjected.points[2].x *= 0.5f * (float)width; triProjected.points[2].y *= 0.5f * (float)height; SDL_RenderDrawLine(renderer, (int)triProjected.points[0].x, (int)triProjected.points[0].y, (int)triProjected.points[1].x, (int)triProjected.points[1].y); SDL_RenderDrawLine(renderer, (int)triProjected.points[1].x, (int)triProjected.points[1].y, (int)triProjected.points[2].x, (int)triProjected.points[2].y); SDL_RenderDrawLine(renderer, (int)triProjected.points[2].x, (int)triProjected.points[2].y, (int)triProjected.points[0].x, (int)triProjected.points[0].y); } void MultiplyMatrixVector(Vector3 &i, Vector3 &o, Matrix4x4 &m) { o.x = i.x * m.m[0][0] + i.y * m.m[1][0] + i.z * m.m[2][0] + m.m[3][0]; o.y = i.x * m.m[0][1] + i.y * m.m[1][1] + i.z * m.m[2][1] + m.m[3][1]; o.z = i.x * m.m[0][2] + i.y * m.m[1][2] + i.z * m.m[2][2] + m.m[3][2]; float w = i.x * m.m[0][3] + i.y * m.m[1][3] + i.z * m.m[2][3] + m.m[3][3]; if (w != 0.0f) { o.x /= w; o.y /= w; o.z /= w; } } };
Game.h
#pragma once #include "SDL.h" #include "3D.h" void draw2DTriangle(SDL_Renderer* renderer, int ax, int ay, int bx, int by, int cx, int cy) { SDL_RenderDrawLine(renderer, ax, ay, bx, by); SDL_RenderDrawLine(renderer, bx, by, cx, cy); SDL_RenderDrawLine(renderer, cx, cy, ax, ay); } class Game { public: Game() {}; ~Game() {}; void init(const char* title, int width, int height, bool fullscreen) { SDL_Init(SDL_INIT_EVERYTHING); int flags = SDL_WINDOW_SHOWN; if (fullscreen) { int flags = SDL_WINDOW_FULLSCREEN; } window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags); renderer = SDL_CreateRenderer(window, -1, 0); isRunning = true; camera.init(1280, 720, 90.0f, 0.1f, 1000.0f); }; void update() { }; void render() { SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[0]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[1]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[2]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[3]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[4]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[5]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[6]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[7]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[8]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[9]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[10]); camera.renderTriangle(1280, 720, renderer, camera.cube.Triangles[11]); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderPresent(renderer); }; void handleEvents() { SDL_Event event; SDL_PollEvent(&event); switch (event.type) { case SDL_QUIT: isRunning = false; break; } }; void clean() { SDL_DestroyWindow(window); SDL_DestroyRenderer(renderer); SDL_Quit(); }; bool running() { return isRunning; }; private: bool isRunning{}; SDL_Window* window{}; SDL_Renderer* renderer{}; Camera camera; };
已进行初步调试,排除了MultiplyMatrixVector函数的问题,至少我认为该函数不是问题所在。
内容的提问来源于stack exchange,提问作者user21956960
相关产品推荐
相关产品推荐

