Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
bwrender.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 : ww3d2 *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/bwrender.cpp $*
26 * *
27 * Original Author:: Jani Penttinen *
28 * *
29 * $Author:: Greg_h $*
30 * *
31 * $Modtime:: 4/04/01 10:14a $*
32 * *
33 * $Revision:: 2 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39
40#include "bwrender.h"
41#include "vp.h"
42#include <string.h>
43
44
45BWRenderClass::Buffer::Buffer(unsigned char* buffer_, int scale_)
46 :
47 buffer(buffer_),
48 scale(scale_),
49 minv(3),
50 maxv(scale_-3)
51{
52}
53
54BWRenderClass::Buffer::~Buffer()
55{
56}
57
58void BWRenderClass::Buffer::Set_H_Line(int start_x, int end_x, int y)
59{
60 if (y<minv || y>=maxv || end_x<minv || start_x>=maxv) return;
61 if (start_x<minv) start_x=minv;
62 if (end_x>=maxv) end_x=maxv-1;
63 unsigned char* ptr=buffer+scale*y+start_x;
64 int w=end_x-start_x;
65 if (w) {
66 ::memset(ptr,0x00,w);
67
68/* // Blurring (test)
69 *(ptr-1)&=0x80;
70 *(ptr-2)&=0xc0;
71 *(ptr+w)&=0x80;
72 *(ptr+w+1)&=0xc0;
73 for (int a=0;a<w;++a) {
74 *(ptr-scale+a)&=0xc0;
75 *(ptr+scale+a)&=0xc0;
76 }
77*/
78 }
79}
80
81void BWRenderClass::Buffer::Fill(unsigned char c)
82{
83 memset(buffer,c,scale*scale);
84}
85
86// ------------------------------------------------------------------------------
87
88BWRenderClass::BWRenderClass(unsigned char* buffer, int buffer_scale)
89 :
90 pixel_buffer(buffer,buffer_scale)
91{
92}
93
97
98void BWRenderClass::Fill(unsigned char c)
99{
100 pixel_buffer.Fill(c);
101}
102
103// Sets the vertex coordinate buffer location and scales the vertex locations to the kjkj
105{
106 vertices=vertices_;
107
108 float half_scale=pixel_buffer.Scale()*0.5f;
110 reinterpret_cast<float*>(vertices),
111 half_scale,
112 half_scale,
113 count*2);
114}
115
116// --------------------------------------------------------------------
117
118static inline bool Cull(
119 const Vector2& c1,
120 const Vector2& c2,
121 const Vector2& c3)
122{
123 float x1=c2[0]-c1[0];
124 float y1=c2[1]-c1[1];
125 float x2=c3[0]-c1[0];
126 float y2=c3[1]-c1[1];
127 float r=x1*y2-x2*y1;
128 if (r<0) return false;
129 return true;
130}
131
132void BWRenderClass::Render_Triangle_Strip(const unsigned long* indices,int index_count)
133{
134 index_count-=2;
135 bool b=false;
136 for (int n=0;n<index_count;++n) {
137 b=!b;
138 int idx_1=indices[0];
139 int idx_2=indices[1];
140 int idx_3=indices[2];
141 indices++;
142
143 if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])==b) continue;
144
145 Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
146 Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
147 Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
148
149 // Sort the corners on y axis
150
151 if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
152 if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
153 if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
154
155 Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
156 Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
157
158 Render_Preprocessed_Triangle(xcf,yci);
159 }
160}
161
162void BWRenderClass::Render_Triangles(const unsigned long* indices,int index_count)
163{
164 index_count/=3;
165 for (int n=0;n<index_count;++n) {
166 int idx_1=*indices++;
167 int idx_2=*indices++;
168 int idx_3=*indices++;
169
170 if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])) continue;
171
172 Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
173 Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
174 Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
175
176 // Sort the corners on y axis
177
178 if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
179 if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
180 if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
181
182 Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
183 Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
184
185 Render_Preprocessed_Triangle(xcf,yci);
186 }
187}
188
189void BWRenderClass::Render_Preprocessed_Triangle(Vector3& xcf,Vector3i& yci)
190{
191 float x_left=xcf[0];
192 float x_right=x_left;
193 int ycnt=yci[1]-yci[0];
194 int y=yci[0];
195 if (ycnt) {
196 float x_step_1=(xcf[1]-xcf[0])/float(ycnt);
197 float x_step_2=(xcf[2]-xcf[0])/float(yci[2]-y);
198 if (x_step_1>x_step_2) {
199 float t=x_step_1;
200 x_step_1=x_step_2;
201 x_step_2=t;
202 }
203
204 while (ycnt>0) {
205 pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
206
207 x_left+=x_step_1;
208 x_right+=x_step_2;
209 ycnt--;
210 y++;
211 }
212 }
213 else {
214 if (xcf[0]<xcf[1]) {
215 x_left=xcf[0];
216 x_right=xcf[1];
217 }
218 else {
219 x_right=xcf[0];
220 x_left=xcf[1];
221 }
222
223 }
224
225 ycnt=yci[2]-yci[1];
226 y=yci[1];
227
228 if (ycnt) {
229 float one_per_ycnt=1.0f/float(ycnt);
230 float x_step_1=(xcf[2]-x_left)*one_per_ycnt;
231 float x_step_2=(xcf[2]-x_right)*one_per_ycnt;
232 while (ycnt>0) {
233 pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
234 x_left+=x_step_1;
235 x_right+=x_step_2;
236 ycnt--;
237 y++;
238 }
239 }
240
241}
242
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
WWINLINE void Swap(Vector2 &a, Vector2 &b)
Definition vector2.h:488
void Set_Vertex_Locations(Vector2 *vertices, int count)
Definition bwrender.cpp:104
void Render_Triangle_Strip(const unsigned long *indices, int index_count)
Definition bwrender.cpp:132
void Render_Triangles(const unsigned long *indices, int index_count)
Definition bwrender.cpp:162
BWRenderClass(unsigned char *buffer, int scale)
Definition bwrender.cpp:88
void Fill(unsigned char c)
Definition bwrender.cpp:98
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]