Skip to content

Commit 4d8ccf5

Browse files
committed
Demo - add primvar
1 parent c6424e2 commit 4d8ccf5

File tree

5 files changed

+314
-0
lines changed

5 files changed

+314
-0
lines changed

tutorials/37_primvar/main.cpp

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/*****************************************************************************\
2+
*
3+
* Module Name Primvar Demo
4+
* Project Radeon ProRender rendering tutorial
5+
*
6+
* Description Radeon ProRender SDK tutorials
7+
*
8+
* Copyright(C) 2011-2022 Advanced Micro Devices, Inc. All rights reserved.
9+
*
10+
\*****************************************************************************/
11+
12+
#include "RadeonProRender.h"
13+
#include "Math/mathutils.h"
14+
#include "../common/common.h"
15+
#include <cassert>
16+
#include <iostream>
17+
18+
//
19+
// Demo of the Primvar. With this feature you can assign additional sets of parameters to rpr_shape.
20+
// Those parameters can be for example: a scalar, 2-float UVs, 3-floats colors.
21+
// They can be uniform to the whole shape, per vertice or per face.
22+
//
23+
24+
// garbage collector of this demo
25+
RPRGarbageCollector g_gc;
26+
27+
int main()
28+
{
29+
// for Debugging you can enable Radeon ProRender API trace
30+
// set this before any RPR API calls
31+
// rprContextSetParameterByKey1u(0,RPR_CONTEXT_TRACING_ENABLED,1);
32+
33+
// the RPR context object.
34+
rpr_context context = nullptr;
35+
36+
// Register the RPR DLL
37+
rpr_int tahoePluginID = rprRegisterPlugin(RPR_PLUGIN_FILE_NAME);
38+
CHECK_NE(tahoePluginID , -1);
39+
rpr_int plugins[] = { tahoePluginID };
40+
size_t pluginCount = sizeof(plugins) / sizeof(plugins[0]);
41+
42+
// Create context
43+
CHECK( rprCreateContext(RPR_API_VERSION, plugins, pluginCount, g_ContextCreationFlags, NULL, NULL, &context) );
44+
45+
// Set the active plugin.
46+
CHECK( rprContextSetActivePlugin(context, plugins[0]) );
47+
48+
std::cout << "RPR Context creation succeeded." << std::endl;
49+
50+
// Create the scene.
51+
rpr_scene scene = nullptr;
52+
CHECK( rprContextCreateScene(context, &scene) );
53+
CHECK( rprContextSetScene(context, scene) );
54+
55+
// Create the camera
56+
rpr_camera camera = nullptr;
57+
CHECK( rprContextCreateCamera(context, &camera) );
58+
CHECK( rprCameraLookAt(camera, 0, 10, 12, 0, -2, 0, 0, 1, 0) );
59+
CHECK( rprSceneSetCamera(scene, camera) );
60+
61+
62+
// Create an environment light
63+
// For this demo we are going to use a simple 1x1 pixel white env light.
64+
// the image will be created with rprContextCreateImage ( instead of creating it from an image file )
65+
{
66+
rpr_light lightEnv = nullptr;
67+
CHECK( rprContextCreateEnvironmentLight(context, &lightEnv));
68+
g_gc.GCAdd(lightEnv);
69+
70+
rpr_image_format imageFormat;
71+
memset(&imageFormat,0,sizeof(imageFormat));
72+
imageFormat.num_components = 4;
73+
imageFormat.type = RPR_COMPONENT_TYPE_FLOAT32;
74+
75+
rpr_image_desc imageDesc;
76+
memset(&imageDesc,0,sizeof(imageDesc));
77+
imageDesc.image_depth = 1;
78+
imageDesc.image_width = 1;
79+
imageDesc.image_height = 1;
80+
imageDesc.image_row_pitch = imageDesc.image_width * sizeof(unsigned char)*4;
81+
imageDesc.image_slice_pitch = imageDesc.image_width * imageDesc.image_height * sizeof(unsigned char)*4;
82+
83+
// white pixel
84+
float dataImage[4];
85+
dataImage[0] = 1.0;
86+
dataImage[1] = 1.0;
87+
dataImage[2] = 1.0;
88+
dataImage[3] = 1.0;
89+
90+
rpr_image imgEnvLight = nullptr;
91+
CHECK( rprContextCreateImage(context, imageFormat, &imageDesc, dataImage, &imgEnvLight));
92+
g_gc.GCAdd(imgEnvLight);
93+
94+
CHECK( rprEnvironmentLightSetImage(lightEnv, imgEnvLight));
95+
CHECK( rprEnvironmentLightSetIntensityScale(lightEnv, 1.0f));
96+
CHECK( rprSceneAttachLight(scene, lightEnv));
97+
}
98+
99+
100+
// create the material system
101+
rpr_material_system matsys = nullptr;
102+
CHECK( rprContextCreateMaterialSystem(context, 0, &matsys) );
103+
104+
105+
// create the shape plane.
106+
// this shape will be a grid so that we can assign primvar set on different vertices/faces.
107+
rpr_shape plane = NULL;
108+
{
109+
110+
const int gridSize = 4; // create a 3x3 grid (4*4 vertices)
111+
vertex plane_data[gridSize*gridSize];
112+
113+
// grid dimensions
114+
const float minGrid = -5.0f;
115+
const float maxGrid = +5.0f;
116+
117+
// create grid
118+
for(int y=0; y<gridSize; y++)
119+
{
120+
for(int x=0; x<gridSize; x++)
121+
{
122+
plane_data[y*gridSize+x].pos[0] = minGrid + (maxGrid-minGrid) / ((float)gridSize-1.0f) * ((float)x);
123+
plane_data[y*gridSize+x].pos[1] = 0.0f;
124+
plane_data[y*gridSize+x].pos[2] = minGrid + (maxGrid-minGrid) / ((float)gridSize-1.0f) * ((float)y);
125+
126+
plane_data[y*gridSize+x].norm[0] = 0.0f;
127+
plane_data[y*gridSize+x].norm[1] = 1.0f;
128+
plane_data[y*gridSize+x].norm[2] = 0.0f;
129+
130+
plane_data[y*gridSize+x].tex[0] = (plane_data[y*gridSize+x].pos[0] - minGrid) / (maxGrid - minGrid);
131+
plane_data[y*gridSize+x].tex[1] = 1.0f - (plane_data[y*gridSize+x].pos[2] - minGrid) / (maxGrid - minGrid);
132+
}
133+
}
134+
135+
// create indices of the grid
136+
rpr_int indices[(gridSize-1)*(gridSize-1)*4];
137+
for(int y=0; y<gridSize-1; y++)
138+
{
139+
for(int x=0; x<gridSize-1; x++)
140+
{
141+
indices[ (x+y*(gridSize-1))*4 + 0 ] = y*gridSize+x ;
142+
indices[ (x+y*(gridSize-1))*4 + 1 ] = y*gridSize+(x+1) ;
143+
indices[ (x+y*(gridSize-1))*4 + 3 ] = (y+1)*gridSize+x ;
144+
indices[ (x+y*(gridSize-1))*4 + 2 ] = (y+1)*gridSize+(x+1) ;
145+
}
146+
}
147+
148+
// create face list
149+
rpr_int num_face_vertices[(gridSize-1)*(gridSize-1)];
150+
for(int y=0; y<gridSize-1; y++)
151+
{
152+
for(int x=0; x<gridSize-1; x++)
153+
{
154+
num_face_vertices[ (x+y*(gridSize-1)) ] = 4; // use quad face: 4 vertices per face.
155+
}
156+
}
157+
158+
CHECK( rprContextCreateMesh(context,
159+
(rpr_float const*)&plane_data[0], gridSize*gridSize, sizeof(vertex),
160+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float)*3), gridSize*gridSize, sizeof(vertex),
161+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float)*6), gridSize*gridSize, sizeof(vertex),
162+
(rpr_int const*)indices, sizeof(rpr_int),
163+
(rpr_int const*)indices, sizeof(rpr_int),
164+
(rpr_int const*)indices, sizeof(rpr_int),
165+
num_face_vertices, (gridSize-1)*(gridSize-1), &plane) );
166+
g_gc.GCAdd(plane);
167+
168+
// attach the plane to the scene.
169+
CHECK( rprSceneAttachShape(scene, plane));
170+
171+
}
172+
173+
// Create framebuffer
174+
rpr_framebuffer_desc desc = { 800 , 600 };
175+
rpr_framebuffer_format fmt = {4, RPR_COMPONENT_TYPE_FLOAT32};
176+
rpr_framebuffer frame_buffer = nullptr;
177+
rpr_framebuffer frame_buffer_resolved = nullptr;
178+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer) );
179+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer_resolved) );
180+
CHECK( rprContextSetAOV(context, RPR_AOV_COLOR, frame_buffer) );
181+
182+
183+
//
184+
// Primvar demo of a set defining 1-float per vertex.
185+
//
186+
187+
float fl1[] = {
188+
1.0, 0.2, 0.3, 0.8,
189+
0.8, 0.2, 0.2 , 0.7,
190+
0.2, 0.2, 0.1, 0.6,
191+
0.0, 0.0, 0.0 , 0.0,
192+
};
193+
194+
// We bind this primvar to key=100
195+
CHECK( rprShapeSetPrimvar(plane, 100, fl1, sizeof(fl1)/sizeof(float), 1, RPR_PRIMVAR_INTERPOLATION_VERTEX ));
196+
197+
rpr_material_node matPrimvar = NULL;
198+
CHECK( rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_PRIMVAR_LOOKUP, &matPrimvar));
199+
CHECK( rprMaterialNodeSetInputUByKey(matPrimvar, RPR_MATERIAL_INPUT_VALUE, 100)); // <- specify the primvar key here.
200+
g_gc.GCAdd(matPrimvar);
201+
202+
rpr_material_node matDiffuse0 = NULL;
203+
CHECK( rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &matDiffuse0));
204+
CHECK( rprMaterialNodeSetInputNByKey(matDiffuse0, RPR_MATERIAL_INPUT_COLOR, matPrimvar));
205+
CHECK( rprShapeSetMaterial(plane, matDiffuse0));
206+
g_gc.GCAdd(matDiffuse0);
207+
208+
// set rendering gamma
209+
CHECK( rprContextSetParameterByKey1f(context, RPR_CONTEXT_DISPLAY_GAMMA , 2.2f ) );
210+
211+
// Render the scene
212+
CHECK( rprContextSetParameterByKey1u(context,RPR_CONTEXT_ITERATIONS, 100));
213+
CHECK( rprContextRender(context) );
214+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
215+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"37_1.png"));
216+
217+
218+
//
219+
// Primvar demo of a set defining 3-float (color) per vertex.
220+
//
221+
222+
float fl2[] = {
223+
1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0,
224+
1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0,
225+
1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0,
226+
1.0,1.0,0.0, 1.0,1.0,0.0, 1.0,1.0,1.0, 1.0,1.0,1.0,
227+
};
228+
// assign this set to another key : 101
229+
CHECK( rprShapeSetPrimvar(plane, 101, fl2, sizeof(fl2)/sizeof(float), 3, RPR_PRIMVAR_INTERPOLATION_VERTEX ));
230+
231+
// as we are currently rendering 'matPrimvar', we need to update the key
232+
CHECK( rprMaterialNodeSetInputUByKey(matPrimvar, RPR_MATERIAL_INPUT_VALUE, 101));
233+
234+
// Render the scene
235+
CHECK( rprFrameBufferClear(frame_buffer) ); // clear the framebuffer before starting a new rendering
236+
CHECK( rprContextRender(context) );
237+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
238+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"37_2.png"));
239+
240+
//
241+
// Primvar demo of uniform 3-float value
242+
//
243+
244+
float fl3[] = { 0.5,0.2,1.0, };
245+
CHECK( rprShapeSetPrimvar(plane, 101, fl3, sizeof(fl3)/sizeof(float), 3, RPR_PRIMVAR_INTERPOLATION_CONSTANT ));
246+
247+
// Render the scene
248+
CHECK( rprFrameBufferClear(frame_buffer) ); // clear the framebuffer before starting a new rendering
249+
CHECK( rprContextRender(context) );
250+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
251+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"37_3.png"));
252+
253+
//
254+
// Primvar demo of a set defining 3-float (color) per face.
255+
//
256+
257+
float fl4[] = {
258+
0.0,0.0,1.0, 0.0,1.0,0.0, 1.0,0.0,0.0,
259+
1.0,1.0,0.0, 0.0,1.0,1.0, 1.0,0.0,1.0,
260+
1.0,1.0,1.0, 0.0,0.0,0.0, 0.0,1.0,1.0,
261+
};
262+
CHECK( rprShapeSetPrimvar(plane, 101, fl4, sizeof(fl4)/sizeof(float), 3, RPR_PRIMVAR_INTERPOLATION_UNIFORM ));
263+
264+
// Render the scene
265+
CHECK( rprFrameBufferClear(frame_buffer) ); // clear the framebuffer before starting a new rendering
266+
CHECK( rprContextRender(context) );
267+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
268+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"37_4.png"));
269+
270+
271+
// Release the stuff we created
272+
CHECK( rprObjectDelete(camera)); camera=nullptr;
273+
CHECK( rprObjectDelete(frame_buffer)); frame_buffer=nullptr;
274+
CHECK( rprObjectDelete(frame_buffer_resolved)); frame_buffer_resolved=nullptr;
275+
g_gc.GCClean();
276+
CHECK( rprObjectDelete(scene)); scene=nullptr;
277+
CHECK( rprObjectDelete(matsys)); matsys=nullptr;
278+
CheckNoLeak(context);
279+
CHECK( rprObjectDelete(context)); context=nullptr;
280+
return 0;
281+
}
282+
283+
284+
285+

tutorials/37_primvar/premake4.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
project "37_primvar"
2+
kind "ConsoleApp"
3+
location "../build"
4+
files { "../37_primvar/**.h", "../37_primvar/**.cpp"}
5+
files { "../common/common.cpp","../common/common.h"}
6+
7+
-- remove filters for Visual Studio
8+
vpaths { [""] = { "../37_primvar/**.h", "../37_primvar/**.cpp","../common/common.cpp","../common/common.h"} }
9+
10+
11+
includedirs{ "../../RadeonProRender/inc" }
12+
13+
buildoptions "-std=c++14"
14+
15+
configuration {"x64"}
16+
links {"RadeonProRender64"}
17+
18+
if os.istarget("linux") then
19+
links {"pthread"}
20+
end
21+
22+
configuration {"x64", "Debug"}
23+
targetdir "../Bin"
24+
configuration {"x64", "Release"}
25+
targetdir "../Bin"
26+
configuration {}
27+

tutorials/37_primvar/screenshot.png

7.2 KB
Loading

tutorials/premake5.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ solution "Tutorials"
100100
include "34_material_per_face"
101101
include "35_advanced_texturing"
102102
include "36_shadow_catcher"
103+
include "37_primvar"
103104
include "50_curve"
104105
include "51_volume"
105106
include "60_mesh_export"

tutorials/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ List of tutorials in this SDK
2727
| [Material Per Face](34_material_per_face) | ![](34_material_per_face/screenshot.png) | Demo of the rprShapeSetMaterialFaces API. This allows to set materials for specific faces of the shape. |
2828
| [Advanced Texturing](35_advanced_texturing) | ![](35_advanced_texturing/screenshot.png) | This demo shows different features related to texture manipulation: Manage the UV, create procedural textures, use arthmetics and custom materials, texture wrapping. |
2929
| [Shadow Catcher](36_shadow_catcher) | ![](36_shadow_catcher/screenshot.png) | Demo of the Shadow Catcher. If a shape has this feature activated, it will "catch" the shadow. This shadow quantity can be rendered on a dedicated AOV. |
30+
| [Primvar](37_primvar) | ![](37_primvar/screenshot.png) | Demo of the Primvar. With this feature you can assign additional sets of parameters to rpr_shape. Those parameters can be for example: a scalar, 2-float UVs, 3-floats colors. They can be uniform to the whole shape, per vertice or per face. |
3031
| [Curves](50_curve) | ![](50_curve/screenshot.png) | Demo covering Curves rendering. Curves are often used for hair rendering. |
3132
| [Volume](51_volume) | ![](51_volume/screenshot.png) | This demo demonstrates Volumes with RPR |
3233
| [RPR Scene Export](60_mesh_export) | ![](60_mesh_export/screenshot.png) | Shows how to export an RPR scene as RPRS files ( native RPR file format ) or GLTF ( Khronos Group ). |

0 commit comments

Comments
 (0)