You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:02:35