1
+ #include " radeon_rays.h"
2
+ #include < GL/glew.h>
3
+ #include < GLUT/GLUT.h>
4
+ #include < cassert>
5
+ #include < iostream>
6
+ #include < memory>
7
+ #include " ../tools/shader_manager.h"
8
+ #include " ../tools/tiny_obj_loader.h"
9
+
10
+ using namespace RadeonRays ;
11
+ using namespace tinyobj ;
12
+
13
+ namespace {
14
+ std::vector<shape_t > g_objshapes;
15
+ std::vector<material_t > g_objmaterials;
16
+
17
+ GLuint g_vertex_buffer, g_index_buffer;
18
+ GLuint g_texture;
19
+ int g_window_width = 640 ;
20
+ int g_window_height = 480 ;
21
+ std::unique_ptr<ShaderManager> g_shader_manager;
22
+ }
23
+
24
+ void CheckGlErr ()
25
+ {
26
+ auto err = glGetError ();
27
+ while (err != GL_NO_ERROR)
28
+ {
29
+ std::cout << " err " << err << std::endl;
30
+ err = glGetError ();
31
+ }
32
+ }
33
+
34
+ void InitData ()
35
+ {
36
+ std::string basepath = " ../../Resources/CornellBox/" ;
37
+ std::string filename = basepath + " orig.objm" ;
38
+ std::string res = LoadObj (g_objshapes, g_objmaterials, filename.c_str (), basepath.c_str ());
39
+ if (res != " " )
40
+ {
41
+ throw std::runtime_error (res);
42
+ }
43
+
44
+ }
45
+
46
+ float3 ConvertFromBarycentric (const float * vec, const int * ind, int prim_id, const float4& uvwt)
47
+ {
48
+ float3 a = { vec[ind[prim_id * 3 ] * 3 ],
49
+ vec[ind[prim_id * 3 ] * 3 + 1 ],
50
+ vec[ind[prim_id * 3 ] * 3 + 2 ], };
51
+
52
+ float3 b = { vec[ind[prim_id * 3 + 1 ] * 3 ],
53
+ vec[ind[prim_id * 3 + 1 ] * 3 + 1 ],
54
+ vec[ind[prim_id * 3 + 1 ] * 3 + 2 ], };
55
+
56
+ float3 c = { vec[ind[prim_id * 3 + 2 ] * 3 ],
57
+ vec[ind[prim_id * 3 + 2 ] * 3 + 1 ],
58
+ vec[ind[prim_id * 3 + 2 ] * 3 + 2 ], };
59
+ return a * (1 - uvwt.x - uvwt.y ) + b * uvwt.x + c * uvwt.y ;
60
+ }
61
+
62
+ void InitGl ()
63
+ {
64
+ g_shader_manager.reset (new ShaderManager ());
65
+
66
+ glClearColor (0.0 , 0.0 , 0.0 , 0.0 );
67
+ glCullFace (GL_NONE);
68
+ glDisable (GL_DEPTH_TEST);
69
+ glEnable (GL_TEXTURE_2D);
70
+
71
+ glGenBuffers (1 , &g_vertex_buffer);
72
+ glGenBuffers (1 , &g_index_buffer);
73
+
74
+ // create Vertex buffer
75
+ glBindBuffer (GL_ARRAY_BUFFER, g_vertex_buffer);
76
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, g_index_buffer);
77
+
78
+ float quad_vdata[] =
79
+ {
80
+ -1 , -1 , 0.5 , 0 , 0 ,
81
+ 1 , -1 , 0.5 , 1 , 0 ,
82
+ 1 , 1 , 0.5 , 1 , 1 ,
83
+ -1 , 1 , 0.5 , 0 , 1
84
+ };
85
+
86
+ GLshort quad_idata[] =
87
+ {
88
+ 0 , 1 , 3 ,
89
+ 3 , 1 , 2
90
+ };
91
+
92
+ // fill data
93
+ glBufferData (GL_ARRAY_BUFFER, sizeof (quad_vdata), quad_vdata, GL_STATIC_DRAW);
94
+ glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (quad_idata), quad_idata, GL_STATIC_DRAW);
95
+
96
+ glBindBuffer (GL_ARRAY_BUFFER, 0 );
97
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0 );
98
+
99
+
100
+ glGenTextures (1 , &g_texture);
101
+ glBindTexture (GL_TEXTURE_2D, g_texture);
102
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
103
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
104
+
105
+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, g_window_width, g_window_height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
106
+
107
+ glBindTexture (GL_TEXTURE_2D, 0 );
108
+ }
109
+
110
+ void DrawScene ()
111
+ {
112
+
113
+ glDisable (GL_DEPTH_TEST);
114
+ glViewport (0 , 0 , g_window_width, g_window_height);
115
+
116
+ glClear (GL_COLOR_BUFFER_BIT);
117
+
118
+ glBindBuffer (GL_ARRAY_BUFFER, g_vertex_buffer);
119
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, g_index_buffer);
120
+
121
+ GLuint program = g_shader_manager->GetProgram (" simple" );
122
+ glUseProgram (program);
123
+
124
+ GLuint texloc = glGetUniformLocation (program, " g_Texture" );
125
+ assert (texloc >= 0 );
126
+
127
+ glUniform1i (texloc, 0 );
128
+
129
+ glActiveTexture (GL_TEXTURE0);
130
+ glBindTexture (GL_TEXTURE_2D, g_texture);
131
+
132
+ GLuint position_attr = glGetAttribLocation (program, " inPosition" );
133
+ GLuint texcoord_attr = glGetAttribLocation (program, " inTexcoord" );
134
+
135
+ glVertexAttribPointer (position_attr, 3 , GL_FLOAT, GL_FALSE, sizeof (float ) * 5 , 0 );
136
+ glVertexAttribPointer (texcoord_attr, 2 , GL_FLOAT, GL_FALSE, sizeof (float ) * 5 , (void *)(sizeof (float ) * 3 ));
137
+
138
+ glEnableVertexAttribArray (position_attr);
139
+ glEnableVertexAttribArray (texcoord_attr);
140
+
141
+ glDrawElements (GL_TRIANGLES, 6 , GL_UNSIGNED_SHORT, nullptr );
142
+
143
+ glDisableVertexAttribArray (texcoord_attr);
144
+ glBindTexture (GL_TEXTURE_2D, 0 );
145
+ glBindBuffer (GL_ARRAY_BUFFER, 0 );
146
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0 );
147
+ glUseProgram (0 );
148
+
149
+ glFinish ();
150
+
151
+
152
+ glutSwapBuffers ();
153
+ }
154
+
155
+ int main (int argc, char * argv[])
156
+ {
157
+ // GLUT Window Initialization:
158
+ glutInit (&argc, (char **)argv);
159
+ glutInitWindowSize (640 , 480 );
160
+ glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
161
+ glutCreateWindow (" Triangle" );
162
+ #ifndef __APPLE__
163
+ GLenum err = glewInit ();
164
+ if (err != GLEW_OK)
165
+ {
166
+ std::cout << " GLEW initialization failed\n " ;
167
+ return -1 ;
168
+ }
169
+ #endif
170
+
171
+ InitGl ();
172
+ InitData ();
173
+
174
+ int nativeidx = -1 ;
175
+
176
+ // Always use OpenCL
177
+ IntersectionApi::SetPlatform (DeviceInfo::kOpenCL );
178
+
179
+ for (auto idx = 0U ; idx < IntersectionApi::GetDeviceCount (); ++idx)
180
+ {
181
+ DeviceInfo devinfo;
182
+ IntersectionApi::GetDeviceInfo (idx, devinfo);
183
+
184
+ if (devinfo.type == DeviceInfo::kGpu && nativeidx == -1 )
185
+ {
186
+ nativeidx = idx;
187
+ }
188
+ }
189
+
190
+ assert (nativeidx != -1 );
191
+ IntersectionApi* api = IntersectionApi::Create (nativeidx);
192
+
193
+ // Shapes
194
+ float3 light = {-0 .01f , 1 .9f , 0 .1f };
195
+ for (int id = 0 ; id < g_objshapes.size (); ++id)
196
+ {
197
+ shape_t & objshape = g_objshapes[id];
198
+ float * vertdata = objshape.mesh .positions .data ();
199
+ int nvert = objshape.mesh .positions .size ();
200
+ int * indices = objshape.mesh .indices .data ();
201
+ int nfaces = objshape.mesh .indices .size () / 3 ;
202
+ Shape* shape = api->CreateMesh (vertdata, nvert, 3 * sizeof (float ), indices, 0 , nullptr , nfaces);
203
+
204
+ assert (shape != nullptr );
205
+ api->AttachShape (shape);
206
+ shape->SetId (id);
207
+ }
208
+
209
+ const int k_raypack_size = g_window_height * g_window_width;
210
+ // Rays
211
+ std::vector<ray> rays (k_raypack_size);
212
+
213
+ // Prepare the ray
214
+ float4 camera_pos = { 0 .f , 1 .f , 3 .f , 1000 .f };
215
+ for (int i = 0 ; i < g_window_height; ++i)
216
+ for (int j = 0 ; j < g_window_width; ++j)
217
+ {
218
+ const float xstep = 2 .f / (float )g_window_width;
219
+ const float ystep = 2 .f / (float )g_window_height;
220
+ float x = -1 .f + xstep * (float )j;
221
+ float y = ystep * (float )i;
222
+ float z = 1 .f ;
223
+ rays[i * g_window_width + j].o = camera_pos;
224
+ rays[i * g_window_width + j].d = float3 (x - camera_pos.x , y - camera_pos.y , z - camera_pos.z );
225
+ }
226
+
227
+ // Intersection and hit data
228
+ std::vector<Intersection> isect (k_raypack_size);
229
+
230
+ Buffer* ray_buffer = api->CreateBuffer (rays.size () * sizeof (ray), rays.data ());
231
+ Buffer* isect_buffer = api->CreateBuffer (isect.size () * sizeof (Intersection), nullptr );
232
+
233
+ api->Commit ();
234
+ api->QueryIntersection (ray_buffer, k_raypack_size, isect_buffer, nullptr , nullptr );
235
+ Event* e = nullptr ;
236
+ Intersection* tmp = nullptr ;
237
+ api->MapBuffer (isect_buffer, kMapRead , 0 , isect.size () * sizeof (Intersection), (void **)&tmp, &e);
238
+ e->Wait ();
239
+ api->DeleteEvent (e);
240
+ e = nullptr ;
241
+
242
+ for (int i = 0 ; i < k_raypack_size; ++i)
243
+ {
244
+ isect[i] = tmp[i];
245
+ }
246
+
247
+ std::vector<unsigned char > tex_data (k_raypack_size * 4 );
248
+ for (int i = 0 ; i < k_raypack_size ; ++i)
249
+ {
250
+ int shape_id = isect[i].shapeid ;
251
+ int prim_id = isect[i].primid ;
252
+
253
+ if (shape_id != kNullId && prim_id != kNullId )
254
+ {
255
+ mesh_t & mesh = g_objshapes[shape_id].mesh ;
256
+ int mat_id = mesh.material_ids [prim_id];
257
+ material_t & mat = g_objmaterials[mat_id];
258
+
259
+ float3 diff_col = { mat.diffuse [0 ],
260
+ mat.diffuse [1 ],
261
+ mat.diffuse [2 ] };
262
+
263
+ float3 pos = ConvertFromBarycentric (mesh.positions .data (), mesh.indices .data (), prim_id, isect[i].uvwt );
264
+ float3 norm = ConvertFromBarycentric (mesh.normals .data (), mesh.indices .data (), prim_id, isect[i].uvwt );
265
+ norm.normalize ();
266
+ float3 col = { 0 .f , 0 .f , 0 .f };
267
+ float3 light_dir = light - pos;
268
+ light_dir.normalize ();
269
+ float dot_prod = dot (norm, light_dir);
270
+
271
+ if (dot_prod > 0 )
272
+ col += dot_prod * diff_col;
273
+
274
+ tex_data[i * 4 ] = col[0 ] * 255 ;
275
+ tex_data[i * 4 + 1 ] = col[1 ] * 255 ;
276
+ tex_data[i * 4 + 2 ] = col[2 ] * 255 ;
277
+ tex_data[i * 4 + 3 ] = 255 ;
278
+ }
279
+ }
280
+ glBindTexture (GL_TEXTURE_2D, g_texture);
281
+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , g_window_width, g_window_height, GL_RGBA, GL_UNSIGNED_BYTE, tex_data.data ());
282
+ glBindTexture (GL_TEXTURE_2D, NULL );
283
+
284
+ glutDisplayFunc (DrawScene);
285
+ glutMainLoop (); // Start the main loop
286
+ IntersectionApi::Delete (api);
287
+
288
+ return 0 ;
289
+ }
0 commit comments