// Unlike normal OpenGL immediate mode, you must specify a texture coord // per vertex or you will get junk... void GLBatch::MultiTexCoord2f( GLuint texture, GLclampf s, GLclampf t ) { // First see if the vertex array buffer has been created... if( uiTextureCoordArray[texture] == 0 ) { // Nope, we need to create it glGenBuffers( 1, &uiTextureCoordArray[texture] ); glBindBuffer( GL_ARRAY_BUFFER, uiTextureCoordArray[texture] ); glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * 2 * nNumVerts, NULL, GL_DYNAMIC_DRAW ); } // Now see if it's already mapped, if not, map it if( pTexCoords[texture] == NULL ) { glBindBuffer( GL_ARRAY_BUFFER, uiTextureCoordArray[texture] ); pTexCoords[texture] = ( M3DVector2f * )glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); } // Ignore if we go past the end, keeps things from blowing up if( nVertsBuilding >= nNumVerts ) { return; } // Copy it in... pTexCoords[texture][nVertsBuilding][0] = s; pTexCoords[texture][nVertsBuilding][1] = t; }
void myGLWidget::updateVertexBufferObject(void *data, int byteSize, int shift) { // locking VBO glBindBuffer(GL_ARRAY_BUFFER, m_vboID); // getting VBO's address void *vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!vbo) { std::cout << "Error: cannot get VBO" << std::endl; glBindBuffer(GL_ARRAY_BUFFER, 0); return; } // updating data memcpy((char*)vbo + shift, data, byteSize); glUnmapBuffer(GL_ARRAY_BUFFER); vbo = 0; // unlocking VBO glBindBuffer(GL_ARRAY_BUFFER, 0); }
void filterGLGetOutputData(cv::Mat& outputPlane) { cv::Size opSize = outputPlane.size(); GLuint outputPixelBuffer = 0; glGenBuffers(1, &outputPixelBuffer); glBindBuffer(GL_PIXEL_PACK_BUFFER, outputPixelBuffer); glBufferData(GL_PIXEL_PACK_BUFFER, planeSize.width * planeSize.height * sizeof(float), 0, GL_DYNAMIC_DRAW); CHECK_GL_ERROR("glBufferData"); glReadPixels(0, 0, planeSize.width, planeSize.height, GL_RED, GL_FLOAT, 0); CHECK_GL_ERROR("glReadPixels"); void *resultAddr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); CHECK_GL_ERROR("glMapBuffer"); memcpy(outputPlane.data, resultAddr, opSize.width * opSize.height * sizeof(float)); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glDeleteBuffers(1, &outputPixelBuffer); }
void GLBatch::Vertex3fv( M3DVector3f vVertex ) { // First see if the vertex array buffer has been created... if( uiVertexArray == 0 ) { // Nope, we need to create it glGenBuffers( 1, &uiVertexArray ); glBindBuffer( GL_ARRAY_BUFFER, uiVertexArray ); glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * 3 * nNumVerts, NULL, GL_DYNAMIC_DRAW ); } // Now see if it's already mapped, if not, map it if( pVerts == NULL ) { glBindBuffer( GL_ARRAY_BUFFER, uiVertexArray ); pVerts = ( M3DVector3f * )glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); } // Ignore if we go past the end, keeps things from blowing up if( nVertsBuilding >= nNumVerts ) { return; } // Copy it in... memcpy( pVerts[nVertsBuilding], vVertex, sizeof( M3DVector3f ) ); nVertsBuilding++; }
void drawNormals(GLuint vbo, int vertNum) { if(vbo == 0) { std::cerr<<"[drawNormals] invalid vbo"<<std::endl; } if(vertNum < 0) { std::cerr<<"[drawNormals] invalid vertNum"<<std::endl; } glBindBuffer(GL_ARRAY_BUFFER,vbo); Vector3* buffer = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); PRINT_GL_ERROR(); Vector3* verts = buffer; Vector3* norms = buffer + vertNum; const float mag = 0.3; for(int i = 0; i < vertNum; i++) { glBegin(GL_LINES); glNormal3f(norms[i].x, norms[i].y, norms[i].z); glVertex3f(verts[i].x, verts[i].y, verts[i].z); glVertex3f(verts[i].x + mag + norms[i].x, verts[i].y + mag + norms[i].y, verts[i].z + mag + norms[i].z); glEnd(); } glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); PRINT_GL_ERROR(); }
static void * bo_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints) { uint8_t *data; CoglBufferBindTarget target; GLenum gl_target; CoglContext *ctx = buffer->context; if ((access & COGL_BUFFER_ACCESS_READ) && !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) return NULL; if ((access & COGL_BUFFER_ACCESS_WRITE) && !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE)) return NULL; target = buffer->last_target; _cogl_buffer_bind_no_create (buffer, target); gl_target = convert_bind_target_to_gl_target (target); /* create an empty store if we don't have one yet. creating the store * lazily allows the user of the CoglBuffer to set a hint before the * store is created. */ if (!buffer->store_created || (hints & COGL_BUFFER_MAP_HINT_DISCARD)) bo_recreate_store (buffer); GE_RET( data, ctx, glMapBuffer (gl_target, _cogl_buffer_access_to_gl_enum (access)) ); if (data) buffer->flags |= COGL_BUFFER_FLAG_MAPPED; _cogl_buffer_unbind (buffer); return data; }
bool GLMeshBuffer::readbackMeshVertexAttribGL(VertexAttribType attrib, U32& count, vector<float>& values) const { U32 vbo = 0; U32 szRead = 0; count = 0; if(attrib == vatPosition) { vbo = m_vboVertex; szRead = m_ctVertices * m_stepVertex; } else if(attrib == vatNormal) { vbo = m_vboNormal; szRead = m_ctVertices * 3; } else if(attrib == vatColor) { vbo = m_vboColor; szRead = m_ctVertices * m_stepColor; } else if(attrib == vatTexCoord) { vbo = m_vboTexCoord; szRead = m_ctVertices * m_stepTexCoord; } else return false; glBindBuffer( GL_ARRAY_BUFFER, vbo); float* lpBuffer = (float *) glMapBuffer( GL_ARRAY_BUFFER, GL_READ_ONLY ); if(lpBuffer == NULL) { return false; } values.assign(lpBuffer, lpBuffer + szRead); glUnmapBuffer( GL_ARRAY_BUFFER ); count = m_ctVertices; //PS::DEBUG::PrintArrayF(&values[0], 180); return true; }
static void surface_init(glw_video_t *gv, glw_video_surface_t *gvs, const glw_video_config_t *gvc) { int i; glGenBuffers(3, gvs->gvs_pbo); glGenTextures(3, gvs->gvs_textures); gvs->gvs_uploaded = 0; for(i = 0; i < 3; i++) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gvs->gvs_pbo[i]); glBufferData(GL_PIXEL_UNPACK_BUFFER, gvc->gvc_width[i] * gvc->gvc_height[i], NULL, GL_STREAM_DRAW); gvs->gvs_pbo_ptr[i] = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); gvs->gvs_data[i] = gvs->gvs_pbo_ptr[i]; } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); TAILQ_INSERT_TAIL(&gv->gv_avail_queue, gvs, gvs_link); }
// Unlike normal OpenGL immediate mode, you must specify a normal per vertex // or you will get junk... void GLBatch::Normal3f(GLfloat x, GLfloat y, GLfloat z) { // First see if the vertex array buffer has been created... if(uiNormalArray == 0) { // Nope, we need to create it glGenBuffers(1, &uiNormalArray); glBindBuffer(GL_ARRAY_BUFFER, uiNormalArray); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nNumVerts, NULL, GL_DYNAMIC_DRAW); } // Now see if it's already mapped, if not, map it if(pNormals == NULL) { glBindBuffer(GL_ARRAY_BUFFER, uiNormalArray); pNormals = (M3DVector3f *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); } // Ignore if we go past the end, keeps things from blowing up if(nVertsBuilding >= nNumVerts) return; // Copy it in... pNormals[nVertsBuilding][0] = x; pNormals[nVertsBuilding][1] = y; pNormals[nVertsBuilding][2] = z; }
WavePrim::WavePrim(const char *name, int size) : Prim(name), _size(size), _time(0.) { glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, _size*_size*sizeof(Vec3), 0, GL_STATIC_DRAW); Vec3 *vertices = (Vec3 *) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); for (int x = 0; x < _size; ++x) for (int y = 0; y < _size; ++y) vertices[y*_size + x] = Vec3(x, 0, y); glUnmapBuffer(GL_ARRAY_BUFFER); //// //_waveProgram.setDebug(true); _waveProgram.addShader( (new Program::Shader(GL_VERTEX_SHADER)) ->addFile("shaders/standard.vs").compile()); _waveProgram.addShader( (new Program::Shader(GL_GEOMETRY_SHADER)) ->addFile("shaders/common.inc") .addFile("shaders/wave.gs").compile()); _waveProgram.addShader( ((new Program::Shader(GL_FRAGMENT_SHADER)) ->addFile("shaders/common.inc") .addFile("shaders/wave.fs").compile())); _waveProgram.link(); }
static void random_ushort_indices(GLsizei offset, GLsizei count, GLuint min_index, GLuint max_index) { GLushort *indices; GLsizei size = offset + count*sizeof(*indices); GLsizei i; glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); assert(glGetError() == GL_NO_ERROR); indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); assert(indices); if (!indices) { return; } assert(offset % sizeof(*indices) == 0); for (i = 0; i < count; ++i) { GLushort *index = indices + offset / sizeof *indices + i; *index = min_index + rand() % (max_index - min_index + 1); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); }
static GLuint CreateGridIndexBuffer(int* count, float vd) { int n = 2*(int)ceil(vd); size_t is_size = (2*(n-1) + 2*(n-1)*n)*sizeof(GLuint); GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER, buf); glBufferData(GL_ARRAY_BUFFER, is_size, NULL, GL_STATIC_DRAW); GLuint* is = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); int i, j, front = 0; for(i = 0; i < n-1; i++) { is[front++] = i*n; for(j = 0; j < n; j++) { is[front++] = i*n+j; is[front++] = (i+1)*n+j; } is[front++] = (i+1)*n+n-1; } *count = front; glUnmapBuffer(GL_ARRAY_BUFFER); return buf; }
// create fixed vertex buffer to store mesh vertices void createMeshPositionVBO(GLuint *id, int w, int h) { createVBO(id, w*h*4*sizeof(float)); glBindBuffer(GL_ARRAY_BUFFER, *id); float *pos = (float *) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!pos) { return; } for(int y=0; y<h; y++) { for(int x=0; x<w; x++) { float u = x / (float) (w-1); float v = y / (float) (h-1); *pos++ = u*2.0f-1.0f; *pos++ = 0.0f; *pos++ = v*2.0f-1.0f; *pos++ = 1.0f; } } glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); }
void Cube::updateVBO(void *data, int byteSize, int offset) { glBindBuffer(GL_ARRAY_BUFFER, mVBOid); //Getting the address of the VBO in the VRAM void* VBOaddress = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if(VBOaddress == NULL) { std::cout << "Error getting the VBO address" << std::endl; glBindBuffer(GL_ARRAY_BUFFER, 0); return; } //Updating data memcpy((char*)VBOaddress + offset, data, byteSize); glUnmapBuffer(GL_ARRAY_BUFFER); VBOaddress = 0; glBindBuffer(GL_ARRAY_BUFFER, 0); }
void COpenGL::Render(SSurface Src) { SSurface Dst; RECT dstRect; unsigned int newFilterScale; GLenum error; if(!initDone) return; //create a new draw surface if the filter scale changes //at least factor 2 so we can display unscaled hi-res images newFilterScale = max(2,max(GetFilterScale(GUI.ScaleHiRes),GetFilterScale(GUI.Scale))); if(newFilterScale!=filterScale) { ChangeDrawSurfaceSize(newFilterScale); } if(pboFunctionsLoaded) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer); Dst.Surface = (unsigned char *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER,GL_READ_WRITE); } else { Dst.Surface = noPboBuffer; } Dst.Height = quadTextureSize; Dst.Width = quadTextureSize; Dst.Pitch = quadTextureSize * 2; RenderMethod (Src, Dst, &dstRect); if(!Settings.AutoDisplayMessages) { WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); } if(pboFunctionsLoaded) glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) { afterRenderHeight = dstRect.bottom; afterRenderWidth = dstRect.right; ChangeRenderSize(0,0); } glBindTexture(GL_TEXTURE_2D,drawTexture); glPixelStorei(GL_UNPACK_ROW_LENGTH, quadTextureSize); glTexSubImage2D (GL_TEXTURE_2D,0,0,0,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,pboFunctionsLoaded?0:noPboBuffer); if(pboFunctionsLoaded) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (shader_type != OGL_SHADER_NONE) { if(shader_type == OGL_SHADER_GLSL) { GLint location; float inputSize[2] = { (float)afterRenderWidth, (float)afterRenderHeight }; RECT windowSize; GetClientRect(hWnd,&windowSize); float outputSize[2] = {(float)(GUI.Stretch?windowSize.right:afterRenderWidth), (float)(GUI.Stretch?windowSize.bottom:afterRenderHeight) }; float textureSize[2] = { (float)quadTextureSize, (float)quadTextureSize }; float frameCnt = (float)++frameCount; location = glGetUniformLocation (shaderProgram, "rubyInputSize"); glUniform2fv (location, 1, inputSize); location = glGetUniformLocation (shaderProgram, "rubyOutputSize"); glUniform2fv (location, 1, outputSize); location = glGetUniformLocation (shaderProgram, "rubyTextureSize"); glUniform2fv (location, 1, textureSize); } else if(shader_type == OGL_SHADER_CG) { xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight }; RECT windowSize, displayRect; GetClientRect(hWnd,&windowSize); xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom }; //Get maximum rect respecting AR setting displayRect=CalculateDisplayRect(windowSize.right,windowSize.bottom,windowSize.right,windowSize.bottom); xySize viewportSize = { (double)(displayRect.right - displayRect.left), (double)(displayRect.bottom - displayRect.top) }; xySize textureSize = { (double)quadTextureSize, (double)quadTextureSize }; cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize); } } if(GUI.BilinearFilter) { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays (GL_QUADS, 0, 4); glFlush(); SwapBuffers(hDC); }
void init() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); GLuint vbo,ebo; GLfloat *vertices; GLushort *indices; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 2*NumPoints*sizeof(GLfloat), NULL, GL_STATIC_DRAW ); vertices = (GLfloat *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (vertices == NULL) { fprintf(stderr, "Unable to map vertex buffer\n"); exit(EXIT_FAILURE); } else{ int i,j; GLfloat dx = (XEnd - XStart) /(NumPoints -1); GLfloat dy = (YEnd - YStart)/(NumPoints -1); GLfloat *tmp = vertices; int n = 0; for (j=0; j<NumYPoints; ++j) { GLfloat y = YStart + j*dy; for (i=0; i<NumXPoints; ++i) { GLfloat x = XStart + i*dx; *tmp++=x; *tmp++=y; } } glUnmapBuffer(GL_ARRAY_BUFFER); glVertexPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(0) ); glEnableClientState(GL_VERTEX_ARRAY); } //建立数据索引 glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); //分配一个额外的重启索引 glBufferData(GL_ELEMENT_ARRAY_BUFFER, NumSrips*(NumPointsPerStrip+1)*sizeof(GLushort), NULL, GL_STATIC_DRAW); indices = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); if (indices==NULL) { fprintf(stderr, "Unable to map index buffer\n"); exit(EXIT_FAILURE); }else{ int i,j; GLushort *index = indices; for (j=0; j<NumSrips; ++j) { GLushort bottomRow = j*NumYPoints; GLushort topRow = bottomRow + NumYPoints; for (i=0; i<NumXPoints; ++i) { *index++ = topRow + i; *index++ = bottomRow + i; } *index++ = RestartIndex; } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } // glPrimitiveRestartIndex(RestartIndex); // glEnable(GL_PRIMITIVE_RESTART); }
void BatchRenderer2D::begin() { glBindBuffer(GL_ARRAY_BUFFER, m_VBO); m_Buffer = (VertexData*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); }
void s_light_t::setup(GLuint program) { const int block_sz = 10; const char *block_name = "sLight"; static const char *s_light_names[block_sz] = { "sLight_num", "sLight_position", "sLight_direction", "sLight_ambient", "sLight_diffuse", "sLight_specular", "sLight_attenuation", "sLight_cutoff", "sLight_exponent", "sLight_mat" }; static GLuint index[block_sz]; static int offset[block_sz]; static GLuint blockIndex; static int blockSize; static bool init = false; static GLuint buffer; if (!init) { init = true; blockIndex = glGetUniformBlockIndex(program, block_name); glGetActiveUniformBlockiv(program, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); glGetUniformIndices(program, block_sz, s_light_names, index); glGetActiveUniformsiv(program, block_sz, index, GL_UNIFORM_OFFSET, offset); char *ch = new char[blockSize]; memset(ch, 0, blockSize); glGenBuffersARB(1, &buffer); glBindBuffer(GL_UNIFORM_BUFFER, buffer); glBufferData(GL_UNIFORM_BUFFER, blockSize, ch, GL_STREAM_DRAW); } glBindBufferBase(GL_UNIFORM_BUFFER, 2, buffer); glUniformBlockBinding(program, blockIndex, 2); char *ptr = (char*)glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); memcpy(ptr + offset[0], &cnt, sizeof(int)); if (!cnt) { glUnmapBuffer(GL_UNIFORM_BUFFER); return; } memcpy(ptr + offset[1], position[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[2], direction[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[3], ambient[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[4], diffuse[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[5], specular[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[6], attenuation[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[7], &cutoff[0], cnt * sizeof(GLfloat)); memcpy(ptr + offset[8], &exponent[0], cnt * sizeof(GLfloat)); memcpy(ptr + offset[9], mat[0].m, cnt * 4 * 4 * sizeof(GLfloat)); glUnmapBuffer(GL_UNIFORM_BUFFER); }
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); if(transparent) { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } glColor3f(1.0f, 1.0f, 1.0f); if(rgba.data_type == TYPE_HALF) { /* 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 */ GLuint texid; glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); if(draw_params.bind_display_space_shader_cb) { draw_params.bind_display_space_shader_cb(); } 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] = 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(); } glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &texid); } else { /* 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(dx, dy); uint8_t *pixels = (uint8_t*)rgba.data_pointer; pixels += 4*y*w; glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glRasterPos2f(0.0f, 0.0f); glPixelZoom(1.0f, 1.0f); } if(transparent) glDisable(GL_BLEND); }
void GLData::reloadColorLookupBuffer(){ // // Resize the buffer, then go through the lookup table and get colours // from layers // glcontext_->makeCurrent(); IF_FAIL("bind failed") = color_lookup_buffer_->bind(); CE(); size_t label_buff_size = (ll_->getLastLabel()+1)*sizeof(float)*4; color_lookup_buffer_->allocate(label_buff_size); CE(); float * color_lookup_buffer = static_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); CE(); // For every label calculate the color auto mix = [this] (const LayerSet & layerset) { std::vector<const Layer *> selected; for(const Layer * layer : layerset) { if(!layer->isVisible()) return QColor(0, 0, 0, 0); for(boost::weak_ptr<Layer> l : ll_->getSelection()){ boost::shared_ptr<Layer> selected_layer = l.lock(); if(layer == selected_layer.get()){ selected.push_back(layer); break; } } } if(selected.size() == 0){ selected.push_back(ll_->getDefaultLayer().get()); } float r = 0, g = 0, b = 0; float weight = 1.0/selected.size(); for(const Layer * l : selected) { QColor col = l->getColor(); r += col.red() * weight; g += col.green() * weight; b += col.blue() * weight; } // Round up r += 0.5; g +=0.5; b +=0.5; return QColor(r, g, b); }; for(uint i = 0; i < ll_->getLastLabel()+1; i++) { const LayerSet &ll = ll_->getLayersForLabel(i); QColor color = mix(ll); color_lookup_buffer[i*4] = color.red()/255.0f; color_lookup_buffer[i*4+1] = color.green()/255.0f; color_lookup_buffer[i*4+2] = color.blue()/255.0f; color_lookup_buffer[i*4+3] = color.alpha()/255.0f; } glUnmapBuffer(GL_ARRAY_BUFFER); color_lookup_buffer_->release(); CE(); //qDebug() << "Color lookup buffer synced"; emit update(); }
void GLInstancingRenderer::writeTransforms() { b3Assert(glGetError() ==GL_NO_ERROR); glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo); glFlush(); b3Assert(glGetError() ==GL_NO_ERROR); char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE); if (orgBase) { int totalNumInstances= 0; for (int k=0;k<m_graphicsInstances.size();k++) { b3GraphicsInstance* gfxObj = m_graphicsInstances[k]; totalNumInstances+=gfxObj->m_numGraphicsInstances; } m_data->m_totalNumInstances = totalNumInstances; for (int k=0;k<m_graphicsInstances.size();k++) { //int k=0; b3GraphicsInstance* gfxObj = m_graphicsInstances[k]; int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); // int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3); char* base = orgBase; float* positions = (float*)(base+m_data->m_maxShapeCapacityInBytes); float* orientations = (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE); float* colors= (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE); float* scaling= (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE); //static int offset=0; //offset++; for (int i=0;i<gfxObj->m_numGraphicsInstances;i++) { int srcIndex=i+gfxObj->m_instanceOffset; positions[srcIndex*4] = m_data->m_instance_positions_ptr[srcIndex*4]; positions[srcIndex*4+1] = m_data->m_instance_positions_ptr[srcIndex*4+1]; positions[srcIndex*4+2] = m_data->m_instance_positions_ptr[srcIndex*4+2]; positions[srcIndex*4+3] = m_data->m_instance_positions_ptr[srcIndex*4+3]; orientations[srcIndex*4]=m_data->m_instance_quaternion_ptr[srcIndex*4]; orientations[srcIndex*4+1]=m_data->m_instance_quaternion_ptr[srcIndex*4+1]; orientations[srcIndex*4+2]=m_data->m_instance_quaternion_ptr[srcIndex*4+2]; orientations[srcIndex*4+3]=m_data->m_instance_quaternion_ptr[srcIndex*4+3]; colors[srcIndex*4]=m_data->m_instance_colors_ptr[srcIndex*4]; colors[srcIndex*4+1]=m_data->m_instance_colors_ptr[srcIndex*4+1]; colors[srcIndex*4+2]=m_data->m_instance_colors_ptr[srcIndex*4+2]; colors[srcIndex*4+3]=m_data->m_instance_colors_ptr[srcIndex*4+3]; scaling[srcIndex*3]=m_data->m_instance_scale_ptr[srcIndex*3]; scaling[srcIndex*3+1]=m_data->m_instance_scale_ptr[srcIndex*3+1]; scaling[srcIndex*3+2]=m_data->m_instance_scale_ptr[srcIndex*3+2]; } } } else { b3Error("ERROR glMapBuffer failed\n"); } b3Assert(glGetError() ==GL_NO_ERROR); glUnmapBuffer( GL_ARRAY_BUFFER); //if this glFinish is removed, the animation is not always working/blocks //@todo: figure out why glFlush(); glBindBuffer(GL_ARRAY_BUFFER, 0);//m_data->m_vbo); b3Assert(glGetError() ==GL_NO_ERROR); }
void* CVertexBufferObject::MapBufferToMemory(int iUsageHint) { if(!bDataUploaded)return NULL; void* ptrRes = glMapBuffer(iBufferType, iUsageHint); return ptrRes; }
void piglit_init(int argc, char **argv) { GLint vertex_data[1] = { GEOM_OUT_VERTS }; bool pass = true; GLuint vs, gs, prog, array_buf, query_result, xfb_buf, generated_query, written_query, vao; GLint vertex_count_loc; const GLint *readback; int i; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gstext); prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, gs); glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); /* Setup inputs */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &array_buf); glBindBuffer(GL_ARRAY_BUFFER, array_buf); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), &vertex_data, GL_STATIC_DRAW); vertex_count_loc = glGetAttribLocation(prog, "vertex_count"); glVertexAttribIPointer(vertex_count_loc, 1, GL_INT, sizeof(GLint), 0); glEnableVertexAttribArray(vertex_count_loc); /* Setup transform feedback buffer */ glGenBuffers(1, &xfb_buf); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, GEOM_OUT_VERTS * sizeof(GLint), NULL, GL_STREAM_READ); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0, GEOM_OUT_VERTS * sizeof(GLint)); /* Setup queries */ glGenQueries(1, &generated_query); glGenQueries(1, &written_query); glBeginQuery(GL_PRIMITIVES_GENERATED, generated_query); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, written_query); /* Do drawing */ glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 1); glEndTransformFeedback(); /* Check query results */ glEndQuery(GL_PRIMITIVES_GENERATED); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glGetQueryObjectuiv(generated_query, GL_QUERY_RESULT, &query_result); if (query_result != GEOM_OUT_VERTS) { printf("GL_PRIMITIVES_GENERATED query failed." " Expected %d, got %d.\n", GEOM_OUT_VERTS, query_result); pass = false; } glGetQueryObjectuiv(written_query, GL_QUERY_RESULT, &query_result); if (query_result != GEOM_OUT_VERTS) { printf("GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query failed." " Expected %d, got %d.\n", GEOM_OUT_VERTS, query_result); pass = false; } /* Check transform feedback data */ readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); for (i = 0; i < GEOM_OUT_VERTS; i++) { if (readback[i] != i) { printf("Incorrect data for vertex %d." " Expected %d, got %d.", i, i, readback[i]); pass = false; } } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); /* Check for errors */ pass = piglit_check_gl_error(GL_NO_ERROR) && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void OGL_StructuredBuffer::BeginUpdate() { glBindBuffer(GL_SHADER_STORAGE_BUFFER, structuredBufferName); mappedStructuredBuffer = (unsigned char*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); }
void Renderer::drawBatchedQuads() { //TODO we can improve the draw performance by insert material switching command before hand. int quadsToDraw = 0; int startQuad = 0; //Upload buffer to VBO if(_numQuads <= 0 || _batchedQuadCommands.empty()) { return; } if (Configuration::getInstance()->supportsShareableVAO()) { //Set VBO data glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // option 1: subdata // glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); // option 2: data // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); // option 3: orphaning + glMapBuffer glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), nullptr, GL_DYNAMIC_DRAW); void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); //Bind VAO GL::bindVAO(_quadVAO); } else { #define kQuadSize sizeof(_quads[0].bl) glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _numQuads , _quads, GL_DYNAMIC_DRAW); GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); // vertices glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); // colors glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); } //Start drawing verties in batch for(const auto& cmd : _batchedQuadCommands) { auto newMaterialID = cmd->getMaterialID(); if(_lastMaterialID != newMaterialID || newMaterialID == QuadCommand::MATERIAL_ID_DO_NOT_BATCH) { //Draw quads if(quadsToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); _drawnBatches++; _drawnVertices += quadsToDraw*6; startQuad += quadsToDraw; quadsToDraw = 0; } //Use new material cmd->useMaterial(); _lastMaterialID = newMaterialID; } quadsToDraw += cmd->getQuadCount(); } //Draw any remaining quad if(quadsToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); _drawnBatches++; _drawnVertices += quadsToDraw*6; } if (Configuration::getInstance()->supportsShareableVAO()) { //Unbind VAO GL::bindVAO(0); } else { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } _batchedQuadCommands.clear(); _numQuads = 0; }
void Render(float alpha, float elapsedtime) { float world[16]; float tmp[16]; float view[16]; float proj[16]; float viewproj[16]; float eye[3] = { 0, 0.3f, 8 }; float look[3] = { 0, 0.3f, 0 }; float up[3] = { 0, 1, 0 }; float clipplanes[2]; float orient[2]; cameraangle.smooth(orient, alpha); GLMatrixRotationAxis(view, orient[1], 1, 0, 0); GLMatrixRotationAxis(tmp, orient[0], 0, 1, 0); GLMatrixMultiply(view, view, tmp); GLVec3Transform(eye, eye, view); GLFitToBox(clipplanes[0], clipplanes[1], eye, look, scenebox); GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f, (float)screenwidth / (float)screenheight, clipplanes[0], clipplanes[1]); GLMatrixLookAtRH(view, eye, look, up); GLMatrixMultiply(viewproj, view, proj); // STEP 1: initialize header pointer buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDisable(GL_DEPTH_TEST); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, headbuffer); init->SetInt("screenWidth", screenwidth); init->Begin(); { screenquad->Draw(); } init->End(); // STEP 2: collect transparent fragments into lists glBindTexture(GL_TEXTURE_2D, white); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer); GLuint* counter = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY); *counter = 0; glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodebuffer); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterbuffer); collect->SetMatrix("matView", view); collect->SetMatrix("matProj", proj); collect->SetInt("screenWidth", screenwidth); collect->Begin(); { GLMatrixIdentity(world); for( int i = 0; i < numobjects; ++i ) { const SceneObject& obj = objects[i]; // scaling * rotation * translation GLMatrixScaling(tmp, obj.scale[0], obj.scale[1], obj.scale[2]); GLMatrixRotationAxis(world, obj.angle, 0, 1, 0); GLMatrixMultiply(world, tmp, world); GLMatrixTranslation(tmp, obj.position[0], obj.position[1], obj.position[2]); GLMatrixMultiply(world, world, tmp); collect->SetMatrix("matWorld", world); collect->SetVector("matAmbient", &obj.color.r); collect->CommitChanges(); if( obj.type == 0 ) box->DrawSubset(0); else if( obj.type == 1 ) dragon->DrawSubset(0); else if( obj.type == 2 ) buddha->DrawSubset(0); } } collect->End(); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); // STEP 3: render glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_SRC_ALPHA); render->SetInt("screenWidth", screenwidth); render->Begin(); { screenquad->Draw(); } render->End(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); #ifdef _DEBUG // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; #endif SwapBuffers(hdc); mousedx = mousedy = 0; }
void * RendererBase::Map(IndexBuffer * resource, MapAccess access) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint) resource->PRIVATE); return glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, MapAccessMap[access]); }
void GOPlate::refreshBuffers() { GameObject::refreshBuffers(); float DX; float DY; if (autoSize && texture) { size = CVector(texture->getWidth(), texture->getHeight()); } if (useArea && texture) { tw = areaSize.x / texture->getWidth(); th = areaSize.y / texture->getHeight(); tx = areaOrigin.x / texture->getWidth(); ty = areaOrigin.y / texture->getHeight(); } else if (texture) { tx = texture->getU(); tw = flipHorizontal ? -texture->getUL() : texture->getUL(); ty = texture->getV(); th = flipVertical ? -texture->getVL() : texture->getVL(); } if (density == 0) { DX = 1.0/(size.x+1); // density (cubs per one) DY = 1.0/(size.y+1); } else { DX = 1.0/density; // density (cubs per one) DY = 1.0/density; } int px = (int)ceil(size.x / (1.0 / DX)); // pieces for x int py = (int)ceil(size.y / (1.0 / DY)); // pieces for y float psx = size.x / (float)px; // pieces step for x float psy = size.y / (float)py; // pieces step for y float tpss = tw / textureZoomS / (float)px; // texture pieces step for s float tpst = th / textureZoomT / (float)py; // texture pieces step for t // for positioning CVector p = getPositioningOffset(getPositioningMode(), size.x, size.y); float offsetX = p.x; float offsetY = p.y; verticesCount = (4 + (px - 1) * 2) * py + (py - 1) * 2; // | one row count | * py + |degenerate vertices| if (verticesCount != oldVerticesCount) { glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(MHVertex) * verticesCount, 0, GL_STATIC_DRAW); } else { glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer); } vertexBuffer = (MHVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!vertexBuffer) { Log::warning("Can't map buffer. GOPlate(\"%s\")", id.c_str()); return; } oldVerticesCount = verticesCount; // calculate normal /*CVector v1(0.0f, 0.0f); CVector v2(1.0f, 0.0f); CVector v3(0.0f, 1.0); CVector n = (v1 - v2).CrossProduct(v2-v3); n.Normalize(); */ CVector n = CVector(0,0,1.0f); int currentVerticleIndex = 0; for (int y = 0; y < py; y++) { for (int x = 0; x < px; x++) { // B D // | / | // A C if (py > 1 && x == 0 && y > 0) { // second degenerate vertex (for each begin except first) //B vertexBuffer[currentVerticleIndex].x = x * psx + offsetX; vertexBuffer[currentVerticleIndex].y = psy + (y * psy) + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst + tpst * y + ty; currentVerticleIndex++; } if (x == 0) { //B vertexBuffer[currentVerticleIndex].x = x * psx + offsetX; vertexBuffer[currentVerticleIndex].y = psy + (y * psy) + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst + tpst * y + ty; currentVerticleIndex++; // A vertexBuffer[currentVerticleIndex].x = x * psx + offsetX; vertexBuffer[currentVerticleIndex].y = y * psy + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst * y + ty; currentVerticleIndex++; } //D vertexBuffer[currentVerticleIndex].x = psx + (x * psx) + offsetX; vertexBuffer[currentVerticleIndex].y = psy + (y * psy) + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss + tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst + tpst * y + ty; currentVerticleIndex++; //C vertexBuffer[currentVerticleIndex].x = psx + (x * psx) + offsetX; vertexBuffer[currentVerticleIndex].y = y * psy + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss + tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst * y + ty; currentVerticleIndex++; if (py > 1 && x == px - 1 && y != py - 1) { // last vertex must copy (degenerate) //C vertexBuffer[currentVerticleIndex].x = psx + (x * psx) + offsetX; vertexBuffer[currentVerticleIndex].y = y * psy + offsetY; vertexBuffer[currentVerticleIndex].z = 0; vertexBuffer[currentVerticleIndex].nx = n.x; vertexBuffer[currentVerticleIndex].ny = n.y; vertexBuffer[currentVerticleIndex].nz = n.z; vertexBuffer[currentVerticleIndex].s = tpss + tpss * x + tx; vertexBuffer[currentVerticleIndex].t = tpst * y + ty; currentVerticleIndex++; } } } if (!glUnmapBuffer(GL_ARRAY_BUFFER) ) { #ifdef MH_DEBUG Log::warning("Unmap buffer failed. GOPlate(\"%s\")", id.c_str()); #endif } }
void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start) { CCASSERT(numberOfQuads>=0 && start>=0, "numberOfQuads and start must be >= 0"); if(!numberOfQuads) return; //Check depth write GLboolean depthWirte; glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWirte); //Turn depth write off if necessary if(depthWirte) { glDepthMask(false); } GL::bindTexture2D(_texture->getName()); if (Configuration::getInstance()->supportsShareableVAO()) { // // Using VBO and VAO // // FIXME:: update is done in draw... perhaps it should be done in a timer if (_dirty) { glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // option 1: subdata // glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); // option 2: data // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); // option 3: orphaning + glMapBuffer glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _capacity, nullptr, GL_DYNAMIC_DRAW); void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(buf, _quads, sizeof(_quads[0])* _totalQuads); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); _dirty = false; } GL::bindVAO(_VAOname); #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); #endif glDrawElements(GL_TRIANGLES, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) ); #if CC_REBIND_INDICES_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif // glBindVertexArray(0); } else { // // Using VBO without VAO // #define kQuadSize sizeof(_quads[0].bl) glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // FIXME:: update is done in draw... perhaps it should be done in a timer if (_dirty) { glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_quads[0]) * _totalQuads , &_quads[0] ); _dirty = false; } GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); // vertices glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); // colors glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glDrawElements(GL_TRIANGLES, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0]))); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,numberOfQuads*6); //Turn depth write on if necessary if(depthWirte) { glDepthMask(true); } CHECK_GL_ERROR_DEBUG(); }
enum piglit_result piglit_display(void) { const char *vs_ssbo_template = "#version 130\n" "#extension GL_ARB_shader_storage_buffer_object : enable\n" "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "varying vec4 vary;" "in vec4 piglit_vertex;\n" "\n" "layout(std140) buffer ssbo {\n" " vec4 v[%d];\n" "};\n" "uniform int i;\n" "\n" "void main() {\n" " gl_Position = piglit_vertex;\n" " vary = v[i];\n" "}\n"; const char *fs_template = "#version 130\n" "#extension GL_ARB_shader_storage_buffer_object : enable\n" "\n" "varying vec4 vary;" "\n" "void main() {\n" " gl_FragColor = vary;\n" "}\n"; const char *vs_template = "#version 130\n" "#extension GL_ARB_shader_storage_buffer_object : enable\n" "in vec4 piglit_vertex;\n" "\n" "void main() {\n" " gl_Position = piglit_vertex;\n" "}\n"; const char *fs_ssbo_template = "#version 130\n" "#extension GL_ARB_shader_storage_buffer_object : enable\n" "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "layout(std140) buffer ssbo {\n" " vec4 v[%d];\n" "};\n" "uniform int i;\n" "\n" "void main() {\n" " gl_FragColor = v[i];\n" "}\n"; char *vs_source, *fs_source; GLint max_size, vec4s, i_location; GLuint vs, fs, prog, bo; GLenum target; float *data; size_t size; bool pass = true; bool link_should_fail; const float green[4] = { 0, 1, 0, 0 }; int test_index; piglit_require_extension("GL_ARB_shader_storage_buffer_object"); piglit_require_extension("GL_ARB_uniform_buffer_object"); glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size); printf("Max shader storage block size: %d\n", max_size); vec4s = max_size / 4 / 4; switch (mode) { case VS: target = GL_VERTEX_SHADER; link_should_fail = false; test_index = vec4s - 1; break; case VS_EXCEED: target = GL_VERTEX_SHADER; link_should_fail = true; vec4s++; test_index = vec4s - 2; break; case FS: target = GL_FRAGMENT_SHADER; link_should_fail = false; test_index = vec4s - 1; break; case FS_EXCEED: target = GL_FRAGMENT_SHADER; link_should_fail = true; vec4s++; test_index = vec4s - 2; break; default: assert(false); target = GL_NONE; link_should_fail = false; } switch (target) { case GL_VERTEX_SHADER: (void)!asprintf(&vs_source, vs_ssbo_template, vec4s); (void)!asprintf(&fs_source, "%s", fs_template); printf("Testing VS with shader storage block vec4 v[%d]\n", vec4s); break; case GL_FRAGMENT_SHADER: (void)!asprintf(&vs_source, "%s", vs_template); (void)!asprintf(&fs_source, fs_ssbo_template, vec4s); printf("Testing FS with shader storage block vec4 v[%d]\n", vec4s); break; default: piglit_report_result(PIGLIT_FAIL); } vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); glLinkProgram(prog); if (link_should_fail) { if (!piglit_link_check_status_quiet(prog)) { printf("Failed to link with shader storage block vec4 " "v[%d]\n", vec4s); piglit_report_result(PIGLIT_PASS); } } else { if (!piglit_link_check_status_quiet(prog)) { fprintf(stderr, "Failed to link with shader storage block vec4 " "v[%d]\n", vec4s); return PIGLIT_FAIL; } } size = vec4s * 4 * sizeof(float); glGenBuffers(1, &bo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, bo); glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_DYNAMIC_DRAW); data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE); memset(data, 0, size); /* The whole shader storage buffer will be zeros, except for the * entry at v[test_index] which will be green. */ data[test_index * 4 + 0] = green[0]; data[test_index * 4 + 1] = green[1]; data[test_index * 4 + 2] = green[2]; data[test_index * 4 + 3] = green[3]; glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); glUseProgram(prog); i_location = glGetUniformLocation(prog, "i"); glUniform1i(i_location, test_index); glShaderStorageBlockBinding(prog, 0, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bo); piglit_draw_rect(-1, -1, 2, 2); pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green); glDeleteProgram(prog); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }