diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-05-11 17:28:41 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-05-11 17:28:41 +0300 |
commit | e38f9144212dc0e7e7f3e6be9b3315435d1669eb (patch) | |
tree | 41532a79c1bdaa484a1cf674625f6a5bce044130 /intern/cycles | |
parent | cc1883468d8537067e0ae6af36075d5cc2d00b68 (diff) |
Cycles: use vertex buffers when possible to draw tiles on the screen.
Not terribly necessary in this case, since we are just drawing a quad,
but makes blender overall more GL 3.x core ready.
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/device/device.cpp | 79 | ||||
-rw-r--r-- | intern/cycles/device/device.h | 7 | ||||
-rw-r--r-- | intern/cycles/device/device_cuda.cpp | 59 |
3 files changed, 119 insertions, 26 deletions
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 839f35116fa..b34e0646384 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -33,6 +33,13 @@ CCL_NAMESPACE_BEGIN /* Device */ +Device::~Device() +{ + if(!background && vertex_buffer != 0) { + glDeleteBuffers(1, &vertex_buffer); + } +} + void Device::pixels_alloc(device_memory& mem) { mem_alloc(mem, MEM_READ_WRITE); @@ -67,6 +74,9 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w /* for multi devices, this assumes the inefficient method that we allocate * all pixels on the device even though we only render to a subset */ GLhalf *data_pointer = (GLhalf*)rgba.data_pointer; + float vbuffer[16], *basep; + float *vp = NULL; + data_pointer += 4*y*w; /* draw half float texture, GLSL shader for display transform assumed to be bound */ @@ -83,18 +93,63 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w draw_params.bind_display_space_shader_cb(); } - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex2f(0.0f, dy); - glTexCoord2f(1.0f, 0.0f); - glVertex2f((float)width, dy); - glTexCoord2f(1.0f, 1.0f); - glVertex2f((float)width, (float)height + dy); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(0.0f, (float)height + dy); - - glEnd(); + if(GLEW_VERSION_1_5) { + if (!vertex_buffer) + glGenBuffers(1, &vertex_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */ + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW); + + vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + basep = NULL; + } + else { + basep = vbuffer; + vp = vbuffer; + } + + if (vp) { + /* texture coordinate - vertex pair */ + vp[0] = 0.0f; + vp[1] = 0.0f; + vp[2] = 0.0f; + vp[3] = dy; + + vp[4] = 1.0f; + vp[5] = 0.0f; + vp[6] = (float)width; + vp[7] = dy; + + vp[8] = 1.0f; + vp[9] = 1.0f; + vp[10] = (float)width; + vp[11] = (float)height + dy; + + vp[12] = 0.0f; + vp[13] = 1.0f; + vp[14] = 0.0f; + vp[15] = (float)height + dy; + + if (vertex_buffer) + glUnmapBuffer(GL_ARRAY_BUFFER); + } + + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep); + glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + if(vertex_buffer) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + } if(draw_params.unbind_display_space_shader_cb) { draw_params.unbind_display_space_shader_cb(); diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 162f51252b0..b32f7b406c7 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -119,13 +119,16 @@ struct DeviceDrawParams { class Device { protected: - Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {} + Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), vertex_buffer(0), info(info_), stats(stats_) {} bool background; string error_msg; + /* used for real time display */ + unsigned int vertex_buffer; + public: - virtual ~Device() {} + virtual ~Device(); /* info */ DeviceInfo info; diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 42d4f8e48ff..be6a1f3502d 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -885,6 +885,7 @@ public: { if(!background) { PixelMem pmem = pixel_mem_map[mem.device_pointer]; + float *vpointer; cuda_push_context(); @@ -918,18 +919,52 @@ public: draw_params.bind_display_space_shader_cb(); } - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex2f(0.0f, dy); - glTexCoord2f((float)w/(float)pmem.w, 0.0f); - glVertex2f((float)width, dy); - glTexCoord2f((float)w/(float)pmem.w, (float)h/(float)pmem.h); - glVertex2f((float)width, (float)height + dy); - glTexCoord2f(0.0f, (float)h/(float)pmem.h); - glVertex2f(0.0f, (float)height + dy); - - glEnd(); + if (!vertex_buffer) + glGenBuffers(1, &vertex_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */ + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW); + + vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + if (vpointer) { + /* texture coordinate - vertex pair */ + vpointer[0] = 0.0f; + vpointer[1] = 0.0f; + vpointer[2] = 0.0f; + vpointer[3] = dy; + + vpointer[4] = (float)w/(float)pmem.w; + vpointer[5] = 0.0f; + vpointer[6] = (float)width; + vpointer[7] = dy; + + vpointer[8] = (float)w/(float)pmem.w; + vpointer[9] = (float)h/(float)pmem.h; + vpointer[10] = (float)width; + vpointer[11] = (float)height + dy; + + vpointer[12] = 0.0f; + vpointer[13] = (float)h/(float)pmem.h; + vpointer[14] = 0.0f; + vpointer[15] = (float)height + dy; + + glUnmapBuffer(GL_ARRAY_BUFFER); + } + + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0); + glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)NULL + 2 * sizeof(float)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); if(draw_params.unbind_display_space_shader_cb) { draw_params.unbind_display_space_shader_cb(); |