Skip to content

Commit 2af21ac

Browse files
authored
Merge pull request #126 from beasterio/tutorials
Tutorials
2 parents 1ec3c82 + f84bcef commit 2af21ac

24 files changed

+3480
-0
lines changed

Doc/RadeonRays.md

Lines changed: 451 additions & 0 deletions
Large diffs are not rendered by default.

Tutorials/CornellBox/CornellBox.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
project "TutorialCornellBox"
2+
kind "ConsoleApp"
3+
location "../CornellBox"
4+
links {"RadeonRays", "CLW", "Calc"}
5+
files { "../CornellBox/**.h", "../CornellBox/**.cpp", "../Tools/**.h", "../Tools/**.cpp", "../CornellBox/**.fsh" , "../CornellBox/**.vsh"}
6+
includedirs{ "../../RadeonRays/include", "../../CLW", "../Tools", "." }
7+
8+
if os.is("macosx") then
9+
sysincludedirs {"/usr/local/include"}
10+
libdirs {"/usr/local/lib"}
11+
linkoptions{ "-framework OpenGL", "-framework GLUT" }
12+
buildoptions "-std=c++11 -stdlib=libc++"
13+
links {"OpenImageIO"}
14+
end
15+
16+
if os.is("windows") then
17+
includedirs { "../../3rdparty/glew/include", "../../3rdparty/freeglut/include", "../../3rdparty/oiio/include" }
18+
links {"RadeonRays",}
19+
links {"freeglut", "glew"}
20+
libdirs { "../../3rdparty/glew/lib/%{cfg.platform}",
21+
"../../3rdparty/freeglut/lib/%{cfg.platform}",
22+
"../../3rdparty/embree/lib/%{cfg.platform}",
23+
"../../3rdparty/oiio/lib/%{cfg.platform}"}
24+
configuration {"Debug"}
25+
links {"OpenImageIOD"}
26+
configuration {"Release"}
27+
links {"OpenImageIO"}
28+
configuration {}
29+
end
30+
31+
if os.is("linux") then
32+
buildoptions "-std=c++11"
33+
links {"OpenImageIO", "pthread",}
34+
links{"glut", "GLEW", "GL",}
35+
os.execute("rm -rf obj");
36+
end
37+
38+
configuration {"x32", "Debug"}
39+
targetdir "../../Bin/Debug/x86"
40+
configuration {"x64", "Debug"}
41+
targetdir "../../Bin/Debug/x64"
42+
configuration {"x32", "Release"}
43+
targetdir "../../Bin/Release/x86"
44+
configuration {"x64", "Release"}
45+
targetdir "../../Bin/Release/x64"
46+
configuration {}
47+
48+
if os.is("windows") then
49+
postbuildcommands {
50+
'copy "..\\..\\3rdparty\\glew\\bin\\%{cfg.platform}\\glew32.dll" "%{cfg.buildtarget.directory}"',
51+
'copy "..\\..\\3rdparty\\freeglut\\bin\\%{cfg.platform}\\freeglut.dll" "%{cfg.buildtarget.directory}"',
52+
'copy "..\\..\\3rdparty\\embree\\bin\\%{cfg.platform}\\embree.dll" "%{cfg.buildtarget.directory}"',
53+
'copy "..\\..\\3rdparty\\embree\\bin\\%{cfg.platform}\\tbb.dll" "%{cfg.buildtarget.directory}"',
54+
'copy "..\\..\\3rdparty\\oiio\\bin\\%{cfg.platform}\\OpenImageIO.dll" "%{cfg.buildtarget.directory}"',
55+
'copy "..\\..\\3rdparty\\oiio\\bin\\%{cfg.platform}\\OpenImageIOD.dll" "%{cfg.buildtarget.directory}"'
56+
}
57+
end

Tutorials/CornellBox/main.cpp

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
/**********************************************************************
2+
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in
12+
all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.
21+
********************************************************************/
22+
#include "radeon_rays.h"
23+
#include <GL/glew.h>
24+
#include <GLUT/GLUT.h>
25+
#include <cassert>
26+
#include <iostream>
27+
#include <memory>
28+
#include "../tools/shader_manager.h"
29+
#include "../tools/tiny_obj_loader.h"
30+
31+
using namespace RadeonRays;
32+
using namespace tinyobj;
33+
34+
namespace {
35+
std::vector<shape_t> g_objshapes;
36+
std::vector<material_t> g_objmaterials;
37+
38+
GLuint g_vertex_buffer, g_index_buffer;
39+
GLuint g_texture;
40+
int g_window_width = 640;
41+
int g_window_height = 480;
42+
std::unique_ptr<ShaderManager> g_shader_manager;
43+
}
44+
45+
void InitData()
46+
{
47+
std::string basepath = "../../Resources/CornellBox/";
48+
std::string filename = basepath + "orig.objm";
49+
std::string res = LoadObj(g_objshapes, g_objmaterials, filename.c_str(), basepath.c_str());
50+
if (res != "")
51+
{
52+
throw std::runtime_error(res);
53+
}
54+
}
55+
56+
float3 ConvertFromBarycentric(const float* vec, const int* ind, int prim_id, const float4& uvwt)
57+
{
58+
float3 a = { vec[ind[prim_id * 3] * 3],
59+
vec[ind[prim_id * 3] * 3 + 1],
60+
vec[ind[prim_id * 3] * 3 + 2], };
61+
62+
float3 b = { vec[ind[prim_id * 3 + 1] * 3],
63+
vec[ind[prim_id * 3 + 1] * 3 + 1],
64+
vec[ind[prim_id * 3 + 1] * 3 + 2], };
65+
66+
float3 c = { vec[ind[prim_id * 3 + 2] * 3],
67+
vec[ind[prim_id * 3 + 2] * 3 + 1],
68+
vec[ind[prim_id * 3 + 2] * 3 + 2], };
69+
return a * (1 - uvwt.x - uvwt.y) + b * uvwt.x + c * uvwt.y;
70+
}
71+
72+
void InitGl()
73+
{
74+
g_shader_manager.reset(new ShaderManager());
75+
76+
glClearColor(0.0, 0.0, 0.0, 0.0);
77+
glCullFace(GL_NONE);
78+
glDisable(GL_DEPTH_TEST);
79+
glEnable(GL_TEXTURE_2D);
80+
81+
glGenBuffers(1, &g_vertex_buffer);
82+
glGenBuffers(1, &g_index_buffer);
83+
84+
// create Vertex buffer
85+
glBindBuffer(GL_ARRAY_BUFFER, g_vertex_buffer);
86+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_index_buffer);
87+
88+
float quad_vdata[] =
89+
{
90+
-1, -1, 0.5, 0, 0,
91+
1, -1, 0.5, 1, 0,
92+
1, 1, 0.5, 1, 1,
93+
-1, 1, 0.5, 0, 1
94+
};
95+
96+
GLshort quad_idata[] =
97+
{
98+
0, 1, 3,
99+
3, 1, 2
100+
};
101+
102+
// fill data
103+
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vdata), quad_vdata, GL_STATIC_DRAW);
104+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_idata), quad_idata, GL_STATIC_DRAW);
105+
glBindBuffer(GL_ARRAY_BUFFER, 0);
106+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
107+
108+
// texture
109+
glGenTextures(1, &g_texture);
110+
glBindTexture(GL_TEXTURE_2D, g_texture);
111+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
112+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
113+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_window_width, g_window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
114+
glBindTexture(GL_TEXTURE_2D, 0);
115+
}
116+
117+
void DrawScene()
118+
{
119+
glDisable(GL_DEPTH_TEST);
120+
glViewport(0, 0, g_window_width, g_window_height);
121+
122+
glClear(GL_COLOR_BUFFER_BIT);
123+
124+
glBindBuffer(GL_ARRAY_BUFFER, g_vertex_buffer);
125+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_index_buffer);
126+
127+
// shader data
128+
GLuint program = g_shader_manager->GetProgram("simple");
129+
glUseProgram(program);
130+
GLuint texloc = glGetUniformLocation(program, "g_Texture");
131+
assert(texloc >= 0);
132+
133+
glUniform1i(texloc, 0);
134+
135+
glActiveTexture(GL_TEXTURE0);
136+
glBindTexture(GL_TEXTURE_2D, g_texture);
137+
138+
GLuint position_attr = glGetAttribLocation(program, "inPosition");
139+
GLuint texcoord_attr = glGetAttribLocation(program, "inTexcoord");
140+
glVertexAttribPointer(position_attr, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
141+
glVertexAttribPointer(texcoord_attr, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3));
142+
glEnableVertexAttribArray(position_attr);
143+
glEnableVertexAttribArray(texcoord_attr);
144+
145+
// draw rectanle
146+
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
147+
148+
glDisableVertexAttribArray(texcoord_attr);
149+
glBindTexture(GL_TEXTURE_2D, 0);
150+
glBindBuffer(GL_ARRAY_BUFFER, 0);
151+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
152+
glUseProgram(0);
153+
154+
glFinish();
155+
glutSwapBuffers();
156+
}
157+
158+
int main(int argc, char* argv[])
159+
{
160+
// GLUT Window Initialization:
161+
glutInit(&argc, (char**)argv);
162+
glutInitWindowSize(640, 480);
163+
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
164+
glutCreateWindow("Triangle");
165+
#ifndef __APPLE__
166+
GLenum err = glewInit();
167+
if (err != GLEW_OK)
168+
{
169+
std::cout << "GLEW initialization failed\n";
170+
return -1;
171+
}
172+
#endif
173+
// Prepare rectangle for drawing texture
174+
// rendered using intersection results
175+
InitGl();
176+
177+
// Load CornellBox model
178+
InitData();
179+
180+
// Choose device
181+
int nativeidx = -1;
182+
// Always use OpenCL
183+
IntersectionApi::SetPlatform(DeviceInfo::kOpenCL);
184+
for (auto idx = 0U; idx < IntersectionApi::GetDeviceCount(); ++idx)
185+
{
186+
DeviceInfo devinfo;
187+
IntersectionApi::GetDeviceInfo(idx, devinfo);
188+
189+
if (devinfo.type == DeviceInfo::kGpu && nativeidx == -1)
190+
{
191+
nativeidx = idx;
192+
}
193+
}
194+
assert(nativeidx != -1);
195+
IntersectionApi* api = IntersectionApi::Create(nativeidx);
196+
197+
// Adding meshes to tracing scene
198+
for (int id = 0; id < g_objshapes.size(); ++id)
199+
{
200+
shape_t& objshape = g_objshapes[id];
201+
float* vertdata = objshape.mesh.positions.data();
202+
int nvert = objshape.mesh.positions.size();
203+
int* indices = objshape.mesh.indices.data();
204+
int nfaces = objshape.mesh.indices.size() / 3;
205+
Shape* shape = api->CreateMesh(vertdata, nvert, 3 * sizeof(float), indices, 0, nullptr, nfaces);
206+
207+
assert(shape != nullptr);
208+
api->AttachShape(shape);
209+
shape->SetId(id);
210+
}
211+
// Ñommit scene changes
212+
api->Commit();
213+
214+
const int k_raypack_size = g_window_height * g_window_width;
215+
216+
// Prepare rays. One for each texture pixel.
217+
std::vector<ray> rays(k_raypack_size);
218+
float4 camera_pos = { 0.f, 1.f, 3.f, 1000.f };
219+
for (int i = 0; i < g_window_height; ++i)
220+
for (int j = 0; j < g_window_width; ++j)
221+
{
222+
const float xstep = 2.f / (float)g_window_width;
223+
const float ystep = 2.f / (float)g_window_height;
224+
float x = -1.f + xstep * (float)j;
225+
float y = ystep * (float)i;
226+
float z = 1.f;
227+
// Perspective view
228+
rays[i * g_window_width + j].o = camera_pos;
229+
rays[i * g_window_width + j].d = float3(x - camera_pos.x, y - camera_pos.y, z - camera_pos.z);
230+
}
231+
Buffer* ray_buffer = api->CreateBuffer(rays.size() * sizeof(ray), rays.data());
232+
233+
// Intersection data
234+
std::vector<Intersection> isect(k_raypack_size);
235+
Buffer* isect_buffer = api->CreateBuffer(isect.size() * sizeof(Intersection), nullptr);
236+
237+
// Intersection
238+
api->QueryIntersection(ray_buffer, k_raypack_size, isect_buffer, nullptr, nullptr);
239+
240+
// Get results
241+
Event* e = nullptr;
242+
Intersection* tmp = nullptr;
243+
api->MapBuffer(isect_buffer, kMapRead, 0, isect.size() * sizeof(Intersection), (void**)&tmp, &e);
244+
// RadeonRays calls are asynchronous, so need to wait for calculation to complete.
245+
e->Wait();
246+
api->DeleteEvent(e);
247+
e = nullptr;
248+
249+
// Copy results
250+
for (int i = 0; i < k_raypack_size; ++i)
251+
{
252+
isect[i] = tmp[i];
253+
}
254+
255+
// Point light position
256+
float3 light = { -0.01f, 1.9f, 0.1f };
257+
258+
// Draw
259+
std::vector<unsigned char> tex_data(k_raypack_size * 4);
260+
for (int i = 0; i < k_raypack_size ; ++i)
261+
{
262+
int shape_id = isect[i].shapeid;
263+
int prim_id = isect[i].primid;
264+
265+
if (shape_id != kNullId && prim_id != kNullId)
266+
{
267+
mesh_t& mesh = g_objshapes[shape_id].mesh;
268+
int mat_id = mesh.material_ids[prim_id];
269+
material_t& mat = g_objmaterials[mat_id];
270+
271+
float3 diff_col = { mat.diffuse[0],
272+
mat.diffuse[1],
273+
mat.diffuse[2] };
274+
275+
// Calculate position and normal of the intersection point
276+
float3 pos = ConvertFromBarycentric(mesh.positions.data(), mesh.indices.data(), prim_id, isect[i].uvwt);
277+
float3 norm = ConvertFromBarycentric(mesh.normals.data(), mesh.indices.data(), prim_id, isect[i].uvwt);
278+
norm.normalize();
279+
280+
// Calculate lighting
281+
float3 col = { 0.f, 0.f, 0.f };
282+
float3 light_dir = light - pos;
283+
light_dir.normalize();
284+
float dot_prod = dot(norm, light_dir);
285+
if (dot_prod > 0)
286+
col += dot_prod * diff_col;
287+
288+
tex_data[i * 4] = col[0] * 255;
289+
tex_data[i * 4 + 1] = col[1] * 255;
290+
tex_data[i * 4 + 2] = col[2] * 255;
291+
tex_data[i * 4 + 3] = 255;
292+
}
293+
}
294+
295+
// Update texture data
296+
glBindTexture(GL_TEXTURE_2D, g_texture);
297+
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_window_width, g_window_height, GL_RGBA, GL_UNSIGNED_BYTE, tex_data.data());
298+
glBindTexture(GL_TEXTURE_2D, NULL);
299+
300+
// Start the main loop
301+
glutDisplayFunc(DrawScene);
302+
glutMainLoop();
303+
304+
// Cleanup
305+
IntersectionApi::Delete(api);
306+
307+
return 0;
308+
}

0 commit comments

Comments
 (0)