void VAR::uploadToCard(const void* sourcePtr, int dstPtrOffset, size_t size) { void* ptr = (void*)(reinterpret_cast<intptr_t>(_pointer) + dstPtrOffset); switch (VARArea::mode) { case VARArea::VBO_MEMORY: // Don't destroy any existing bindings; this call can // be made at any time and the program might also // use VBO on its own. glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glBindBufferARB(GL_ARRAY_BUFFER_ARB, area->glbuffer); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (GLintptrARB)ptr, size, sourcePtr); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glPopClientAttrib(); break; case VARArea::MAIN_MEMORY: System::memcpy(ptr, sourcePtr, size); break; default: alwaysAssertM(false, "Fell through switch"); } }
//--------------------------------------------------------------------- void GLHardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, bool discardWholeBuffer) { glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId ); // Update the shadow buffer if(mUseShadowBuffer) { void* destData = mpShadowBuffer->lock(offset, length, discardWholeBuffer ? HBL_DISCARD : HBL_NORMAL); memcpy(destData, pSource, length); mpShadowBuffer->unlock(); } if(discardWholeBuffer) { glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, GLHardwareBufferManager::getGLUsage(mUsage)); } // Now update the real buffer glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pSource); }
void ren_vbosquare_item_set_vertex_position(const int id, const int item_idx, const ren_vertex_position_t * data_in, const int nverts) { int size; vbo_t *vb; vb = __get_vbo_from_id(id); size = sizeof(ren_vertex_position_t) * nverts; /* set context to this vbo's buffer */ glBindBufferARB(GL_ARRAY_BUFFER, vb->vtxpos); /* memcpy to subdata of buffer */ glBufferSubDataARB(GL_ARRAY_BUFFER, /* buffer type */ item_idx * size, /* memory location */ size, /* size of data */ data_in); /* data */ /* clean up */ glBindBufferARB(GL_ARRAY_BUFFER, 0); }
void TerrainRenderer::UpdateTriangleColor(const MapCoord x, const MapCoord y,const GameWorldViewer * gwv, const bool update) { unsigned int pos = 2 * width * y + x*2; gl_colors[pos].colors[0].r = gl_colors[pos].colors[0].g = gl_colors[pos].colors[0].b = GetColor(gwv->GetXA(x,y,4), gwv->GetYA(x,y,4)); gl_colors[pos].colors[1].r = gl_colors[pos].colors[1].g = gl_colors[pos].colors[1].b = GetColor(x, y); gl_colors[pos].colors[2].r = gl_colors[pos].colors[2].g = gl_colors[pos].colors[2].b = GetColor(gwv->GetXA(x,y,5), gwv->GetYA(x,y,5)); ++pos; gl_colors[pos].colors[0].r = gl_colors[pos].colors[0].g = gl_colors[pos].colors[0].b = GetColor(x, y); gl_colors[pos].colors[1].r = gl_colors[pos].colors[1].g = gl_colors[pos].colors[1].b = GetColor(gwv->GetXA(x,y,4), gwv->GetYA(x,y,4)); gl_colors[pos].colors[2].r = gl_colors[pos].colors[2].g = gl_colors[pos].colors[2].b = GetColor(gwv->GetXA(x,y,3), gwv->GetYA(x,y,3)); /// Bei Vertexbuffern das die Daten aktualisieren if(update && SETTINGS.video.vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,(pos-1) * 3 * 3 * sizeof(float), 2 * 3 * 3 * sizeof(float), &gl_colors[pos-1]); } }
//--------------------------------------------------------------------- void GLHardwareVertexBuffer::_updateFromShadow(void) { if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate) { const void *srcData = mShadowBuffer->lock( mLockStart, mLockSize, HBL_READ_ONLY); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId); // Update whole buffer if possible, otherwise normal if (mLockStart == 0 && mLockSize == mSizeInBytes) { glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, srcData, GLHardwareBufferManager::getGLUsage(mUsage)); } else { glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, mLockStart, mLockSize, srcData); } mShadowBuffer->unlock(); mShadowUpdated = false; } }
void CVertexBuffer::_uploadData(void *data, U32 offset, U32 size){ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, size, data); checkGLError(); }
// Non-interleaved VBO with 16-bit indices float measureDrawElementsVBO16Performance(Model& model) { bool hasVBO = (strstr((char*)glGetString(GL_EXTENSIONS), "GL_ARB_vertex_buffer_object") != NULL) && (glGenBuffersARB != NULL) && (glBufferDataARB != NULL) && (glDeleteBuffersARB != NULL); if (! hasVBO) { return 0.0; } // Load the vertex arrays // Number of indices const int N = (int)model.cpuIndex.size(); // Number of vertices const int V = (int)model.cpuVertex.size(); GLuint vbo, indexBuffer; glGenBuffersARB(1, &vbo); glGenBuffersARB(1, &indexBuffer); glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); size_t vertexSize = V * sizeof(float) * 3; size_t normalSize = V * sizeof(float) * 3; size_t texCoordSize = V * sizeof(float) * 2; size_t colorSize = V * sizeof(float) * 4; size_t totalSize = vertexSize + normalSize + texCoordSize + colorSize; size_t indexSize = N * sizeof(unsigned short); // Pointers relative to the start of the vbo in video memory // (would interleaving be faster?) GLintptrARB vertexPtr = 0; GLintptrARB normalPtr = vertexSize + vertexPtr; GLintptrARB colorPtr = normalSize + normalPtr; GLintptrARB texCoordPtr = colorSize + colorPtr; GLintptrARB indexPtr = 0; // Upload data glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexBuffer); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexSize, &model.cpuIndex16[0], GL_STATIC_DRAW_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); glBufferDataARB(GL_ARRAY_BUFFER_ARB, totalSize, NULL, GL_STATIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexPtr, vertexSize, &model.cpuVertex[0]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, colorPtr, colorSize, &model.cpuColor[0]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, normalPtr, normalSize, &model.cpuNormal[0]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, texCoordPtr, texCoordSize, &model.cpuTexCoord[0]); configureCameraAndLights(); float k = 0; double t0 = 0, t1 = 0; for (int j = 0; j < frames + 1; ++j) { if (j == 1) { t0 = System::time(); } k += kstep; glClearColor(1.0f, 1.0f, 1.0f, 0.04f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, model.textureID); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_FLOAT, 0, (void*)colorPtr); glTexCoordPointer(2, GL_FLOAT, 0, (void*)texCoordPtr); glNormalPointer(GL_FLOAT, 0, (void*)normalPtr); glVertexPointer(3, GL_FLOAT, 0, (void*)vertexPtr); for (int c = 0; c < count; ++c) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(c - (count - 1) / 2.0, 0, -2); glRotatef(k * ((c & 1) * 2 - 1) + 90, 0, 1, 0); glDrawElements(GL_TRIANGLES, N, GL_UNSIGNED_SHORT, (void*)indexPtr); } glSwapBuffers(); } glFinish(); t1 = System::time(); glPopClientAttrib(); glPopAttrib(); glDeleteBuffersARB(1, &indexBuffer); glDeleteBuffersARB(1, &vbo); return frames / (t1 - t0); }
void LLVertexBuffer::unmapBuffer(S32 type) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (!useVBOs()) { return ; //nothing to unmap } bool updated_all = false ; if (mMappedData && mVertexLocked && type != TYPE_INDEX) { updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating if(sDisableVBOMapping) { stop_glerror(); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData); stop_glerror(); } else { stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); mMappedData = NULL; } mVertexLocked = FALSE ; sMappedCount--; } if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) { if(sDisableVBOMapping) { stop_glerror(); glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData); stop_glerror(); } else { stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); mMappedIndexData = NULL ; } mIndexLocked = FALSE ; sMappedCount--; } if(updated_all) { if(mUsage == GL_STATIC_DRAW_ARB) { //static draw buffers can only be mapped a single time //throw out client data (we won't be using it again) mEmpty = TRUE; mFinal = TRUE; if(sDisableVBOMapping) { freeClientBuffer() ; } } else { mEmpty = FALSE; } } }
void Vbo::bufferSubData( ptrdiff_t offset, size_t size, const void *data ) { bind(); glBufferSubDataARB( mObj->mTarget, offset, size, data ); }
void LLVertexBuffer::unmapBuffer() { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mMappedData || mMappedIndexData) { if (useVBOs() && mLocked) { if (mGLBuffer) { if (mResized) { glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage); } else { if (mEmpty || mDirtyRegions.empty()) { glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); } else { for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) { DirtyRegion& region = *i; glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride); } } } } if (mGLIndices) { if (mResized) { glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage); } else { if (mEmpty || mDirtyRegions.empty()) { glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); } else { for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) { DirtyRegion& region = *i; glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32), region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32)); } } } } mDirtyRegions.clear(); mFilthy = FALSE; mResized = FALSE; if (mUsage == GL_STATIC_DRAW_ARB) { //static draw buffers can only be mapped a single time //throw out client data (we won't be using it again) delete [] mMappedData; delete [] mMappedIndexData; mMappedIndexData = NULL; mMappedData = NULL; mEmpty = TRUE; mFinal = TRUE; } else { mEmpty = FALSE; } mLocked = FALSE; glFlush(); } } }
// -------------------------------------- static void update_vbo(ParticleEmitter* emitter) { // Ensure that drawing order is correct by drawing in order of creation... // First, we draw all those from after the current, going up to the last one. Particle* first = &emitter->particles[emitter->next_particle_index]; Particle* last = &emitter->particles[emitter->max_particles - 1]; if(color_changes(emitter)) { write_colors_for_particles(emitter->color_array, first, last); } if(texture_changes(emitter)) { write_texture_coords_for_particles(emitter->texture_coords_array, first, last, &emitter->texture_info); } uint num_particles_written = write_vertices_for_particles(emitter->vertex_array, first, last, emitter->width, emitter->height); // When we copy the second half of the particles, we want to start writing further on. uint offset = num_particles_written * VERTICES_IN_PARTICLE; // Then go from the first to the current. first = emitter->particles; last = &emitter->particles[emitter->next_particle_index - 1]; if(color_changes(emitter)) { write_colors_for_particles(&emitter->color_array[offset], first, last); } if(texture_changes(emitter)) { write_texture_coords_for_particles(&emitter->texture_coords_array[offset], first, last, &emitter->texture_info); } write_vertices_for_particles(&emitter->vertex_array[offset], first, last, emitter->width, emitter->height); // Upload the data, but only as much as we are actually using. glBindBufferARB(GL_ARRAY_BUFFER_ARB, emitter->vbo_id); if(color_changes(emitter)) { glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, emitter->color_array_offset, sizeof(Color_i) * VERTICES_IN_PARTICLE * emitter->count, emitter->color_array); } if(texture_changes(emitter)) { glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, emitter->texture_coords_array_offset, sizeof(Vertex2d) * VERTICES_IN_PARTICLE * emitter->count, emitter->texture_coords_array); } glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, emitter->vertex_array_offset, sizeof(Vertex2d) * VERTICES_IN_PARTICLE * emitter->count, emitter->vertex_array); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); }
void TerrainRenderer::UpdateBorderTriangleTerrain(const MapCoord x, const MapCoord y,const GameWorldViewer * gwv, const bool update) { unsigned int pos = y * width + x; // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].left_right[i]) { unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset].pos[i ? 0 : 2].x = 0.0f; gl_texcoords[offset].pos[i ? 0 : 2].y = 0.0f; gl_texcoords[offset].pos[1 ].x = 1.0f; gl_texcoords[offset].pos[1 ].y = 0.0f; gl_texcoords[offset].pos[i ? 2 : 0].x = 0.5f; gl_texcoords[offset].pos[i ? 2 : 0].y = 1.0f; ++count_borders; } } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].right_left[i]) { unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset].pos[i ? 2 : 0].x = 0.0f; gl_texcoords[offset].pos[i ? 2 : 0].y = 0.0f; gl_texcoords[offset].pos[1 ].x = 1.0f; gl_texcoords[offset].pos[1 ].y = 0.0f; gl_texcoords[offset].pos[i ? 0 : 2].x = 0.5f; gl_texcoords[offset].pos[i ? 0 : 2].y = 1.0f; ++count_borders; } } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].top_down[i]) { unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset].pos[i ? 2 : 0].x = 0.0f; gl_texcoords[offset].pos[i ? 2 : 0].y = 0.0f; gl_texcoords[offset].pos[1 ].x = 1.0f; gl_texcoords[offset].pos[1 ].y = 0.0f; gl_texcoords[offset].pos[i ? 0 : 2].x = 0.5f; gl_texcoords[offset].pos[i ? 0 : 2].y = 1.0f; ++count_borders; } } /// Bei Vertexbuffern das die Daten aktualisieren if(update && SETTINGS.video.vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,first_offset * 3 * 2 * sizeof(float), count_borders * 3 * 2 * sizeof(float), &gl_texcoords[first_offset]); } }
void TerrainRenderer::UpdateTriangleTerrain(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { const MapNode& node = gwv.GetNode(pt); unsigned int pos = GetTriangleIdx(pt); Triangle& texCoord = gl_texcoords[pos]; if(!TerrainData::IsAnimated(node.t1)) { texCoord[1].x = 0.225f; texCoord[1].y = 0.f; texCoord[2].x = 0.f; //-V807 texCoord[2].y = 0.45f; texCoord[0].x = 0.45f; texCoord[0].y = texCoord[2].y; }else { // We use the full texture as it already consists of 2 triangles // But we need to make sure to only use the correct part of it (texture sizes are powers of 2) // Note: Better would be to use the actual textures, but they are not loaded when this is called during game start Rect texRect = TerrainData::GetPosInTexture(node.t1); int w = texRect.right - texRect.left; int h = texRect.bottom - texRect.top; assert(w > 0 && h > 0); unsigned texW = helpers::roundToNextPowerOfTwo(w); unsigned texH = helpers::roundToNextPowerOfTwo(h); float texScaleW = 1.f / texW; float texScaleH = 1.f / texH; // Tip of the triangle is in the middle in x texCoord[1].x = (w + 1) / 2.f * texScaleW; texCoord[1].y = 0.f; // Bottom of the triangle is in the middle in y texCoord[2].x = 0.f; texCoord[2].y = (h + 1) / 2.f * texScaleH; texCoord[0].x = (w - 1) * texScaleW; texCoord[0].y = texCoord[2].y; } Triangle& texCoord2 = gl_texcoords[pos+1]; if(!TerrainData::IsAnimated(node.t2)) { texCoord2[1].x = 0.235f; texCoord2[1].y = 0.45f; texCoord2[2].x = 0.47f; //-V807 texCoord2[2].y = 0.0f; texCoord2[0].x = 0.0f; texCoord2[0].y = texCoord2[2].y; }else { Rect texRect = TerrainData::GetPosInTexture(node.t1); int w = texRect.right - texRect.left; int h = texRect.bottom - texRect.top; assert(w > 0 && h > 0); unsigned texW = helpers::roundToNextPowerOfTwo(w); unsigned texH = helpers::roundToNextPowerOfTwo(h); float texScaleW = 1.f / texW; float texScaleH = 1.f / texH; // Bottom tip of the triangle is in the middle in x texCoord2[1].x = (w + 1) / 2.f * texScaleW; texCoord2[1].y = (h - 1) * texScaleH; // Top of the triangle is in the middle in y texCoord2[2].x = (w - 1) * texScaleW; texCoord2[2].y = (h + 1) / 2.f * texScaleH; texCoord2[0].x = 0.f; texCoord2[0].y = texCoord2[2].y; } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (pos - 1) * sizeof(Triangle), 2 * sizeof(Triangle), &gl_texcoords[pos - 1]); } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBBufferObject_nglBufferSubDataARB(JNIEnv *env, jclass clazz, jint target, jlong offset, jlong size, jobject data, jint data_position, jlong function_pointer) { const GLvoid *data_address = ((const GLvoid *)(((char *)(*env)->GetDirectBufferAddress(env, data)) + data_position)); glBufferSubDataARBPROC glBufferSubDataARB = (glBufferSubDataARBPROC)((intptr_t)function_pointer); glBufferSubDataARB(target, offset, size, data_address); }
/// Erzeugt die Dreiecke für die Ränder void TerrainRenderer::UpdateBorderTrianglePos(const MapCoord x, const MapCoord y,const GameWorldViewer * gwv, const bool update) { unsigned int pos = y * width + x; // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].left_right[i]) { unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset].pos[i ? 0 : 2].x = GetTerrainX(x, y); gl_vertices[offset].pos[i ? 0 : 2].y = GetTerrainY(x, y); gl_vertices[offset].pos[1 ].x = GetTerrainXAround(x,y,4); gl_vertices[offset].pos[1 ].y = GetTerrainYAround(x,y,4); gl_vertices[offset].pos[i ? 2 : 0].x = GetBX(x, y, i); gl_vertices[offset].pos[i ? 2 : 0].y = GetBY(x, y, i); ++count_borders; } } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].right_left[i]) { unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset].pos[i ? 2 : 0].x = GetTerrainXAround(x,y,4); gl_vertices[offset].pos[i ? 2 : 0].y = GetTerrainYAround(x,y,4); gl_vertices[offset].pos[1 ].x = GetTerrainXAround(x,y,3); gl_vertices[offset].pos[1 ].y = GetTerrainYAround(x,y,3); if(i == 0) { gl_vertices[offset].pos[2].x = GetBX(x, y, 1); gl_vertices[offset].pos[2].y = GetBY(x, y, 1); } else { gl_vertices[offset].pos[0].x = GetBXAround(x, y, 0, 3); gl_vertices[offset].pos[0].y = GetBYAround(x, y, 0, 3); } ++count_borders; } } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].top_down[i]) { unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset].pos[i ? 2 : 0].x = GetTerrainXAround(x,y,5); gl_vertices[offset].pos[i ? 2 : 0].y = GetTerrainYAround(x,y,5); gl_vertices[offset].pos[1 ].x = GetTerrainXAround(x,y,4); gl_vertices[offset].pos[1 ].y = GetTerrainYAround(x,y,4); if(i == 0) { gl_vertices[offset].pos[2].x = GetBX(x,y,i); gl_vertices[offset].pos[2].y = GetBY(x,y,i); } else { //x - i + i * rt, y + i, i gl_vertices[offset].pos[0].x = GetBXAround(x, y, i, 5); gl_vertices[offset].pos[0].y = GetBYAround(x, y, i, 5); } ++count_borders; } } /// Bei Vertexbuffern das die Daten aktualisieren if(update && SETTINGS.video.vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,first_offset * 3 * 2 * sizeof(float), count_borders * 3 * 2 * sizeof(float), &gl_vertices[first_offset]); } }
void TerrainRenderer::UpdateBorderTriangleTerrain(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { unsigned int pos = GetVertexIdx(pt); // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].left_right[i]) { unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset][i ? 0 : 2] = PointF(0.0f, 0.0f); gl_texcoords[offset][1 ] = PointF(1.0f, 0.0f); gl_texcoords[offset][i ? 2 : 0] = PointF(0.5f, 1.0f); ++count_borders; } } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].right_left[i]) { unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset][i ? 2 : 0] = PointF(0.0f, 0.0f); gl_texcoords[offset][1 ] = PointF(1.0f, 0.0f); gl_texcoords[offset][i ? 0 : 2] = PointF(0.5f, 1.0f); ++count_borders; } } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].top_down[i]) { unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_texcoords[offset][i ? 2 : 0] = PointF(0.0f, 0.0f); gl_texcoords[offset][1 ] = PointF(1.0f, 0.0f); gl_texcoords[offset][i ? 0 : 2] = PointF(0.5f, 1.0f); ++count_borders; } } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * sizeof(Triangle), count_borders * sizeof(Triangle), &gl_texcoords[first_offset]); } }
void TerrainRenderer::UpdateBorderTriangleColor(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { unsigned int pos = GetVertexIdx(pt); // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].left_right[i]) continue; unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset][i ? 0 : 2].r = gl_colors[offset][i ? 0 : 2].g = gl_colors[offset][i ? 0 : 2].b = GetColor(pt); //-V807 gl_colors[offset][1 ].r = gl_colors[offset][1 ].g = gl_colors[offset][1 ].b = GetColor(gwv.GetNeighbour(pt, 4)); //-V807 gl_colors[offset][i ? 2 : 0].r = gl_colors[offset][i ? 2 : 0].g = gl_colors[offset][i ? 2 : 0].b = GetBColor(pt, i); //-V807 ++count_borders; } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].right_left[i]) continue; unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset][i ? 2 : 0].r = gl_colors[offset][i ? 2 : 0].g = gl_colors[offset][i ? 2 : 0].b = GetColor(gwv.GetNeighbour(pt, 4)); gl_colors[offset][1 ].r = gl_colors[offset][1 ].g = gl_colors[offset][1 ].b = GetColor(gwv.GetNeighbour(pt, 3)); MapPoint pt2(pt.x + i, pt.y); if(pt2.x >= width) pt2.x -= width; gl_colors[offset][i ? 0 : 2].r = gl_colors[offset][i ? 0 : 2].g = gl_colors[offset][i ? 0 : 2].b = GetBColor(pt2, i ? 0 : 1); ++count_borders; } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].top_down[i]) continue; unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset][i ? 2 : 0].r = gl_colors[offset][i ? 2 : 0].g = gl_colors[offset][i ? 2 : 0].b = GetColor(gwv.GetNeighbour(pt, 5)); gl_colors[offset][1 ].r = gl_colors[offset][1 ].g = gl_colors[offset][1 ].b = GetColor(gwv.GetNeighbour(pt, 4)); if(i == 0) gl_colors[offset][2].r = gl_colors[offset][2].g = gl_colors[offset][2].b = GetBColor(pt, i); //-V807 else gl_colors[offset][0].r = gl_colors[offset][0].g = gl_colors[offset][0].b = GetBColor(gwv.GetNeighbour(pt, 5), i); //-V807 ++count_borders; } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * sizeof(ColorTriangle), count_borders * sizeof(ColorTriangle), &gl_colors[first_offset]); } }
/// Erzeugt die Dreiecke für die Ränder void TerrainRenderer::UpdateBorderTrianglePos(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { unsigned int pos = GetVertexIdx(pt); // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].left_right[i]) continue; unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 0 : 2] = GetTerrain(pt); gl_vertices[offset][1 ] = GetTerrainAround(pt, 4); gl_vertices[offset][i ? 2 : 0] = GetB(pt, i); ++count_borders; } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].right_left[i]) continue; unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 2 : 0] = GetTerrainAround(pt, 4); gl_vertices[offset][1 ] = GetTerrainAround(pt, 3); if(i == 0) gl_vertices[offset][2] = GetB(pt, 1); else gl_vertices[offset][0] = GetBAround(pt, 0, 3); ++count_borders; } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].top_down[i]) continue; unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 2 : 0] = GetTerrainAround(pt, 5); gl_vertices[offset][1 ] = GetTerrainAround(pt, 4); if(i == 0) gl_vertices[offset][2] = GetB(pt, i); else gl_vertices[offset][0] = GetBAround(pt, i, 5); //x - i + i * rt, y + i, i ++count_borders; } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * sizeof(Triangle), count_borders * sizeof(Triangle), &gl_vertices[first_offset]); } }
void ParticleManager::draw() { ofSetColor(255, 255, 255); //motionCVGrayscaleImage->draw(0, 0, ofGetWidth(), ofGetHeight()); //glEnable( GL_BLEND ); // Define the blend mode //glBlendFunc( GL_SRC_ALPHA, GL_ONE ); //ofEnableAlphaBlending(); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear(GL_COLOR_BUFFER_BIT); //glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // bind tex coords glBindBufferARB(GL_ARRAY_BUFFER_ARB, particleVBO[2]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, (NUM_PARTICLES*4)*2*sizeof(float), texcords); glTexCoordPointer(2, GL_FLOAT, 0, 0); // bind color glBindBufferARB(GL_ARRAY_BUFFER_ARB, particleVBO[0]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, (NUM_PARTICLES*4)*4*sizeof(float), colors); glColorPointer(4, GL_FLOAT, 0, 0); // bind vertices [these are quads] glBindBufferARB(GL_ARRAY_BUFFER_ARB, particleVBO[1]); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, (NUM_PARTICLES*4)*3*sizeof(float), posQuads); glVertexPointer(3, GL_FLOAT, 0, 0); // draw the vbo //glDisable(GL_DEPTH_TEST); ofEnableArbTex(); texture.getTextureReference().bind(); glDrawArrays(GL_QUADS, 0, NUM_PARTICLES * 4); texture.getTextureReference().unbind(); //ofDisableAlphaBlending(); ofDisableArbTex(); //glEnable(GL_DEPTH_TEST); //glDisable( GL_BLEND ); //glutSwapBuffers(); glDepthMask(GL_TRUE); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_TEXTURE_2D); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); ofSetColor(100, 100, 100); //ofDrawBitmapString(ofToString(mouseX, 0)+", "+ofToString(mouseY, 0), mouseX + 2, mouseY - 2); /* ofSetColor(255, 255, 255); for(int i = 0; i < NUM_PARTICLES; i++) { if (visibles[i]) { ofSetColor(0, 255, 0); } else { ofSetColor(255, 0, 0); } //ofSetColor(visibles[i] * 250, 255, colors[i] * 250); ofCircle(pos[i].x, pos[i].y, 5); } */ //for (int i = 0; i < NUM_PARTICLES; i++) { // ofDrawBitmapString( ofToString(screenLocs[i * 3], 0) +", "+ofToString(screenLocs[i * 3 + 1], 0), // screenLocs[i * 3] + 2, screenLocs[i * 3 + 1] + 2); //} }
inline void TriangleSet<VertexParam>::glRenderAction( GLContextData& contextData) const { /* Get the context data item: */ DataItem* dataItem=contextData.template retrieveDataItem<DataItem>(this); /* Save the current number of triangles (for parallel creation and rendering): */ size_t numRenderTriangles=numTriangles; /* Render the current amount of triangles: */ GLVertexArrayParts::enable(Vertex::getPartsMask()); if(dataItem->vertexBufferId!=0) { glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferId); #if 0 /* Render all triangle set chunks in streaming mode: */ glVertexPointer(static_cast<const Vertex*>(0)); size_t numTrianglesLeft=numRenderTriangles; for(const Chunk* chPtr=head;numTrianglesLeft>0;chPtr=chPtr->succ) { /* Calculate the number of triangles in this chunk: */ size_t numChunkTriangles=numTrianglesLeft; if(numChunkTriangles>chunkSize) numChunkTriangles=chunkSize; /* Upload the triangles: */ glBufferDataARB(GL_ARRAY_BUFFER_ARB,numChunkTriangles*3*sizeof(Vertex),chPtr->vertices,GL_STREAM_DRAW_ARB); glDrawArrays(GL_TRIANGLES,0,numChunkTriangles*3); numTrianglesLeft-=numChunkTriangles; } #else /* Check if the vertex buffer is current: */ if(dataItem->version!=version||dataItem->numTriangles!=numRenderTriangles) { /* Upload the triangles to the vertex buffer: */ glBufferDataARB(GL_ARRAY_BUFFER_ARB,numRenderTriangles*3*sizeof(Vertex),0,GL_STATIC_DRAW_ARB); GLintptrARB offset=0; size_t numTrianglesLeft=numRenderTriangles; for(const Chunk* chPtr=head;numTrianglesLeft>0;chPtr=chPtr->succ) { /* Calculate the number of triangles in this chunk: */ size_t numChunkTriangles=numTrianglesLeft; if(numChunkTriangles>chunkSize) numChunkTriangles=chunkSize; /* Upload the triangles: */ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,offset,numChunkTriangles*3*sizeof(Vertex),chPtr->vertices); numTrianglesLeft-=numChunkTriangles; offset+=numChunkTriangles*3*sizeof(Vertex); } dataItem->version=version; dataItem->numTriangles=numRenderTriangles; } /* Render the triangles: */ glVertexPointer(static_cast<const Vertex*>(0)); glDrawArrays(GL_TRIANGLES,0,numRenderTriangles*3); #endif glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); } else { for(const Chunk* chPtr=head;numRenderTriangles>0;chPtr=chPtr->succ) { /* Calculate the number of triangles in this chunk: */ size_t numChunkTriangles=numRenderTriangles; if(numChunkTriangles>chunkSize) numChunkTriangles=chunkSize; /* Draw the triangles: */ glVertexPointer(chPtr->vertices); glDrawArrays(GL_TRIANGLES,0,numChunkTriangles*3); numRenderTriangles-=numChunkTriangles; } } GLVertexArrayParts::disable(Vertex::getPartsMask()); }
GLvoid CVBO::draw() { VBOData *vColData = &VBOs[IDT_color]; VBOData *vNormData = &VBOs[IDT_normal]; VBOData *vVertData = &VBOs[IDT_vertex]; bool reupload = (bufferType==BT_STREAM_DRAW || bufferType==BT_DYNAMIC_DRAW); bool col = vColData->id>0; if (col) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vColData->id); if (reupload && reUpload[IDT_color]) { //glBufferDataARB(GL_ARRAY_BUFFER_ARB, vColData->size, vColData->data, bufferType); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vColData->size, vColData->data); } glColorPointer(vColData->elementLength, vColData->dataType, 0, 0); glEnableClientState(GL_COLOR_ARRAY); } bool tex=false; for (GLint i=IDT_texture0; i<=IDT_texture7; i++) { VBOData *vTexData = &VBOs[i]; bool tex_ = vTexData->id>0; if (tex_) { glActiveTextureARB(GL_TEXTURE0_ARB+(i-IDT_texture0)); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures[(i-IDT_texture0)]); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vTexData->id); if (reupload && reUpload[i]) { //glBufferDataARB(GL_ARRAY_BUFFER_ARB, vTexData->size, vTexData->data, bufferType); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vTexData->size, vTexData->data); } glTexCoordPointer(vTexData->elementLength, vTexData->dataType, 0, 0); tex=true; } } bool norm = vNormData->id>0; if (norm && reUpload[IDT_normal]) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vNormData->id); if (reupload) { //glBufferDataARB(GL_ARRAY_BUFFER_ARB, vNormData->size, vNormData->data, bufferType); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vNormData->size, vNormData->data); } glNormalPointer(vNormData->dataType, 0, 0); glEnableClientState(GL_NORMAL_ARRAY); } bool vert = vVertData->id>0; if (vert) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vVertData->id); if (reupload && reUpload[IDT_vertex]) { //glBufferDataARB(GL_ARRAY_BUFFER_ARB, vVertData->size, vVertData->data, bufferType); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vVertData->size, vVertData->data); } glVertexPointer(vVertData->elementLength, vVertData->dataType, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(enumMode, 0, vVertData->elementsCount); } if (norm) { glDisableClientState(GL_NORMAL_ARRAY); } if (tex) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } if (col) { glDisableClientState(GL_COLOR_ARRAY); } if (vert) { glDisableClientState(GL_VERTEX_ARRAY); } for (GLint i=IDT_texture7; i>=IDT_texture0; i--) { if (VBOs[i].id>0) { glActiveTextureARB(GL_TEXTURE0_ARB+(i-IDT_texture0)); glDisable(GL_TEXTURE_2D); } } string eErr=COGLUtils::errorToString(glGetError()); glClientActiveTexture(GL_TEXTURE0); }
inline void MultiPolyline<VertexParam>::glRenderAction( GLContextData& contextData) const { /* Get the context data item: */ DataItem* dataItem=contextData.template retrieveDataItem<DataItem>(this); GLVertexArrayParts::enable(Vertex::getPartsMask()); if(dataItem->vertexBufferIds[0]!=0) { for(unsigned int polylineIndex=0;polylineIndex<numPolylines;++polylineIndex) { const Polyline& p=polylines[polylineIndex]; /* Save the current number of vertices (for parallel creation and rendering): */ size_t numRenderVertices=p.numVertices; glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferIds[polylineIndex]); /* Check if the vertex buffer is current: */ if(dataItem->version!=version||dataItem->numVertices[polylineIndex]!=numRenderVertices) { /* Upload the vertices to the vertex buffer: */ glBufferDataARB(GL_ARRAY_BUFFER_ARB,numRenderVertices*sizeof(Vertex),0,GL_STATIC_DRAW_ARB); GLintptrARB offset=0; size_t numVerticesLeft=numRenderVertices; for(const Chunk* chPtr=p.head;numVerticesLeft>0;chPtr=chPtr->succ) { /* Calculate the number of vertices in this chunk: */ size_t numChunkVertices=numVerticesLeft; if(numChunkVertices>chunkSize) numChunkVertices=chunkSize; /* Upload the vertices: */ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,offset,numChunkVertices*sizeof(Vertex),chPtr->vertices); numVerticesLeft-=numChunkVertices; offset+=numChunkVertices*sizeof(Vertex); } dataItem->numVertices[polylineIndex]=numRenderVertices; } /* Render the poly line: */ glVertexPointer(static_cast<const Vertex*>(0)); glDrawArrays(GL_LINE_STRIP,0,numRenderVertices); } glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); dataItem->version=version; } else { for(unsigned int polylineIndex=0;polylineIndex<numPolylines;++polylineIndex) { const Polyline& p=polylines[polylineIndex]; /* Save the current number of vertices (for parallel creation and rendering): */ size_t numRenderVertices=p.numVertices; for(const Chunk* chPtr=p.head;numRenderVertices>0;chPtr=chPtr->succ) { /* Calculate the number of vertices in this chunk: */ size_t numChunkVertices=numRenderVertices; if(numChunkVertices>chunkSize) numChunkVertices=chunkSize; /* Draw the partial polyline: */ glVertexPointer(chPtr->vertices); glDrawArrays(GL_LINE_STRIP,0,numChunkVertices); numRenderVertices-=numChunkVertices; } } } GLVertexArrayParts::disable(Vertex::getPartsMask()); }
void TerrainRenderer::UpdateBorderTriangleColor(const MapCoord x, const MapCoord y,const GameWorldViewer * gwv, const bool update) { unsigned int pos = y * width + x; // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].left_right[i]) { unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetColor(x, y); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetXA(x,y,4), gwv->GetYA(x,y,4)); gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetBColor(x, y, i); ++count_borders; } } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].right_left[i]) { unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetXA(x,y,4), gwv->GetYA(x,y,4)); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetXA(x,y,3), gwv->GetYA(x,y,3)); gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetBColor(x + i, y, i ? 0 : 1); ++count_borders; } } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].top_down[i]) { unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetXA(x,y,5), gwv->GetYA(x,y,5)); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetXA(x,y,4), gwv->GetYA(x,y,4)); if(i == 0) gl_colors[offset].colors[2].r = gl_colors[offset].colors[2].g = gl_colors[offset].colors[2].b = GetBColor(x, y, i); else gl_colors[offset].colors[0].r = gl_colors[offset].colors[0].g = gl_colors[offset].colors[0].b = GetBColor(gwv->GetXA(x,y,5), gwv->GetYA(x,y,5),i); ++count_borders; } } /// Bei Vertexbuffern das die Daten aktualisieren if(update && SETTINGS.video.vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,first_offset * 3 * 3 * sizeof(float), count_borders * 3 * 3 * sizeof(float), &gl_colors[first_offset]); } }
void VertexBuffer::SetSubData(std::size_t offset, std::size_t size, void const* data) { GLCHECK(glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_id)); GLCHECK(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, size, data)); GLCHECK(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); }
void MeshRenderer :: setMesh(const Mesh& mesh) { m_pbuffer->makeCurrent(); clearVertexBufferObject(); m_mesh = &mesh; GLuint vbo_id = -1, vbo_faces_id = -1; glGenBuffersARB(1, &vbo_id); if (mesh.hasFaces()) glGenBuffersARB(1, &vbo_faces_id); VertexBufferObject& vbo = m_vertex_buffer_object; vbo.nb_faces = 0; vbo.vertex_id = vbo_id; vbo.faces_id = vbo_faces_id; vbo.has_faces = mesh.hasFaces(); vbo.has_color = mesh.hasColors(); vbo.has_texcoords = mesh.hasTexcoords(); vbo.color_offset = mesh.vertices.size()*sizeof(Vec3f); vbo.texture_offset = mesh.vertices.size()*sizeof(Vec3f) + mesh.colors.size() * sizeof(Vec3b); vbo.nb_vertices = mesh.vertices.size(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo.vertex_id); glBufferDataARB(GL_ARRAY_BUFFER_ARB, mesh.colors.size()*sizeof(Vec3b) + mesh.vertices.size()*sizeof(Vec3f) + mesh.texcoords.size()*sizeof(Point2f), // size 0, // null pointer: just allocate memory GL_STATIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, mesh.vertices.size()*sizeof(Vec3f), &mesh.vertices[0]); if (vbo.has_texcoords) glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vbo.texture_offset, mesh.texcoords.size()*sizeof(Point2f), &mesh.texcoords[0]); else if (vbo.has_color) glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vbo.color_offset, mesh.colors.size()*sizeof(Vec3b), &mesh.colors[0]); if (vbo.has_faces) { vbo.nb_faces = mesh.faces.size(); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo.faces_id); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh.faces.size() * 3 * sizeof(GLuint), // size (GLuint*)&mesh.faces[0], GL_STATIC_DRAW_ARB); } if (mesh.texture.data) { glGenTextures( 1, &vbo.texture_id ); glBindTexture( GL_TEXTURE_2D, vbo.texture_id ); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, mesh.texture.cols, mesh.texture.rows, 0, GL_BGR, GL_UNSIGNED_BYTE,mesh.texture.data); } vbo.initialized = true; }
inline void IndexedTriangleSet<VertexParam>::glRenderAction( GLContextData& contextData) const { /* Get the context data item: */ DataItem* dataItem=contextData.template retrieveDataItem<DataItem>(this); /* Save the current number of vertices and triangles (for parallel creation and rendering): */ size_t numRenderTriangles=numTriangles; size_t numRenderVertices=numVertices; /* Render the current amount of triangles: */ GLVertexArrayParts::enable(Vertex::getPartsMask()); glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferId); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,dataItem->indexBufferId); /* Update the vertex and index buffers: */ if(dataItem->version!=version||dataItem->numVertices!=numRenderVertices) { /* Upload the vertex data into the vertex buffer: */ glBufferDataARB(GL_ARRAY_BUFFER_ARB,numRenderVertices*sizeof(Vertex),0,GL_STATIC_DRAW_ARB); GLintptrARB offset=0; size_t verticesToCopy=numRenderVertices; for(const VertexChunk* chPtr=vertexHead;verticesToCopy>0;chPtr=chPtr->succ) { /* Calculate the number of vertices in this chunk: */ size_t numChunkVertices=verticesToCopy; if(numChunkVertices>vertexChunkSize) numChunkVertices=vertexChunkSize; /* Upload the vertices: */ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,offset,numChunkVertices*sizeof(Vertex),chPtr->vertices); verticesToCopy-=numChunkVertices; offset+=numChunkVertices*sizeof(Vertex); } dataItem->numVertices=numRenderVertices; } if(dataItem->version!=version||dataItem->numTriangles!=numRenderTriangles) { /* Upload the index data into the index buffer: */ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,numRenderTriangles*3*sizeof(Index),0,GL_STATIC_DRAW_ARB); GLintptrARB offset=0; size_t trianglesToCopy=numRenderTriangles; for(const IndexChunk* chPtr=indexHead;trianglesToCopy>0;chPtr=chPtr->succ) { /* Calculate the number of triangles in this chunk: */ size_t numChunkTriangles=trianglesToCopy; if(numChunkTriangles>indexChunkSize) numChunkTriangles=indexChunkSize; /* Upload the vertex indices: */ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,offset,numChunkTriangles*3*sizeof(Index),chPtr->indices); trianglesToCopy-=numChunkTriangles; offset+=numChunkTriangles*3*sizeof(Index); } dataItem->numTriangles=numRenderTriangles; } dataItem->version=version; /* Render the triangles: */ glVertexPointer(static_cast<const Vertex*>(0)); // glDrawRangeElements(GL_TRIANGLES,0,GLuint(numRenderVertices)-1,numRenderTriangles*3,GL_UNSIGNED_INT,static_cast<const Index*>(0)); glDrawElements(GL_TRIANGLES,numRenderTriangles*3,GL_UNSIGNED_INT,static_cast<const Index*>(0)); glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); GLVertexArrayParts::disable(Vertex::getPartsMask()); }
void PixelBuffer::setSubData ( unsigned offs , unsigned size , const void * data ) { // TODO Tests if the Buffer is bound. Is this really important ? glBufferSubDataARB ( target_ , offs , size , data ); }
bool OpenGL_Engine::BindVBO(Class* v, int mode, int mode2, int elCnt) { if (v == NULL || v->empty()) return false; if (GL_EXTENSION_VBO) // Vertex Buffer Object supportd { uid id = v->getId(); if (id == 0) { if (mode != 0) { glEnableClientState(mode); } glBindBufferARB(mode2, 0); return false; } bool loaded = false; if(buffer.find(id) != buffer.end()) { loaded = buffer[id].loaded; } OpenGL_Buffer &buf = buffer[id]; if (loaded && buf.size != v->size()) { glDeleteBuffersARB(1, &buf.glid); buf.loaded = false; loaded = false; } if (loaded) { glBindBufferARB(mode2, buf.glid); if (v->changed) { glBufferSubDataARB(mode2, 0, elCnt*sizeof(float)*v->size(), &v->front()); buf.loadCnt++; } if (mode) { glEnableClientState(mode); } buf.lastUsedTime = info.timeInfo.currentTime; buf.usedCnt++; // buf.temp = false; } else { glGenBuffersARB(1, &buf.glid); if(mode > 0) glEnableClientState ( mode ); glBindBufferARB(mode2, buf.glid); GLenum usage = GL_STATIC_DRAW; if (v->changed) { usage = GL_STREAM_DRAW; } glBufferDataARB(mode2, elCnt*sizeof(float)*v->size(), &v->front(), usage); buf.size = v->size(); buf.loaded = true; buf.loadCnt++; if (mode2 == GL_ARRAY_BUFFER_ARB) { buf.kind = OpenGL_Buffer::array; } if (mode2 == GL_ELEMENT_ARRAY_BUFFER_ARB) { buf.kind = OpenGL_Buffer::index; } // buf.temp = false; buf.lastUsedTime = info.timeInfo.currentTime; buf.usedCnt++; } return true; } else { return false; } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBBufferObject_nglBufferSubDataARB(JNIEnv *env, jclass clazz, jint target, jlong offset, jlong size, jlong data, jlong function_pointer) { const GLvoid *data_address = (const GLvoid *)(intptr_t)data; glBufferSubDataARBPROC glBufferSubDataARB = (glBufferSubDataARBPROC)((intptr_t)function_pointer); glBufferSubDataARB(target, offset, size, data_address); }
void VBO::unmap() { glBufferSubDataARB(getTarget(), 0, getSize(), mapped); free(mapped); mapped = 0; }