diff options
Diffstat (limited to 'intern/cycles/device/device.cpp')
-rw-r--r-- | intern/cycles/device/device.cpp | 85 |
1 files changed, 66 insertions, 19 deletions
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 3a33b8fb68b..5cad8e1b49c 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); @@ -51,7 +58,7 @@ void Device::pixels_free(device_memory& mem) mem_free(mem); } -void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent, +void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent, const DeviceDrawParams &draw_params) { pixels_copy_from(rgba, y, w, h); @@ -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,23 +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(); } - glPushMatrix(); - glTranslatef(0.0f, (float)dy, 0.0f); + 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); - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); - glVertex2f((float)width, 0.0f); - glTexCoord2f(1.0f, 1.0f); - glVertex2f((float)width, (float)height); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(0.0f, (float)height); + vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - glEnd(); + basep = NULL; + } + else { + basep = vbuffer; + vp = vbuffer; + } - glPopMatrix(); + if(vp) { + /* texture coordinate - vertex pair */ + vp[0] = 0.0f; + vp[1] = 0.0f; + vp[2] = dx; + vp[3] = dy; + + vp[4] = 1.0f; + vp[5] = 0.0f; + vp[6] = (float)width + dx; + vp[7] = dy; + + vp[8] = 1.0f; + vp[9] = 1.0f; + vp[10] = (float)width + dx; + vp[11] = (float)height + dy; + + vp[12] = 0.0f; + vp[13] = 1.0f; + vp[14] = dx; + 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(); @@ -113,7 +163,7 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w /* fallback for old graphics cards that don't support GLSL, half float, * and non-power-of-two textures */ glPixelZoom((float)width/(float)w, (float)height/(float)h); - glRasterPos2f(0, dy); + glRasterPos2f(dx, dy); uint8_t *pixels = (uint8_t*)rgba.data_pointer; @@ -277,13 +327,10 @@ string Device::device_capabilities() #endif #ifdef WITH_OPENCL - /* TODO(sergey): Needs proper usable implementation. */ - /* if(device_opencl_init()) { capabilities += "\nOpenCL device capabilities:\n"; capabilities += device_opencl_capabilities(); } - */ #endif return capabilities; |