1
1
/* ****************************************************************************\
2
2
*
3
- * Module Name simple_render .cpp
3
+ * Module Name gl_interop .cpp
4
4
* Project Radeon ProRender SDK rendering tutorial
5
5
*
6
6
* Description Radeon ProRender SDK tutorials
7
+ * Demo of an OpenGL window rendering RPR.
7
8
*
8
9
* Copyright 2011 - 2020 Advanced Micro Devices, Inc.
9
10
*
38
39
39
40
#include < cassert>
40
41
#include < iostream>
42
+ #include < thread>
41
43
42
44
#define WINDOW_WIDTH 800
43
45
#define WINDOW_HEIGHT 600
44
46
47
+
48
+ class GuiRenderImpl
49
+ {
50
+ public:
51
+ struct Update
52
+ {
53
+ Update ()
54
+ {
55
+ clear ();
56
+ m_progress = 0 .0f ;
57
+ }
58
+
59
+ volatile int m_hasUpdate;
60
+ volatile int m_done;
61
+ volatile int m_aborted;
62
+ int m_camUpdated;
63
+ float m_progress;
64
+
65
+ void clear ()
66
+ {
67
+ m_hasUpdate = m_done = m_aborted = m_camUpdated = 0 ;
68
+ }
69
+ };
70
+ static
71
+ void notifyUpdate ( float x, void * userData )
72
+ {
73
+ Update* demo = (Update*)userData;
74
+ demo->m_hasUpdate = 1 ;
75
+ demo->m_progress = x;
76
+ }
77
+ };
78
+
79
+
45
80
GLuint g_vertex_buffer_id = NULL ;
46
81
GLuint g_index_buffer_id = NULL ;
47
82
GLuint g_texture = NULL ;
@@ -61,11 +96,67 @@ float g_camera_posX = 0.0;
61
96
float g_camera_posY = 5.0 ;
62
97
int g_lastMouseDownUpdateX = -1 ;
63
98
int g_lastMouseDownUpdateY = -1 ;
99
+ GuiRenderImpl::Update g_update;
100
+
101
+
102
+ // thread rendering 1 iteration
103
+ void renderJob ( rpr_context ctxt, GuiRenderImpl::Update* update )
104
+ {
105
+ CHECK ( rprContextRender ( ctxt ) );
106
+ update->m_done = 1 ;
107
+ return ;
108
+ }
109
+
110
+
64
111
65
112
void Update ()
66
113
{
67
- // Send update event
68
- glutPostRedisplay ();
114
+ // clear state
115
+ g_update.clear ();
116
+
117
+ // start the rendering thread
118
+ std::thread t ( &renderJob, g_context, &g_update );
119
+
120
+ // wait the rendering thread
121
+ while ( !g_update.m_done )
122
+ {
123
+ // at each update of the rendering thread
124
+ if ( g_update.m_hasUpdate )
125
+ {
126
+ // Read the frame buffer from RPR
127
+ // Note that rprContextResolveFrameBuffer and rprFrameBufferGetInfo(fb,RPR_FRAMEBUFFER_DATA) can be called asynchronous while rprContextRender is running.
128
+
129
+ CHECK ( rprContextResolveFrameBuffer ( g_context, g_frame_buffer, g_frame_buffer_2, false ) );
130
+ size_t frame_buffer_dataSize = 0 ;
131
+ CHECK ( rprFrameBufferGetInfo ( g_frame_buffer_2, RPR_FRAMEBUFFER_DATA, 0 , NULL , &frame_buffer_dataSize ) );
132
+
133
+ // check that the size fits with original buffer alloc
134
+ if ( frame_buffer_dataSize != WINDOW_WIDTH * WINDOW_HEIGHT * 4 * sizeof (float ) )
135
+ {
136
+ CHECK (RPR_ERROR_INTERNAL_ERROR)
137
+ }
138
+
139
+ CHECK ( rprFrameBufferGetInfo ( g_frame_buffer_2, RPR_FRAMEBUFFER_DATA, frame_buffer_dataSize , g_fbdata , NULL ) );
140
+
141
+ // update the OpenGL texture with the new image from RPR
142
+ glBindTexture (GL_TEXTURE_2D, g_texture);
143
+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_FLOAT, static_cast <const GLvoid*>(g_fbdata));
144
+ glBindTexture (GL_TEXTURE_2D, 0 );
145
+
146
+ // clear the update flag
147
+ g_update.m_hasUpdate = false ;
148
+ }
149
+
150
+ // Request a new Display call.
151
+ glutPostRedisplay ();
152
+
153
+ }
154
+
155
+ // wait the end of the rendering thread
156
+ t.join ();
157
+
158
+
159
+ return ;
69
160
}
70
161
71
162
void MoveCamera ()
@@ -143,9 +234,6 @@ void OnKeyboardEvent(unsigned char key, int xmouse, int ymouse)
143
234
144
235
void Display ()
145
236
{
146
- // Render FR image into the GL texture
147
- rprContextRender (g_context);
148
- rprContextResolveFrameBuffer (g_context, g_frame_buffer, g_frame_buffer_2, true );
149
237
150
238
// Clear backbuffer
151
239
glClear (GL_COLOR_BUFFER_BIT);
@@ -166,16 +254,7 @@ void Display()
166
254
167
255
glActiveTexture (GL_TEXTURE0);
168
256
glBindTexture (GL_TEXTURE_2D, g_texture);
169
-
170
-
171
-
172
- CHECK (rprFrameBufferGetInfo (g_frame_buffer_2, RPR_FRAMEBUFFER_DATA, WINDOW_WIDTH*WINDOW_HEIGHT*sizeof (float )*4 , g_fbdata, NULL ));
173
-
174
- // glBindTexture(GL_TEXTURE_2D, g_texture);
175
- glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_FLOAT, static_cast <const GLvoid*>(g_fbdata));
176
- // glBindTexture(GL_TEXTURE_2D, 0);
177
-
178
-
257
+ // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_FLOAT, static_cast<const GLvoid*>(g_fbdata));
179
258
180
259
GLuint position_attr_id = glGetAttribLocation (program, " inPosition" );
181
260
GLuint texcoord_attr_id = glGetAttribLocation (program, " inTexcoord" );
@@ -277,9 +356,9 @@ void OnExit()
277
356
278
357
int main (int argc, char ** argv)
279
358
{
280
- // enable firerender API trace
359
+ // enable RPR API trace
281
360
// set this before any RPR API calls
282
- // frContextSetParameter1u (0,RPR_CONTEXT_TRACING_ENABLED,1);
361
+ // rprContextSetParameter1u (0,RPR_CONTEXT_TRACING_ENABLED,1);
283
362
284
363
// GL setup
285
364
{
@@ -299,12 +378,11 @@ int main(int argc, char** argv)
299
378
InitGraphics ();
300
379
}
301
380
302
- std::cout << " FireRender SDK simple rendering tutorial.\n " ;
303
- // Indicates whether the last operation has suceeded or not
381
+ std::cout << " RPR SDK simple rendering tutorial.\n " ;
382
+
304
383
rpr_int status = RPR_SUCCESS;
305
- // Create OpenCL context using a single GPU
306
384
307
- // Register Tahoe ray tracing plugin.
385
+ // Register the plugin.
308
386
rpr_int tahoePluginID = rprRegisterPlugin (RPR_PLUGIN_FILE_NAME);
309
387
CHECK_NE (tahoePluginID , -1 )
310
388
rpr_int plugins[] = { tahoePluginID };
@@ -411,13 +489,21 @@ int main(int argc, char** argv)
411
489
// Set framebuffer for the context
412
490
CHECK (rprContextSetAOV (g_context, RPR_AOV_COLOR, g_frame_buffer));
413
491
414
- CHECK ( rprContextSetParameterByKey1u (g_context,RPR_CONTEXT_PREVIEW, 1u ) );
492
+ // this line can be added for faster RPR rendering.
493
+ // the higher RPR_CONTEXT_PREVIEW, the faster RPR rendering, ( but more pixelated )
494
+ // CHECK( rprContextSetParameterByKey1u(g_context,RPR_CONTEXT_PREVIEW, 1u ) );
415
495
416
496
// Set framebuffer for the context
417
497
CHECK (rprContextSetAOV (g_context, RPR_AOV_COLOR, g_frame_buffer));
418
498
419
- g_fbdata = new float [WINDOW_WIDTH * WINDOW_HEIGHT * 4 ];
499
+ // Define the update callback.
500
+ // During the rprContextRender execution, RPR will call it regularly
501
+ // The 'CALLBACK_DATA' : 'g_update' is not used by RPR. it can be any data structure that the API user wants.
502
+ CHECK (rprContextSetParameterByKeyPtr (g_context, RPR_CONTEXT_RENDER_UPDATE_CALLBACK_FUNC, (void *)GuiRenderImpl::notifyUpdate));
503
+ CHECK (rprContextSetParameterByKeyPtr (g_context, RPR_CONTEXT_RENDER_UPDATE_CALLBACK_DATA, &g_update));
420
504
505
+ // allocate the data that will be used the read RPR framebuffer, and give it to OpenGL.
506
+ g_fbdata = new float [WINDOW_WIDTH * WINDOW_HEIGHT * 4 ];
421
507
422
508
std::cout << " Press W or S to move the camera.\n " ;
423
509
0 commit comments