软件渲染:为什么我的顶点没有被转换?

huangapple 未分类评论47阅读模式
英文:

Software Rendering: Why aren't my vertices being transformed?

问题

package PixelVision.Rendering;

import PixelVision.Math.*;
import java.util.ArrayList;

/*
 * 这个类位于引擎的实现中。该对象从抽象网格的渲染到将渲染坐标缩放到屏幕尺寸。
 * 
 * 完整列表:
 * ~ 将坐标缩放到屏幕空间。 (0, 0) 是屏幕中心。
 * ~ 对超出屏幕的三角形执行三角形裁剪。
 * ~ 抽象网格的渲染
 */

public final class SWRenderer {
	
	private Bitmap target;
	public ArrayList<Model> Models;
	Mat4x4 projectionMat, viewMat;
	Vec3 Camera, CameraDir, LightDir;

	public SWRenderer() {
		Models = new ArrayList<Model>();
	}
	
	public void SetRenderTarget(Bitmap tar) {
		target = tar;
	}
	
	public void Init() {
		projectionMat = Mat4x4.GetProjection(90f, 1f, 100f);
		Camera = new Vec3();
		LightDir = new Vec3(0, 0, -1f);
	}
	
	public void Render() {
		for(Model m : Models) {
			RenderModel(m);
		}
	}

	private void RenderModel(Model model) {

		Vec3[] vertices = model.getMesh().GetVertexData().clone();
		Triangle[] tris = model.getMesh().GetTriangles().clone();

		for(int v = 0; v < vertices.length; v++) {
			WorldTransform(vertices[v], model);
			ViewTransform(vertices[v]);
			ProjectionTransform(vertices[v]);
		}

		for(Triangle tri : tris) {
			Vec2 v1, v2, v3;
			v1 = new Vec2(vertices[tri.Verts[0]].x, vertices[tri.Verts[0]].y);
			v2 = new Vec2(vertices[tri.Verts[1]].x, vertices[tri.Verts[1]].y);
			v3 = new Vec2(vertices[tri.Verts[2]].x, vertices[tri.Verts[2]].y);

			ScaleVertexToScreen(v1);
			ScaleVertexToScreen(v2);
			ScaleVertexToScreen(v3);

			RasterizeTriangle(v1, v2, v3);
		}
	}

	private void WorldTransform(Vec3 vert, Model currentModel) {

		vert = Mat4x4.Mul(Mat4x4.GetScale(currentModel.getScale()), vert); // 缩放

		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getOrigin().GetNegative()), vert); // 绕模型原点旋转
		vert = Mat4x4.Mul(Mat4x4.GetRotation(currentModel.getRotation()), vert);
		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getOrigin()), vert);

		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getLocation()), vert); // 平移
	}

	private void ViewTransform(Vec3 vert) {
		// 尚未实现
	}

	private void ProjectionTransform(Vec3 vert) {
		Mat4x4.Mul(projectionMat, vert);
	}

	private void ScaleVertexToScreen(Vec2 vert) {

		vert.x += 1.0f;
		vert.y += 1.0f;
		vert.x *= 0.5f * (float)target.GetWidth();
		vert.y *= 0.5f * (float)target.GetHeight();
	}

	private void RasterizeTriangle(Vec2 v1, Vec2 v2, Vec2 v3) {
		Color c = new Color(Color.RED);
		Draw.DrawLine(v1, v2, target, c);
		Draw.DrawLine(v2, v3, target, c);
		Draw.DrawLine(v3, v1, target, c);
	}
}
英文:

I'm currently working on a basic software rendering project and am running into an issue. I've been refactoring and cleaning for a bit so a few things has changed in the rendering code. The issue I'm having at the moment is that even though my list of vertices is being transformed, when the model is rendered, it hasn't been transformed at all. I'm wondering why this is happening since I'm passing objects (Vec3) to the transform functions, and they are being manipulated within those functions, why aren't those changes remaining?

package PixelVision.Rendering;

import PixelVision.Math.*;
import java.util.ArrayList;

/*
 * This class sits in an implementation of the Engine. This Object does
 * everything from abstracting the rendering of meshes, to scaling the
 * rendered coordinates to the screen size.
 * 
 * Full List:
 * ~Scales Coordinates to ScreenSpace. (0, 0) is the center of the screen.
 * ~Performs triangle clipping of triangles that go outside the screen.
 * ~abstracts the rendering of meshes
 */

public final class SWRenderer {
	
	private Bitmap target;
	public ArrayList&lt;Model&gt; Models;
	Mat4x4 projectionMat, viewMat;
	Vec3 Camera, CameraDir, LightDir;

	public SWRenderer() {
		Models = new ArrayList&lt;Model&gt;();
	}
	
	public void SetRenderTarget(Bitmap tar) {
		target = tar;
	}
	
	public void Init() {
		projectionMat = Mat4x4.GetProjection(90f, 1f, 100f);
		Camera = new Vec3();
		LightDir = new Vec3(0, 0, -1f);
	}
	
	public void Render() {
		for(Model m : Models) {
			RenderModel(m);
		}
	}

	private void RenderModel(Model model) {

		Vec3[] vertices = model.getMesh().GetVertexData().clone();
		Triangle[] tris = model.getMesh().GetTriangles().clone();

		for(int v = 0; v &lt; vertices.length; v++) {
			WorldTransform(vertices[v], model);
			ViewTransform(vertices[v]);
			ProjectionTransform(vertices[v]);
		}

		for(Triangle tri : tris) {
			Vec2 v1, v2, v3;
			v1 = new Vec2(vertices[tri.Verts[0]].x, vertices[tri.Verts[0]].y);
			v2 = new Vec2(vertices[tri.Verts[1]].x, vertices[tri.Verts[1]].y);
			v3 = new Vec2(vertices[tri.Verts[2]].x, vertices[tri.Verts[2]].y);

			ScaleVertexToScreen(v1);
			ScaleVertexToScreen(v2);
			ScaleVertexToScreen(v3);

			RasterizeTriangle(v1, v2, v3);
		}
	}

	private void WorldTransform(Vec3 vert, Model currentModel) {

		vert = Mat4x4.Mul(Mat4x4.GetScale(currentModel.getScale()), vert); //Scaling

		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getOrigin().GetNegative()), vert); //Rotation about models origin
		vert = Mat4x4.Mul(Mat4x4.GetRotation(currentModel.getRotation()), vert);
		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getOrigin()), vert);

		vert = Mat4x4.Mul(Mat4x4.GetTranslation(currentModel.getLocation()), vert); //Translation
	}

	private void ViewTransform(Vec3 vert) {
		//not yet implemented
	}

	private void ProjectionTransform(Vec3 vert) {
		Mat4x4.Mul(projectionMat, vert);
	}

	private void ScaleVertexToScreen(Vec2 vert) {

		vert.x += 1.0f;
		vert.y += 1.0f;
		vert.x *= 0.5f * (float)target.GetWidth();
		vert.y *= 0.5f * (float)target.GetHeight();
	}

	private void RasterizeTriangle(Vec2 v1, Vec2 v2, Vec2 v3) {
		Color c = new Color(Color.RED);
		Draw.DrawLine(v1, v2, target, c);
		Draw.DrawLine(v2, v3, target, c);
		Draw.DrawLine(v3, v1, target, c);
	}
}

答案1

得分: 0

WorldTransform 函数中对于 vert 的赋值仅影响局部变量 vert 的引用。这不会改变所引用的对象,因此不会对顶点进行变换。如果需要进行变换(如果需要进行赋值),你的变换函数应该返回新值。

vertices[v]=WorldTransform(vertices[v], model);
...
private Vec3 WorldTransform(Vec3 vert, Model currentModel){
    //应用变换
    return vert;
}
英文:

Your assignments for vert in the WorldTransform function only affect the reference for the local vert variable. This does not alter the referenced object and hence does not transform your vertices. Your transform functions(if assignment is necessary), should return the new value.

vertices[v]=WorldTransform(vertices[v], model);
...
private Vec3 WorldTransform(Vec3 vert, Model currentModel){
    //Apply transformations
    return vert;
}

huangapple
  • 本文由 发表于 2020年4月9日 09:04:33
  • 转载请务必保留本文链接:https://java.coder-hub.com/61112389.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定