Esempio n. 1
0
pj_status_t pjmedia_vid_dev_opengl_init_buffers(gl_buffers *glb)
{
    /* Attributes */
    GLint attribLocation[NUM_ATTRIBUTES] = { ATTRIB_VERTEX,
        ATTRIB_TEXTUREPOSITON };
    GLchar *attribName[NUM_ATTRIBUTES] = { "position", "texCoord" };
    
    if (!glb->direct ) {
    	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
                                     &glb->rendBufW);
    	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
                                     &glb->rendBufH);
    
    	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                  GL_RENDERBUFFER, glb->rendBuf);
    	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
            LOG("Unable to create frame buffer");
            return -1;
        }
    }
    
    create_program(vertSrc, fragSrc, NUM_ATTRIBUTES,
                   (const GLchar **)&attribName[0], attribLocation,
                   &glb->directProg);
    
    if (!glb->directProg) {
        LOG("Unable to create program");
        return -2;
    }
    
    return PJ_SUCCESS;
}
void col::render::OpenGLESIOSContext::resizeRenderTarget(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
    makeCurrent();
    deleteRenderTarget();
    
    // framebuffer object
    GL_COMMAND(glGenFramebuffers(1, &m_defaultFramebuffer));
    GL_COMMAND(glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFramebuffer));
    
    // color target
    GL_COMMAND(glGenRenderbuffers(1, &m_colorRenderBuffer));
    GL_COMMAND(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderBuffer));
    GL_COMMAND([m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)m_view.layer]);
    GL_COMMAND(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderBuffer));
    
    GLint actualWidth, actualHeight;
    GL_COMMAND(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &actualWidth));
    GL_COMMAND(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &actualHeight));
    
    // depth / stencil combo target
    GL_COMMAND(glGenRenderbuffers(1, &m_depthRenderBuffer));
    GL_COMMAND(glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderBuffer));
    //GL_COMMAND(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, actualWidth, actualHeight));
    GL_COMMAND(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, actualWidth, actualHeight));
    GL_COMMAND(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderBuffer));
    //GL_COMMAND(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderBuffer));
    
    GL_COMMAND(glViewport(0, 0, actualWidth, actualHeight));
    
    GL_COMMAND(GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER));
    switch(status) {
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
            COL_LOG_FATAL("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
            break;
            
        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
            COL_LOG_FATAL("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
            break;
            
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
            COL_LOG_FATAL("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
            break;
            
        case GL_FRAMEBUFFER_UNSUPPORTED:
            COL_LOG_FATAL("GL_FRAMEBUFFER_UNSUPPORTED");
            break;
            
        case GL_FRAMEBUFFER_COMPLETE:
            break;
            
        default:
            COL_LOG_FATAL("Unknown framebuffer status");
            break;
    }
}
Esempio n. 3
0
static bool
getBoundRenderbufferDesc(Context &context, ImageDesc &desc)
{
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &desc.width);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &desc.height);
    desc.depth = 1;
    
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &desc.internalFormat);
    
    return desc.valid();
}
Esempio n. 4
0
	void resize(ivec2 const& _dims)
	{
		bind();

		GLint samples{}, format{};

		glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
		glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &format);

		glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, _dims.x, _dims.y);
	}
Esempio n. 5
0
RenderbufferRef Renderbuffer::fromGLRenderbuffer(
    const std::string&         _name, 
    const GLuint             _imageID,
    const G3D::ImageFormat*  _format) {

    GLint w, h;

    // Extract the width and height
    glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &w);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &h);
    debugAssertGLOk();

    // Create new renderbuffer
    return RenderBufferRef(new Renderbuffer(_name, _imageID, _format, w, h));
}
Esempio n. 6
0
static bool
getRenderbufferSize(GLint renderbuffer, GLint *width, GLint *height)
{
    GLint bound_renderbuffer = 0;
    glGetIntegerv(GL_RENDERBUFFER_BINDING, &bound_renderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);

    *width = 0;
    *height = 0;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, width);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, height);

    glBindRenderbuffer(GL_RENDERBUFFER, bound_renderbuffer);
    
    return *width > 0 && *height > 0;
}
Esempio n. 7
0
static void
validate_current_renderbuffer(const char *type, int input_samples, int input_storage_samples)
{
	int samples, storage_samples;

	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STORAGE_SAMPLES_AMD,
				     &storage_samples);
	piglit_check_gl_error(GL_NO_ERROR);

	if (samples != input_samples ||
	    storage_samples != input_storage_samples) {
		piglit_fail("Created %s buffer (samples = %u, storageSamples = %u), got (%u, %u)\n",
			    type, input_samples, input_storage_samples, samples, storage_samples);
	}
}
Esempio n. 8
0
Handle<Value> GLESglGetRenderbufferParameterCallback(const Arguments& args) {
	//if less that nbr of formal parameters then do nothing
	if (args.Length() != 2)
		return v8::Undefined();
	
	//get arguments
	unsigned target = args[0]->Uint32Value();
	unsigned pname = args[1]->Uint32Value();

	switch(pname) {
		//1 int value
		case GL_RENDERBUFFER_WIDTH:
		case GL_RENDERBUFFER_HEIGHT:
		case GL_RENDERBUFFER_INTERNAL_FORMAT:
		case GL_RENDERBUFFER_RED_SIZE:
		case GL_RENDERBUFFER_GREEN_SIZE:
		case GL_RENDERBUFFER_BLUE_SIZE:
		case GL_RENDERBUFFER_ALPHA_SIZE:
		case GL_RENDERBUFFER_DEPTH_SIZE:
		case  GL_RENDERBUFFER_STENCIL_SIZE:
		{
			int ans = 0;
			glGetRenderbufferParameteriv((GLenum)target, (GLenum)pname, (GLint*)&ans);

			return Integer::New(ans);
		}
	}

	return v8::Undefined();
}
Esempio n. 9
0
GLint RenderBufferObject::getParameter(GLenum pname)
{
	GLint value = 0;

	glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &value);
	CheckGLError();

	return value;
}
Esempio n. 10
0
///////////////////////////////////////////////////////////////////////////////
// return renderbuffer parameters as string using glGetRenderbufferParameteriv
///////////////////////////////////////////////////////////////////////////////
    std::string getRenderbufferParameters(GLuint id) {
        if (glIsRenderbuffer(id) == GL_FALSE)
            return "Not Renderbuffer object";

        int width, height, format;
        std::string formatName;
        glBindRenderbuffer(GL_RENDERBUFFER, id);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);    // get renderbuffer width
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);  // get renderbuffer height
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &format); // get renderbuffer internal format
        glBindRenderbuffer(GL_RENDERBUFFER, 0);

        formatName = convertInternalFormatToString(format);

        std::stringstream ss;
        ss << width << "x" << height << ", " << formatName << "(" << format << ")";
        return ss.str();
    }
Esempio n. 11
0
            int getRenderbufferParameter(int renderbuffer, int param) {
            
                int result = 0;

                    glGetRenderbufferParameteriv(renderbuffer, param, &result);

                return result;

            } //
 inline void VL_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
 {
   if (glGetRenderbufferParameteriv)
     glGetRenderbufferParameteriv(target, pname, params);
   else
   if (glGetRenderbufferParameterivEXT)
     glGetRenderbufferParameterivEXT(target, pname, params);
   else
     VL_UNSUPPORTED_FUNC();
 }
Esempio n. 13
0
/*-------------------------------------
 * Introspection (most) of a Texture Attributes
-------------------------------------*/
bool RBOAttrib::introspect_attribs() noexcept {
    GLint fmt = 0;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &fmt);

    if (!fmt) {
        return false;
    }

    set_internal_format((rbo_format_t)fmt);

    return true;
}
FrameBufferObjectSurface::FrameBufferObjectSurface(GLint surfaceWidth, GLint surfaceHeight)
{
    previousFboID   =   0;
    fboID           =   0;
    
    if(surfaceWidth == 0){
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
    }
    else{
        width = surfaceWidth;
    }
    
    if(surfaceHeight == 0){
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
    }
    else{
        height = surfaceHeight;
    }
    
    //bitwiseTexMask  = texturBufferMask;
}
Esempio n. 15
0
  // ********************************************************** Figure::render
  void render( bool update_axes_x=false, bool update_axes_y=false )
  {
    glfwMakeContextCurrent( _window );
    // TODO can also be set to another DataStructure
    glfwSetWindowUserPointer( _window, this);

    if( _offscreen ) {
      // set rendering destination to FBO
      glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
      utils::gl::check_error();
    }
    
    if( update_axes_x || update_axes_y ) {
      // Build proper axis by finding min/max on each axe
      BoundingBox bbox{ std::numeric_limits<double>::max(),
	  (-std::numeric_limits<double>::max()),
	  std::numeric_limits<double>::max(),
	  -std::numeric_limits<double>::max() };
      
      for( const auto& curve: _curves ) {
	auto b = curve->get_bbox();
	if( b.x_min < bbox.x_min ) bbox.x_min = b.x_min;
	if( b.x_max > bbox.x_max ) bbox.x_max = b.x_max;
	if( b.y_min < bbox.y_min ) bbox.y_min = b.y_min;
	if( b.y_max > bbox.y_max ) bbox.y_max = b.y_max;
      }
      if( update_axes_x) 
	_axis_x = Axis( "X", {bbox.x_min,bbox.x_max, 10, 2});
      if( update_axes_y )
	_axis_y = Axis( "Y", {bbox.y_min,bbox.y_max, 10, 2});
    }
    
    // get window size
    if( _offscreen ) {
      glBindRenderbuffer( GL_RENDERBUFFER, _render_buf );
      utils::gl::check_error();
      glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_width);
      glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_height);
      utils::gl::check_error();
      glBindRenderbuffer( GL_RENDERBUFFER, 0 );
      utils::gl::check_error();
    }
    else {
      glfwGetFramebufferSize( _window, &_width, &_height);
    }
    // Info for scaling View and axes
    auto x_min_win = _axis_x.get_range()._min
      - 0.08 * (_axis_x.get_range()._max - _axis_x.get_range()._min);
    auto x_max_win = _axis_x.get_range()._max
      + 0.08 * (_axis_x.get_range()._max - _axis_x.get_range()._min);
    auto ratio_x = (x_max_win-x_min_win) / (double) _width;
    auto y_min_win = _axis_y.get_range()._min
      - 0.08 * (_axis_y.get_range()._max - _axis_y.get_range()._min);
    auto y_max_win = _axis_y.get_range()._max
      + 0.08 * (_axis_y.get_range()._max - _axis_y.get_range()._min);
    auto ratio_y = (y_max_win-y_min_win) / (double) _height;

    glViewport(0, 0, _width, _height);
    glClearColor( 1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho( x_min_win, x_max_win, y_min_win, y_max_win, 1.f, -1.f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Basic axes
    if( _draw_axes ) {
      _axis_x.render( ratio_x, ratio_y );
      glPushMatrix(); // AXE_Y
      glRotated( 90.0, 0.0, 0.0, 1.0 );
      _axis_y.render( ratio_y, ratio_x);
      glPopMatrix(); // AXE_Y
    }
    // All other objects
    for( const auto& curve: _curves) {
      curve->render();
    }

    // GraphicText
    for( auto& txt: _text_list) {
      glPushMatrix(); {
        glTranslated( txt.x, txt.y, 0.0);
        glScaled( ratio_x, ratio_y, 1.0 );
        _font->Render( txt.msg.c_str() );
      } glPopMatrix();
    }

    if( not _offscreen ) {
      // Draw tweak bars
      TwDraw();
      
      glfwSwapBuffers( _window );
      glfwPollEvents();
    }
  }
Esempio n. 16
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(1, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;

        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else if (attachment == QGLFramebufferObject::Depth
               || attachment == QGLFramebufferObject::CombinedDepthStencil)
    {
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::Depth;
        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}
Esempio n. 17
0
enum piglit_result
piglit_display(void)
{
	bool pass = true;
	GLchar label[11];
	GLsizei length;
	GLuint ids[10];
	GLint param;

	/* Throw some invalid inputs at glCreateRenderbuffers */

	/* n is negative */
	glCreateRenderbuffers(-1, ids);
	SUBTEST(GL_INVALID_VALUE, pass, "n < 0");

	/* Throw some valid inputs at glCreateRenderbuffers. */

	/* n is zero */
	glCreateRenderbuffers(0, NULL);
	SUBTEST(GL_NO_ERROR, pass, "n == 0");

	/* n is more than 1 */
	glCreateRenderbuffers(10, ids);
	SUBTEST(GL_NO_ERROR, pass, "n > 1");

	/* test the default state of dsa-created render buffer objects */
	SUBTESTCONDITION(glIsRenderbuffer(ids[2]), pass, "IsRenderbuffer()");

	glBindRenderbuffer(GL_RENDERBUFFER, ids[2]);
	piglit_check_gl_error(GL_NO_ERROR);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_WIDTH, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default width(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_HEIGHT, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default height(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_INTERNAL_FORMAT, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == GL_RGBA, pass,
			 "default internal format == RGBA");

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_RED_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default red size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_GREEN_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default green size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_BLUE_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default blue size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_ALPHA_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default alpha size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_DEPTH_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default depth size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_STENCIL_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default stencil size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_SAMPLES, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default no. of samples(%d) == 0", param);

	glGetObjectLabel(GL_RENDERBUFFER, ids[2], 11, &length, label);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(length == 0, pass,
			 "default label size(%d) == 0", length);

	/* clean up */
	glDeleteRenderbuffers(10, ids);

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Esempio n. 18
0
uintptr_t processFn(struct fnargs* args, char* parg) {
	uintptr_t ret = 0;
	switch (args->fn) {
	case glfnUNDEFINED:
		abort(); // bad glfn
		break;
	case glfnActiveTexture:
		glActiveTexture((GLenum)args->a0);
		break;
	case glfnAttachShader:
		glAttachShader((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnBindAttribLocation:
		glBindAttribLocation((GLint)args->a0, (GLint)args->a1, (GLchar*)args->a2);
		break;
	case glfnBindBuffer:
		glBindBuffer((GLenum)args->a0, (GLuint)args->a1);
		break;
	case glfnBindFramebuffer:
		glBindFramebuffer((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBindRenderbuffer:
		glBindRenderbuffer((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBindTexture:
		glBindTexture((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBlendColor:
		glBlendColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnBlendEquation:
		glBlendEquation((GLenum)args->a0);
		break;
	case glfnBlendEquationSeparate:
		glBlendEquationSeparate((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnBlendFunc:
		glBlendFunc((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnBlendFuncSeparate:
		glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
		break;
	case glfnBufferData:
		glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2);
		break;
	case glfnBufferSubData:
		glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)parg);
		break;
	case glfnCheckFramebufferStatus:
		ret = glCheckFramebufferStatus((GLenum)args->a0);
		break;
	case glfnClear:
		glClear((GLenum)args->a0);
		break;
	case glfnClearColor:
		glClearColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnClearDepthf:
		glClearDepthf(*(GLfloat*)&args->a0);
		break;
	case glfnClearStencil:
		glClearStencil((GLint)args->a0);
		break;
	case glfnColorMask:
		glColorMask((GLboolean)args->a0, (GLboolean)args->a1, (GLboolean)args->a2, (GLboolean)args->a3);
		break;
	case glfnCompileShader:
		glCompileShader((GLint)args->a0);
		break;
	case glfnCompressedTexImage2D:
		glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)parg);
		break;
	case glfnCompressedTexSubImage2D:
		glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)parg);
		break;
	case glfnCopyTexImage2D:
		glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7);
		break;
	case glfnCopyTexSubImage2D:
		glCopyTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7);
		break;
	case glfnCreateProgram:
		ret = glCreateProgram();
		break;
	case glfnCreateShader:
		ret = glCreateShader((GLenum)args->a0);
		break;
	case glfnCullFace:
		glCullFace((GLenum)args->a0);
		break;
	case glfnDeleteBuffer:
		glDeleteBuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteFramebuffer:
		glDeleteFramebuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteProgram:
		glDeleteProgram((GLint)args->a0);
		break;
	case glfnDeleteRenderbuffer:
		glDeleteRenderbuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteShader:
		glDeleteShader((GLint)args->a0);
		break;
	case glfnDeleteTexture:
		glDeleteTextures(1, (const GLuint*)(&args->a0));
		break;
	case glfnDepthFunc:
		glDepthFunc((GLenum)args->a0);
		break;
	case glfnDepthMask:
		glDepthMask((GLboolean)args->a0);
		break;
	case glfnDepthRangef:
		glDepthRangef(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnDetachShader:
		glDetachShader((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnDisable:
		glDisable((GLenum)args->a0);
		break;
	case glfnDisableVertexAttribArray:
		glDisableVertexAttribArray((GLint)args->a0);
		break;
	case glfnDrawArrays:
		glDrawArrays((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2);
		break;
	case glfnDrawElements:
		glDrawElements((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (void*)args->a3);
		break;
	case glfnEnable:
		glEnable((GLenum)args->a0);
		break;
	case glfnEnableVertexAttribArray:
		glEnableVertexAttribArray((GLint)args->a0);
		break;
	case glfnFinish:
		glFinish();
		break;
	case glfnFlush:
		glFlush();
		break;
	case glfnFramebufferRenderbuffer:
		glFramebufferRenderbuffer((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3);
		break;
	case glfnFramebufferTexture2D:
		glFramebufferTexture2D((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4);
		break;
	case glfnFrontFace:
		glFrontFace((GLenum)args->a0);
		break;
	case glfnGenBuffer:
		glGenBuffers(1, (GLuint*)&ret);
		break;
	case glfnGenFramebuffer:
		glGenFramebuffers(1, (GLuint*)&ret);
		break;
	case glfnGenRenderbuffer:
		glGenRenderbuffers(1, (GLuint*)&ret);
		break;
	case glfnGenTexture:
		glGenTextures(1, (GLuint*)&ret);
		break;
	case glfnGenerateMipmap:
		glGenerateMipmap((GLenum)args->a0);
		break;
	case glfnGetActiveAttrib:
		glGetActiveAttrib(
			(GLuint)args->a0,
			(GLuint)args->a1,
			(GLsizei)args->a2,
			NULL,
			(GLint*)&ret,
			(GLenum*)args->a3,
			(GLchar*)parg);
		break;
	case glfnGetActiveUniform:
		glGetActiveUniform(
			(GLuint)args->a0,
			(GLuint)args->a1,
			(GLsizei)args->a2,
			NULL,
			(GLint*)&ret,
			(GLenum*)args->a3,
			(GLchar*)parg);
		break;
	case glfnGetAttachedShaders:
		glGetAttachedShaders((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)&ret, (GLuint*)parg);
		break;
	case glfnGetAttribLocation:
		ret = glGetAttribLocation((GLint)args->a0, (GLchar*)args->a1);
		break;
	case glfnGetBooleanv:
		glGetBooleanv((GLenum)args->a0, (GLboolean*)parg);
		break;
	case glfnGetBufferParameteri:
		glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetFloatv:
		glGetFloatv((GLenum)args->a0, (GLfloat*)parg);
		break;
	case glfnGetIntegerv:
		glGetIntegerv((GLenum)args->a0, (GLint*)parg);
		break;
	case glfnGetError:
		ret = glGetError();
		break;
	case glfnGetFramebufferAttachmentParameteriv:
		glGetFramebufferAttachmentParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint*)&ret);
		break;
	case glfnGetProgramiv:
		glGetProgramiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetProgramInfoLog:
		glGetProgramInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetRenderbufferParameteriv:
		glGetRenderbufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetShaderiv:
		glGetShaderiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetShaderInfoLog:
		glGetShaderInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetShaderPrecisionFormat:
		glGetShaderPrecisionFormat((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg, &((GLint*)parg)[2]);
		break;
	case glfnGetShaderSource:
		glGetShaderSource((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetString:
		ret = (uintptr_t)glGetString((GLenum)args->a0);
		break;
	case glfnGetTexParameterfv:
		glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnGetTexParameteriv:
		glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnGetUniformfv:
		glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)parg);
		break;
	case glfnGetUniformiv:
		glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)parg);
		break;
	case glfnGetUniformLocation:
		ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1);
		break;
	case glfnGetVertexAttribfv:
		glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnGetVertexAttribiv:
		glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnHint:
		glHint((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnIsBuffer:
		ret = glIsBuffer((GLint)args->a0);
		break;
	case glfnIsEnabled:
		ret = glIsEnabled((GLenum)args->a0);
		break;
	case glfnIsFramebuffer:
		ret = glIsFramebuffer((GLint)args->a0);
		break;
	case glfnIsProgram:
		ret = glIsProgram((GLint)args->a0);
		break;
	case glfnIsRenderbuffer:
		ret = glIsRenderbuffer((GLint)args->a0);
		break;
	case glfnIsShader:
		ret = glIsShader((GLint)args->a0);
		break;
	case glfnIsTexture:
		ret = glIsTexture((GLint)args->a0);
		break;
	case glfnLineWidth:
		glLineWidth(*(GLfloat*)&args->a0);
		break;
	case glfnLinkProgram:
		glLinkProgram((GLint)args->a0);
		break;
	case glfnPixelStorei:
		glPixelStorei((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnPolygonOffset:
		glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnReadPixels:
		glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)parg);
		break;
	case glfnReleaseShaderCompiler:
		glReleaseShaderCompiler();
		break;
	case glfnRenderbufferStorage:
		glRenderbufferStorage((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnSampleCoverage:
		glSampleCoverage(*(GLfloat*)&args->a0, (GLboolean)args->a1);
		break;
	case glfnScissor:
		glScissor((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnShaderSource:
#if defined(os_ios) || defined(os_osx)
		glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar *const *)args->a2, NULL);
#else
		glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar **)args->a2, NULL);
#endif
		break;
	case glfnStencilFunc:
		glStencilFunc((GLenum)args->a0, (GLint)args->a1, (GLuint)args->a2);
		break;
	case glfnStencilFuncSeparate:
		glStencilFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLuint)args->a3);
		break;
	case glfnStencilMask:
		glStencilMask((GLuint)args->a0);
		break;
	case glfnStencilMaskSeparate:
		glStencilMaskSeparate((GLenum)args->a0, (GLuint)args->a1);
		break;
	case glfnStencilOp:
		glStencilOp((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2);
		break;
	case glfnStencilOpSeparate:
		glStencilOpSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
		break;
	case glfnTexImage2D:
		glTexImage2D(
			(GLenum)args->a0,
			(GLint)args->a1,
			(GLint)args->a2,
			(GLsizei)args->a3,
			(GLsizei)args->a4,
			0, // border
			(GLenum)args->a5,
			(GLenum)args->a6,
			(const GLvoid*)parg);
		break;
	case glfnTexSubImage2D:
		glTexSubImage2D(
			(GLenum)args->a0,
			(GLint)args->a1,
			(GLint)args->a2,
			(GLint)args->a3,
			(GLsizei)args->a4,
			(GLsizei)args->a5,
			(GLenum)args->a6,
			(GLenum)args->a7,
			(const GLvoid*)parg);
		break;
	case glfnTexParameterf:
		glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnTexParameterfv:
		glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnTexParameteri:
		glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2);
		break;
	case glfnTexParameteriv:
		glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnUniform1f:
		glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnUniform1fv:
		glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform1i:
		glUniform1i((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnUniform1iv:
		glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform2f:
		glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnUniform2fv:
		glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform2i:
		glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2);
		break;
	case glfnUniform2iv:
		glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform3f:
		glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnUniform3fv:
		glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform3i:
		glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnUniform3iv:
		glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform4f:
		glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
		break;
	case glfnUniform4fv:
		glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform4i:
		glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4);
		break;
	case glfnUniform4iv:
		glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniformMatrix2fv:
		glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUniformMatrix3fv:
		glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUniformMatrix4fv:
		glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUseProgram:
		glUseProgram((GLint)args->a0);
		break;
	case glfnValidateProgram:
		glValidateProgram((GLint)args->a0);
		break;
	case glfnVertexAttrib1f:
		glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnVertexAttrib1fv:
		glVertexAttrib1fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib2f:
		glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnVertexAttrib2fv:
		glVertexAttrib2fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib3f:
		glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnVertexAttrib3fv:
		glVertexAttrib3fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib4f:
		glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
		break;
	case glfnVertexAttrib4fv:
		glVertexAttrib4fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttribPointer:
		glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5);
		break;
	case glfnViewport:
		glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	}
	return ret;
}
Esempio n. 19
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(0, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT && samples > 0) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
    // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
    // might not be supported while separate buffers are, according to QTBUG-12861.

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        stencil_buffer = depth_buffer;
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, stencil_buffer);

        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            stencil_buffer = depth_buffer = 0;
        }
    }

    if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
        || (attachment == QGLFramebufferObject::Depth)))
    {
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
            } else {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT16, size.width(), size.height());
            }
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, 
                                        size.width(), size.height());
            } else {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, 
                                        size.width(), size.height());
            }
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            depth_buffer = 0;
        }
    }

    if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
        glGenRenderbuffers(1, &stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX8_EXT, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT,
                                  size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
                                  size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                  GL_RENDERBUFFER_EXT, stencil_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &stencil_buffer);
            stencil_buffer = 0;
        }
    }

    // The FBO might have become valid after removing the depth or stencil buffer.
    valid = checkFramebufferStatus();

    if (depth_buffer && stencil_buffer) {
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
    } else if (depth_buffer) {
        fbo_attachment = QGLFramebufferObject::Depth;
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        if (depth_buffer)
            glDeleteRenderbuffers(1, &depth_buffer);
        if (stencil_buffer && depth_buffer != stencil_buffer)
            glDeleteRenderbuffers(1, &stencil_buffer);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}
Esempio n. 20
0
 void get_renderbuffer_parameteriv(renderbuffer_target_t target, gl::enum_t pname, gl::int_t * params) {
   glGetRenderbufferParameteriv(static_cast<GLenum>(target), pname, params);
 }
Esempio n. 21
0
static inline GLuint
downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
                       GLint colorRb, GLint depthRb, GLint stencilRb,
                       GLuint *rbs, GLint *numRbs)
{
    GLuint fbo;
    GLint format;
    GLint w, h;

    *numRbs = 0;

    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_WIDTH, &w);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_HEIGHT, &h);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_INTERNAL_FORMAT, &format);

    glGenRenderbuffers(1, &rbs[*numRbs]);
    glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
    glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
                              GL_RENDERBUFFER, rbs[*numRbs]);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glDrawBuffer(drawbuffer);
    glReadBuffer(drawbuffer);
    glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    ++*numRbs;

    if (stencilRb == depthRb && stencilRb) {
        //combined depth and stencil buffer
        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                     GL_RENDERBUFFER_WIDTH, &w);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                     GL_RENDERBUFFER_HEIGHT, &h);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);

        glGenRenderbuffers(1, &rbs[*numRbs]);
        glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
        glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                                  GL_RENDERBUFFER, rbs[*numRbs]);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
        glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
                          GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        ++*numRbs;
    } else {
        if (depthRb) {
            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                         GL_RENDERBUFFER_WIDTH, &w);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                         GL_RENDERBUFFER_HEIGHT, &h);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                         GL_RENDERBUFFER_INTERNAL_FORMAT, &format);

            glGenRenderbuffers(1, &rbs[*numRbs]);
            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                                      GL_DEPTH_ATTACHMENT,
                                      GL_RENDERBUFFER, rbs[*numRbs]);
            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
            glDrawBuffer(GL_DEPTH_ATTACHMENT);
            glReadBuffer(GL_DEPTH_ATTACHMENT);
            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
                              GL_DEPTH_BUFFER_BIT, GL_NEAREST);
            ++*numRbs;
        }
        if (stencilRb) {
            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                         GL_RENDERBUFFER_WIDTH, &w);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                         GL_RENDERBUFFER_HEIGHT, &h);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);

            glGenRenderbuffers(1, &rbs[*numRbs]);
            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                                      GL_STENCIL_ATTACHMENT,
                                      GL_RENDERBUFFER, rbs[*numRbs]);
            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
            glDrawBuffer(GL_STENCIL_ATTACHMENT);
            glReadBuffer(GL_STENCIL_ATTACHMENT);
            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
                              GL_STENCIL_BUFFER_BIT, GL_NEAREST);
            ++*numRbs;
        }
    }

    return fbo;
}
Esempio n. 22
0
/**
 * gdk_cairo_draw_from_gl:
 * @cr: a cairo context
 * @window: The window we're rendering for (not necessarily into)
 * @source: The GL ID of the source buffer
 * @source_type: The type of the @source
 * @buffer_scale: The scale-factor that the @source buffer is allocated for
 * @x: The source x position in @source to start copying from in GL coordinates
 * @y: The source y position in @source to start copying from in GL coordinates
 * @width: The width of the region to draw
 * @height: The height of the region to draw
 *
 * This is the main way to draw GL content in GTK+. It takes a render buffer ID
 * (@source_type == #GL_RENDERBUFFER) or a texture id (@source_type == #GL_TEXTURE)
 * and draws it onto @cr with an OVER operation, respecting the current clip.
 * The top left corner of the rectangle specified by @x, @y, @width and @height
 * will be drawn at the current (0,0) position of the cairo_t.
 *
 * This will work for *all* cairo_t, as long as @window is realized, but the
 * fallback implementation that reads back the pixels from the buffer may be
 * used in the general case. In the case of direct drawing to a window with
 * no special effects applied to @cr it will however use a more efficient
 * approach.
 *
 * For #GL_RENDERBUFFER the code will always fall back to software for buffers
 * with alpha components, so make sure you use #GL_TEXTURE if using alpha.
 *
 * Calling this may change the current GL context.
 *
 * Since: 3.16
 */
void
gdk_cairo_draw_from_gl (cairo_t              *cr,
                        GdkWindow            *window,
                        int                   source,
                        int                   source_type,
                        int                   buffer_scale,
                        int                   x,
                        int                   y,
                        int                   width,
                        int                   height)
{
    GdkGLContext *paint_context;
    cairo_surface_t *image;
    cairo_matrix_t matrix;
    int dx, dy, window_scale;
    gboolean trivial_transform;
    cairo_surface_t *group_target;
    GdkWindow *direct_window, *impl_window;
    guint framebuffer;
    int alpha_size = 0;
    cairo_region_t *clip_region;
    GdkGLContextPaintData *paint_data;

    impl_window = window->impl_window;

    window_scale = gdk_window_get_scale_factor (impl_window);

    paint_context = gdk_window_get_paint_gl_context (window, NULL);
    if (paint_context == NULL)
    {
        g_warning ("gdk_cairo_draw_gl_render_buffer failed - no paint context");
        return;
    }

    clip_region = gdk_cairo_region_from_clip (cr);

    gdk_gl_context_make_current (paint_context);
    paint_data = gdk_gl_context_get_paint_data (paint_context);

    if (paint_data->tmp_framebuffer == 0)
        glGenFramebuffersEXT (1, &paint_data->tmp_framebuffer);

    if (source_type == GL_RENDERBUFFER)
    {
        glBindRenderbuffer (GL_RENDERBUFFER, source);
        glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE,  &alpha_size);
    }
    else if (source_type == GL_TEXTURE)
    {
        glBindTexture (GL_TEXTURE_2D, source);

        glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE,  &alpha_size);
    }
    else
    {
        g_warning ("Unsupported gl source type %d\n", source_type);
        return;
    }

    group_target = cairo_get_group_target (cr);
    direct_window = cairo_surface_get_user_data (group_target, &direct_key);

    cairo_get_matrix (cr, &matrix);

    dx = matrix.x0;
    dy = matrix.y0;

    /* Trivial == integer-only translation */
    trivial_transform =
        (double)dx == matrix.x0 && (double)dy == matrix.y0 &&
        matrix.xx == 1.0 && matrix.xy == 0.0 &&
        matrix.yx == 0.0 && matrix.yy == 1.0;

    /* For direct paint of non-alpha renderbuffer, we can
       just do a bitblit */
    if ((_gdk_gl_flags & GDK_GL_SOFTWARE_DRAW_GL) == 0 &&
            source_type == GL_RENDERBUFFER &&
            alpha_size == 0 &&
            direct_window != NULL &&
            direct_window->current_paint.use_gl &&
            trivial_transform &&
            clip_region != NULL)
    {
        int unscaled_window_height;
        int i;

        /* Create a framebuffer with the source renderbuffer and
           make it the current target for reads */
        framebuffer = paint_data->tmp_framebuffer;
        glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);
        glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                      GL_RENDERBUFFER_EXT, source);
        glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);

        /* Translate to impl coords */
        cairo_region_translate (clip_region, dx, dy);

        glEnable (GL_SCISSOR_TEST);

        gdk_window_get_unscaled_size (impl_window, NULL, &unscaled_window_height);
        glDrawBuffer (GL_BACK);

#define FLIP_Y(_y) (unscaled_window_height - (_y))

        for (i = 0; i < cairo_region_num_rectangles (clip_region); i++)
        {
            cairo_rectangle_int_t clip_rect, dest;

            cairo_region_get_rectangle (clip_region, i, &clip_rect);
            clip_rect.x *= window_scale;
            clip_rect.y *= window_scale;
            clip_rect.width *= window_scale;
            clip_rect.height *= window_scale;

            glScissor (clip_rect.x, FLIP_Y (clip_rect.y + clip_rect.height),
                       clip_rect.width, clip_rect.height);

            dest.x = dx * window_scale;
            dest.y = dy * window_scale;
            dest.width = width * window_scale / buffer_scale;
            dest.height = height * window_scale / buffer_scale;

            if (gdk_rectangle_intersect (&clip_rect, &dest, &dest))
            {
                int clipped_src_x = x + (dest.x - dx * window_scale);
                int clipped_src_y = y + (height - dest.height - (dest.y - dy * window_scale));
                glBlitFramebufferEXT(clipped_src_x, clipped_src_y,
                                     (clipped_src_x + dest.width), (clipped_src_y + dest.height),
                                     dest.x, FLIP_Y(dest.y + dest.height),
                                     dest.x + dest.width, FLIP_Y(dest.y),
                                     GL_COLOR_BUFFER_BIT, GL_NEAREST);
                if (impl_window->current_paint.flushed_region)
                {
                    cairo_rectangle_int_t flushed_rect;

                    flushed_rect.x = dest.x / window_scale;
                    flushed_rect.y = dest.y / window_scale;
                    flushed_rect.width = (dest.x + dest.width + window_scale - 1) / window_scale - flushed_rect.x;
                    flushed_rect.height = (dest.y + dest.height + window_scale - 1) / window_scale - flushed_rect.y;

                    cairo_region_union_rectangle (impl_window->current_paint.flushed_region,
                                                  &flushed_rect);
                    cairo_region_subtract_rectangle (impl_window->current_paint.need_blend_region,
                                                     &flushed_rect);
                }
            }
        }

        glDisable (GL_SCISSOR_TEST);

        glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);

#undef FLIP_Y

    }
    /* For direct paint of alpha or non-alpha textures we can use texturing */
    else if ((_gdk_gl_flags & GDK_GL_SOFTWARE_DRAW_GL) == 0 &&
             source_type == GL_TEXTURE &&
             direct_window != NULL &&
             direct_window->current_paint.use_gl &&
             trivial_transform &&
             clip_region != NULL)
    {
        int unscaled_window_height;
        GLint texture_width;
        GLint texture_height;
        int i, n_rects, n_quads;
        GdkTexturedQuad *quads;
        cairo_rectangle_int_t clip_rect;

        /* Translate to impl coords */
        cairo_region_translate (clip_region, dx, dy);

        if (alpha_size != 0)
        {
            cairo_region_t *opaque_region, *blend_region;

            opaque_region = cairo_region_copy (clip_region);
            cairo_region_subtract (opaque_region, impl_window->current_paint.flushed_region);
            cairo_region_subtract (opaque_region, impl_window->current_paint.need_blend_region);

            if (!cairo_region_is_empty (opaque_region))
                gdk_gl_texture_from_surface (impl_window->current_paint.surface,
                                             opaque_region);

            blend_region = cairo_region_copy (clip_region);
            cairo_region_intersect (blend_region, impl_window->current_paint.need_blend_region);

            glEnable (GL_BLEND);
            if (!cairo_region_is_empty (blend_region))
                gdk_gl_texture_from_surface (impl_window->current_paint.surface,
                                             blend_region);

            cairo_region_destroy (opaque_region);
            cairo_region_destroy (blend_region);
        }

        glBindTexture (GL_TEXTURE_2D, source);

        glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  &texture_width);
        glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,  &texture_height);

        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glEnable (GL_SCISSOR_TEST);

        gdk_window_get_unscaled_size (impl_window, NULL, &unscaled_window_height);

#define FLIP_Y(_y) (unscaled_window_height - (_y))

        cairo_region_get_extents (clip_region, &clip_rect);

        glScissor (clip_rect.x * window_scale, FLIP_Y ((clip_rect.y + clip_rect.height) * window_scale),
                   clip_rect.width * window_scale, clip_rect.height * window_scale);

        n_quads = 0;
        n_rects = cairo_region_num_rectangles (clip_region);
        quads = g_new (GdkTexturedQuad, n_rects);
        for (i = 0; i < n_rects; i++)
        {
            cairo_rectangle_int_t dest;

            cairo_region_get_rectangle (clip_region, i, &clip_rect);

            clip_rect.x *= window_scale;
            clip_rect.y *= window_scale;
            clip_rect.width *= window_scale;
            clip_rect.height *= window_scale;

            dest.x = dx * window_scale;
            dest.y = dy * window_scale;
            dest.width = width * window_scale / buffer_scale;
            dest.height = height * window_scale / buffer_scale;

            if (gdk_rectangle_intersect (&clip_rect, &dest, &dest))
            {
                int clipped_src_x = x + (dest.x - dx * window_scale);
                int clipped_src_y = y + (height - dest.height - (dest.y - dy * window_scale));
                GdkTexturedQuad quad = {
                    dest.x, FLIP_Y(dest.y),
                    dest.x + dest.width, FLIP_Y(dest.y + dest.height),
                    clipped_src_x / (float)texture_width, (clipped_src_y + dest.height) / (float)texture_height,
                    (clipped_src_x + dest.width) / (float)texture_width, clipped_src_y / (float)texture_height,
                };

                quads[n_quads++] = quad;

                if (impl_window->current_paint.flushed_region)
                {
                    cairo_rectangle_int_t flushed_rect;

                    flushed_rect.x = dest.x / window_scale;
                    flushed_rect.y = dest.y / window_scale;
                    flushed_rect.width = (dest.x + dest.width + window_scale - 1) / window_scale - flushed_rect.x;
                    flushed_rect.height = (dest.y + dest.height + window_scale - 1) / window_scale - flushed_rect.y;

                    cairo_region_union_rectangle (impl_window->current_paint.flushed_region,
                                                  &flushed_rect);
                    cairo_region_subtract_rectangle (impl_window->current_paint.need_blend_region,
                                                     &flushed_rect);
                }
            }
        }

        if (n_quads > 0)
            gdk_gl_texture_quads (paint_context, GL_TEXTURE_2D, n_quads, quads);

        g_free (quads);

        if (alpha_size != 0)
            glDisable (GL_BLEND);

#undef FLIP_Y

    }
    else
    {
        /* Software fallback */

        /* TODO: avoid reading back non-required data due to dest clip */
        image = cairo_surface_create_similar_image (cairo_get_target (cr),
                (alpha_size == 0) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32,
                width, height);

        cairo_surface_set_device_scale (image, buffer_scale, buffer_scale);

        framebuffer = paint_data->tmp_framebuffer;
        glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);

        if (source_type == GL_RENDERBUFFER)
        {
            /* Create a framebuffer with the source renderbuffer and
               make it the current target for reads */
            glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                          GL_RENDERBUFFER_EXT, source);
        }
        else
        {
            glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                       GL_TEXTURE_2D, source, 0);
        }

        glPixelStorei (GL_PACK_ALIGNMENT, 4);
        glPixelStorei (GL_PACK_ROW_LENGTH, cairo_image_surface_get_stride (image) / 4);

        glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                      cairo_image_surface_get_data (image));

        glPixelStorei (GL_PACK_ROW_LENGTH, 0);

        glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);

        cairo_surface_mark_dirty (image);

        /* Invert due to opengl having different origin */
        cairo_scale (cr, 1, -1);
        cairo_translate (cr, 0, -height / buffer_scale);

        cairo_set_source_surface (cr, image, 0, 0);
        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
        cairo_paint (cr);

        cairo_surface_destroy (image);
    }

    if (clip_region)
        cairo_region_destroy (clip_region);

}
Esempio n. 23
0
UInt2 getRenderBufferSize() {
    int width, height;
	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
    return UInt2(width,height);
}
		bool RenderTargetTexture::Init(RenderTarget::Properties* props)
		{
			m_properties = *static_cast<RenderTargetTextureProperties*>(props);
			Clear();

			//	generate frame buffer
			glGenFramebuffers(1, &m_fb);
			//	create color texture
			if (m_color_texture)
				safe_delete(m_color_texture);
			m_color_texture = new Texture2D;
			m_color_texture->Create(m_properties.m_texture_width, m_properties.m_texture_height, ImageModule::IMAGE_FORMAT_RGBA8, 0, false);

			//	if multisample
			//	generate render buffers
			glGenRenderbuffers(1, &m_depth_rb);
			glGenRenderbuffers(1, &m_color_rb);
			//	generate resolve frame buffer
			glGenFramebuffers(1, &m_resolve_fb);

			//	tune resolve frame buffer
			glBindFramebuffer(GL_FRAMEBUFFER, m_resolve_fb);
			//	bind color texture
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture->GetCode(), 0);

			Check();

			//	tune render frame buffer
			glBindFramebuffer(GL_FRAMEBUFFER, m_fb);

			//	tune color render buffer
			glBindRenderbuffer(GL_RENDERBUFFER, m_color_rb);

			int max_samples;
			glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
			//	for csaa some extra staff needed
			// create a regular MSAA color buffer
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_RGBA8, m_color_texture->GetWidth(), m_color_texture->GetHeight());
			// check the number of samples
			glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &max_samples);

			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rb);

			Check();

			//	tune depth render buffer
			glBindRenderbuffer(GL_RENDERBUFFER, m_depth_rb);

			//	for csaa another method should be used
			//	create a regular MSAA depth buffer
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_DEPTH_COMPONENT24, m_color_texture->GetWidth(), m_color_texture->GetHeight());

			//	attach depth buffer to frame buffer
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_rb);

			Check();

			glBindFramebuffer(GL_FRAMEBUFFER, 0);

			return true;
		}
Esempio n. 25
0
	void FrameBuffer::Init(GLint width, GLint height)
	{
		Clear();

		//	generate frame buffer
		glGenFramebuffers(1, &m_fb);
		//	create color texture
		m_color_texture.reset(new Texture2D);
		m_color_texture->Create(width, height, GL_RGBA8, 0);

		//	if multisample
		//	generate render buffers
		glGenRenderbuffers(1, &m_depth_rb);
		glGenRenderbuffers(1, &m_color_rb);
		//	generate resolve frame buffer
		glGenFramebuffers(1, &m_resolve_fb);

		//	tune resolve frame buffer
		glBindFramebuffer(GL_FRAMEBUFFER, m_resolve_fb);
		//	bind color texture
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture->GetCode(), 0);

		Check();

		//	tune render frame buffer
		glBindFramebuffer(GL_FRAMEBUFFER, m_fb);

		//	tune color render buffer
		glBindRenderbuffer(GL_RENDERBUFFER, m_color_rb);

		int max_samples;
		glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
		//	for csaa some extra staff needed
		// create a regular MSAA color buffer
		glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_RGBA8, m_color_texture->GetWidth(), m_color_texture->GetHeight());
		// check the number of samples
		glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &max_samples);

		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rb);

		Check();

		//	tune depth render buffer
		glBindRenderbuffer(GL_RENDERBUFFER, m_depth_rb);

		//	for csaa another method should be used
		//	create a regular MSAA depth buffer
		glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_DEPTH_COMPONENT24, m_color_texture->GetWidth(), m_color_texture->GetHeight());

		//	attach depth buffer to frame buffer
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_rb);

		Check();

		glBindFramebuffer(GL_FRAMEBUFFER, 0);
//
//		//glGenTextures(1, &m_texture);
//		//glBindTexture(GL_TEXTURE_2D, m_texture);
//		//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//		//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
//		//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//		//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//
//		//glBindTexture(GL_TEXTURE_2D, 0);
//
//		//
//		//	create frame buffer
//		//
//		glGenFramebuffers(1, &m_fbo);
//		CHECK_GL_ERROR(L"Can't generate frame buffer");
//		//
//		//	Create render buffer object
//		//
//		glGenRenderbuffers(1, &m_rbo);
//		CHECK_GL_ERROR(L"Can't generate render buffer");
//		//
//		//	Bind created frame buffer
//		//
//		glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
//		CHECK_GL_ERROR(L"Can't bind frame buffer");
//		//
//		//	Bind texture
//		//
////		m_texture_2d->Bind();
//		//
//		//	attach created texture
//		//
//		int code = m_texture_2d->GetCode();
//		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, code, 0);
//		CHECK_GL_ERROR(L"Can't attach texture to the frame buffer");
//		//
//		//	bind created render buffer
//		//
//		glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
//		CHECK_GL_ERROR(L"Can't bind render buffer");
//		//
//		//	init storage parameters
//		//
//		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
//		CHECK_GL_ERROR(L"Can't glRenderBufferstorage");
//		//
//		//	attach depth buffer
//		//
//		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
//		CHECK_GL_ERROR(L"Can't attach depth buffer fo frame buffer");
//		Check();
//
//		//glBindRenderbuffer(GL_RENDERBUFFER, 0);
//		//CHECK_GL_ERROR(L"Can't unibnd render target buffer");
//		glBindFramebuffer(GL_FRAMEBUFFER, 0);
//		CHECK_GL_ERROR(L"Can't unbind frame buffer object");
	}
	void RenderBufferObject::query(GLenum pname, GLint *ret) const
	{
		bind();
		glGetRenderbufferParameteriv(target, pname, ret);
	}
Esempio n. 27
0
void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
{
    makeContextCurrent();
    glGetRenderbufferParameteriv(target, paramName, value);
}
Esempio n. 28
0
void
dumpFramebuffer(JSONWriter &json, Context &context)
{
    json.beginMember("framebuffer");
    json.beginObject();

    GLint boundDrawFbo = 0, boundReadFbo = 0;
    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);
    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);
    if (!boundDrawFbo) {
        dumpDrawableImages(json, context);
    } else if (context.ES) {
        dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER);
    } else {
        GLint colorRb = 0, stencilRb = 0, depthRb = 0;
        GLint draw_buffer0 = GL_NONE;
        glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer0);
        bool multisample = false;

        GLint boundRb = 0;
        glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);

        GLint object_type;
        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &colorRb);
            glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthRb);
            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &stencilRb);
            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glBindRenderbuffer(GL_RENDERBUFFER, boundRb);

        GLuint rbs[3];
        GLint numRbs = 0;
        GLuint fboCopy = 0;

        if (multisample) {
            // glReadPixels doesnt support multisampled buffers so we need
            // to blit the fbo to a temporary one
            fboCopy = downsampledFramebuffer(context,
                                             boundDrawFbo, draw_buffer0,
                                             colorRb, depthRb, stencilRb,
                                             rbs, &numRbs);
        }

        dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER);

        if (multisample) {
            glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
            glDeleteRenderbuffers(numRbs, rbs);
            glDeleteFramebuffers(1, &fboCopy);
        }

        glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);
    }

    json.endObject();
    json.endMember(); // framebuffer
}
Esempio n. 29
0
void RenderingEngine::Initialize()
{
    const unsigned int* faces[] = { Face0, Face1, Face2, Face3, Face4, Face5 };

    // Load the background texture:
    glGenTextures(1, &m_textures.Metal);
    glBindTexture(GL_TEXTURE_2D, m_textures.Metal);
    {
        PVRTextureHeader* header = (PVRTextureHeader*) Metal;
        GLsizei w = header->Width;
        GLsizei h = header->Height;
        const unsigned int* texels = Metal + header->HeaderSize / 4;
        GLenum format = GL_RGB;
        GLenum type = GL_UNSIGNED_SHORT_5_6_5;
        glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, type, texels);
    }
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Load the cubemap texture:
    PVRTextureHeader* header = (PVRTextureHeader*) faces[0];
    const unsigned int* faceData[] = {
        faces[0] + header->HeaderSize / 4,
        faces[1] + header->HeaderSize / 4,
        faces[2] + header->HeaderSize / 4,
        faces[3] + header->HeaderSize / 4,
        faces[4] + header->HeaderSize / 4,
        faces[5] + header->HeaderSize / 4 };

    m_textures.Cubemap = CreateCubemap((void**) faceData, header->Width, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);

    // Create some geometry:
    m_kleinBottle = CreateDrawable(KleinBottle(0.2), VertexFlagsNormals);
    //m_kleinBottle = CreateDrawable(Sphere(1), VertexFlagsNormals);
    m_quad = CreateDrawable(Quad(6, 9), VertexFlagsTexCoords);
    
    // Extract width and height from the color buffer:
    ivec2 screenSize;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_WIDTH, &screenSize.x);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_HEIGHT, &screenSize.y);
    
    // Create the depth buffer:
    glGenRenderbuffers(1, &m_renderbuffers.Depth);
    glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.Depth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
                             screenSize.x, screenSize.y);
    
    // Create the on-screen FBO:
    glGenFramebuffers(1, &m_framebuffers.Screen);
    glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffers.Screen);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, m_renderbuffers.Color);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, m_renderbuffers.Depth);
    glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.Color);
    
    // Create the GLSL programs:
    BuildProgram(SimpleVertexShader, SimpleFragmentShader, m_simple);
    BuildProgram(CubemapVertexShader, CubemapFragmentShader, m_cubemap);
    
    // Set up various GL state:
    glViewport(0, 0, screenSize.x, screenSize.y);
    glEnable(GL_DEPTH_TEST);

    // Set up the transforms:
    const float NearPlane = 5, FarPlane = 50;
    const float Scale = 0.004;
    const float HalfWidth = Scale * screenSize.x / 2;
    const float HalfHeight = Scale * screenSize.y / 2;
    
    mat4 projection = mat4::Frustum(-HalfWidth, HalfWidth, -HalfHeight, HalfHeight,
                                    NearPlane, FarPlane);

    glUseProgram(m_cubemap.Program);
    glUniformMatrix4fv(m_cubemap.Uniforms.Projection, 1, 0, projection.Pointer());
    
    glUseProgram(m_simple.Program);
    glUniformMatrix4fv(m_simple.Uniforms.Projection, 1, 0, projection.Pointer());
}
 void RenderingEngine::Initialize(const vector<ISurface*>& surfaces)
 {
     vector<ISurface*>::const_iterator surface;
     for (surface = surfaces.begin(); surface != surfaces.end(); ++surface) {
         
         // Create the VBO for the vertices.
         vector<float> vertices;
         (*surface)->GenerateVertices(vertices, VertexFlagsNormals|VertexFlagsTexCoords);
         GLuint vertexBuffer;
         glGenBuffers(1, &vertexBuffer);
         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
         glBufferData(GL_ARRAY_BUFFER,
                      vertices.size() * sizeof(vertices[0]),
                      &vertices[0],
                      GL_STATIC_DRAW);
         
         // Create a new VBO for the indices if needed.
         int indexCount = (*surface)->GetTriangleIndexCount();
         GLuint indexBuffer;
         if (!m_drawables.empty() && indexCount == m_drawables[0].IndexCount) {
             indexBuffer = m_drawables[0].IndexBuffer;
         } else {
             vector<GLushort> indices(indexCount);
             (*surface)->GenerateTriangleIndices(indices);
             glGenBuffers(1, &indexBuffer);
             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
             glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                          indexCount * sizeof(GLushort),
                          &indices[0],
                          GL_STATIC_DRAW);
         }
         int lineIndexCount = (*surface)->GetLineIndexCount();
         GLuint lineIndexBuffer;
         vector<GLushort> lineIndices(lineIndexCount);
         (*surface)->GenerateLineIndices(lineIndices);
         glGenBuffers(1, &lineIndexBuffer);
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lineIndexBuffer);
         glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                      lineIndexCount * sizeof(GLushort),
                      &lineIndices[0],
                      GL_STATIC_DRAW);
         
         Drawable drawable = { vertexBuffer, indexBuffer , indexCount};
         m_drawables.push_back(drawable);
     }
     
     // Extract width and height.
     int width, height;
     glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                  GL_RENDERBUFFER_WIDTH, &width);
     glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                  GL_RENDERBUFFER_HEIGHT, &height);
     
     // Create a depth buffer that has the same size as the color buffer.
     glGenRenderbuffers(1, &m_depthRenderbuffer);
     glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
     
     // Create the framebuffer object.
     GLuint framebuffer;
     glGenFramebuffers(1, &framebuffer);
     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               GL_RENDERBUFFER, m_colorRenderbuffer);
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                               GL_RENDERBUFFER, m_depthRenderbuffer);
     glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
     
     // Create the GLSL program.
     GLuint program = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
     glUseProgram(program);
     
     // Extract the handles to attributes and uniforms.
     m_attributes.Position = glGetAttribLocation(program, "Position");
     m_attributes.Normal = glGetAttribLocation(program, "Normal");
     m_attributes.Diffuse = glGetAttribLocation(program, "DiffuseMaterial");
     m_attributes.TextureCoord = glGetAttribLocation(program, "TextureCoord");
     m_uniforms.Projection = glGetUniformLocation(program, "Projection");
     m_uniforms.Modelview = glGetUniformLocation(program, "Modelview");
     m_uniforms.NormalMatrix = glGetUniformLocation(program, "NormalMatrix");
     m_uniforms.LightPosition = glGetUniformLocation(program, "LightPosition");
     m_uniforms.AmbientMaterial = glGetUniformLocation(program, "AmbientMaterial");
     m_uniforms.SpecularMaterial = glGetUniformLocation(program, "SpecularMaterial");
     m_uniforms.Shininess = glGetUniformLocation(program, "Shininess"); 
     
     // Set up some default material parameters.
     glUniform3f(m_uniforms.AmbientMaterial, 0.04f, 0.04f, 0.04f);
     glUniform3f(m_uniforms.SpecularMaterial, 0.5, 0.5, 0.5);
     glUniform1f(m_uniforms.Shininess, 50);
     // Set the active sampler to stage 0.  Not really necessary since the uniform
     // defaults to zero anyway, but good practice.
     glActiveTexture(GL_TEXTURE0);
     glUniform1i(m_uniforms.Sampler, 0);
     // Load the texture.
     glGenTextures(1,&m_gridTexture);
     glBindTexture(GL_TEXTURE_2D, m_gridTexture);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     m_resourceManager = CreateResourceManager();
     m_resourceManager->LoadPngImage("Grid16.png");
     void* pixels = m_resourceManager->GetImageData();
     ivec2 size = m_resourceManager->GetImageSize();
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, 
                  size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
     m_resourceManager->UnloadImage();
     // Initialize various state.
     glEnableVertexAttribArray(m_attributes.Position);
     glEnableVertexAttribArray(m_attributes.Normal);
     glEnableVertexAttribArray(m_attributes.TextureCoord);
     glEnable(GL_DEPTH_TEST);
     
     // Set up transforms.
     m_translation = mat4::Translate(0, 0, -7);
 }