Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
bw_render.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : ww3d *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/BW_Render.cpp $*
26 * *
27 * Original Author:: Jani Penttinen *
28 * *
29 * $Author:: Greg_h $*
30 * *
31 * $Modtime:: 2/06/01 10:57a $*
32 * *
33 * $Revision:: 4 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39
40#include "bw_render.h"
41#include "vp.h"
42#include <string.h>
43
44BW_Render::Buffer::Buffer(unsigned char* buffer_, int scale_)
45 :
46 buffer(buffer_),
47 scale(scale_),
48 minv(3),
49 maxv(scale_-3)
50{
51}
52
53BW_Render::Buffer::~Buffer()
54{
55}
56
57void BW_Render::Buffer::Set_H_Line(int start_x, int end_x, int y)
58{
59 if (y<minv || y>=maxv || end_x<minv || start_x>=maxv) return;
60 if (start_x<minv) start_x=minv;
61 if (end_x>=maxv) end_x=maxv-1;
62 unsigned char* ptr=buffer+scale*y+start_x;
63 int w=end_x-start_x;
64 if (w) {
65 ::memset(ptr,0x00,w);
66
67/* // Blurring (test)
68 *(ptr-1)&=0x80;
69 *(ptr-2)&=0xc0;
70 *(ptr+w)&=0x80;
71 *(ptr+w+1)&=0xc0;
72 for (int a=0;a<w;++a) {
73 *(ptr-scale+a)&=0xc0;
74 *(ptr+scale+a)&=0xc0;
75 }
76*/
77 }
78}
79
80void BW_Render::Buffer::Fill(unsigned char c)
81{
82 memset(buffer,c,scale*scale);
83}
84
85// ------------------------------------------------------------------------------
86
87BW_Render::BW_Render(unsigned char* buffer, int buffer_scale)
88 :
89 pixel_buffer(buffer,buffer_scale)
90{
91}
92
96
97void BW_Render::Fill(unsigned char c)
98{
99 pixel_buffer.Fill(c);
100}
101
102// Sets the vertex coordinate buffer location and scales the vertex locations to the kjkj
103void BW_Render::Set_Vertex_Locations(Vector2* vertices_,int count)
104{
105 vertices=vertices_;
106
107 float half_scale=pixel_buffer.Scale()*0.5f;
109 reinterpret_cast<float*>(vertices),
110 half_scale,
111 half_scale,
112 count*2);
113}
114
115// --------------------------------------------------------------------
116
117static inline bool Cull(
118 const Vector2& c1,
119 const Vector2& c2,
120 const Vector2& c3)
121{
122 float x1=c2[0]-c1[0];
123 float y1=c2[1]-c1[1];
124 float x2=c3[0]-c1[0];
125 float y2=c3[1]-c1[1];
126 float r=x1*y2-x2*y1;
127 if (r<0) return false;
128 return true;
129}
130
131void BW_Render::Render_Triangle_Strip(const unsigned long* indices,int index_count)
132{
133 index_count-=2;
134 bool b=false;
135 for (int n=0;n<index_count;++n) {
136 b=!b;
137 int idx_1=indices[0];
138 int idx_2=indices[1];
139 int idx_3=indices[2];
140 indices++;
141
142 if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])==b) continue;
143
144 Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
145 Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
146 Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
147
148 // Sort the corners on y axis
149
150 if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
151 if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
152 if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
153
154 Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
155 Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
156
157 Render_Preprocessed_Triangle(xcf,yci);
158 }
159}
160
161void BW_Render::Render_Triangles(const unsigned long* indices,int index_count)
162{
163 index_count/=3;
164 for (int n=0;n<index_count;++n) {
165 int idx_1=*indices++;
166 int idx_2=*indices++;
167 int idx_3=*indices++;
168
169 if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])) continue;
170
171 Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
172 Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
173 Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
174
175 // Sort the corners on y axis
176
177 if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
178 if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
179 if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
180
181 Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
182 Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
183
184 Render_Preprocessed_Triangle(xcf,yci);
185 }
186}
187
188void BW_Render::Render_Preprocessed_Triangle(Vector3& xcf,Vector3i& yci)
189{
190 float x_left=xcf[0];
191 float x_right=x_left;
192 int ycnt=yci[1]-yci[0];
193 int y=yci[0];
194 if (ycnt) {
195 float x_step_1=(xcf[1]-xcf[0])/float(ycnt);
196 float x_step_2=(xcf[2]-xcf[0])/float(yci[2]-y);
197 if (x_step_1>x_step_2) {
198 float t=x_step_1;
199 x_step_1=x_step_2;
200 x_step_2=t;
201 }
202
203 while (ycnt>0) {
204 pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
205
206 x_left+=x_step_1;
207 x_right+=x_step_2;
208 ycnt--;
209 y++;
210 }
211 }
212 else {
213 if (xcf[0]<xcf[1]) {
214 x_left=xcf[0];
215 x_right=xcf[1];
216 }
217 else {
218 x_right=xcf[0];
219 x_left=xcf[1];
220 }
221
222 }
223
224 ycnt=yci[2]-yci[1];
225 y=yci[1];
226
227 if (ycnt) {
228 float one_per_ycnt=1.0f/float(ycnt);
229 float x_step_1=(xcf[2]-x_left)*one_per_ycnt;
230 float x_step_2=(xcf[2]-x_right)*one_per_ycnt;
231 while (ycnt>0) {
232 pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
233 x_left+=x_step_1;
234 x_right+=x_step_2;
235 ycnt--;
236 y++;
237 }
238 }
239
240}
241
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
WWINLINE void Swap(Vector2 &a, Vector2 &b)
Definition vector2.h:488
void Render_Triangle_Strip(const unsigned long *indices, int index_count)
void Render_Triangles(const unsigned long *indices, int index_count)
BW_Render(unsigned char *buffer, int scale)
Definition bw_render.cpp:87
void Set_Vertex_Locations(Vector2 *vertices, int count)
void Fill(unsigned char c)
Definition bw_render.cpp:97
WWINLINE void Scale(float a, float b)
Definition vector2.h:564
static void MulAdd(float *dest, float multiplier, float add, int count)
Definition vp.cpp:516
static long Float_To_Long(float f)
Definition wwmath.h:322
char buffer[1024]