static bool loadBuffer(GLBuffer &buffer, std::vector<T> data){ if(!buffer.create()) { std::cout<<"Failed to create buffe"<<std::endl; return false; } if(!buffer.bind()){ std::cout<<"Failed to bind buffer"<<std::endl; buffer.release(); return false; } glGetError(); //clear any uncaught errors. Report this? glBufferData(buffer.getType(), sizeof(T) * data.size(), &data[0], GL_STATIC_DRAW); GLenum error = glGetError(); if(error != GL_NO_ERROR){ std::cout<<"Error binding data "<<GLHelper::errorEnumToString(error)<<std::endl; buffer.release(); return false; } return true; }
GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) { GLBuffer* object = Backend::getGPUObject<GLBackend::GLBuffer>(buffer); if (object && (object->_stamp == buffer.getSysmem().getStamp())) { return object; } // need to have a gpu object? if (!object) { object = new GLBuffer(); glGenBuffers(1, &object->_buffer); (void) CHECK_GL_ERROR(); Backend::setGPUObject(buffer, object); } // Now let's update the content of the bo with the sysmem version // TODO: in the future, be smarter about when to actually upload the glBO version based on the data that did change //if () { glBindBuffer(GL_ARRAY_BUFFER, object->_buffer); glBufferData(GL_ARRAY_BUFFER, buffer.getSysmem().getSize(), buffer.getSysmem().readData(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); object->_stamp = buffer.getSysmem().getStamp(); object->setSize((GLuint)buffer.getSysmem().getSize()); //} (void) CHECK_GL_ERROR(); return object; }
bool Lights::loadLight(GLBuffer& buffer, int bufferIdx, const glm::mat4& viewMatrix, size_t idx) { if ( idx < m_idxMap.size() && m_idxMap[idx] != INVALID_INDEX ) { LightInfo& info = m_lights[m_idxMap[idx]]; // compute light position in view coordinates glm::vec3 position = (viewMatrix * glm::vec4(info.position, 1.0)).xyz(); // set buffer data buffer.bind(GL_UNIFORM_BUFFER, bufferIdx); buffer.setSubData(&position, LIGHT_ARRAY_OFFSET + m_idxMap[idx] * LIGHT_ARRAY_STEP + LIGHT_ARRAY_POSITION_OFFSET, 1, bufferIdx); buffer.setSubData(&info.diffuse, LIGHT_ARRAY_OFFSET + m_idxMap[idx] * LIGHT_ARRAY_STEP + LIGHT_ARRAY_DIFFUSE_OFFSET, 1, bufferIdx); buffer.setSubData(&info.specular, LIGHT_ARRAY_OFFSET + m_idxMap[idx] * LIGHT_ARRAY_STEP + LIGHT_ARRAY_SPECULAR_OFFSET, 1, bufferIdx); buffer.setSubData(&info.ambient, LIGHT_ARRAY_OFFSET + m_idxMap[idx] * LIGHT_ARRAY_STEP + LIGHT_ARRAY_AMBIENT_OFFSET, 1, bufferIdx); GLBuffer::unbindBuffers(GL_UNIFORM_BUFFER); return true; } return false; }
// Test mapping with the OES extension. TEST_P(BufferDataTest, MapBufferOES) { if (!IsGLExtensionEnabled("GL_EXT_map_buffer_range")) { // Needed for test validation. return; } std::vector<uint8_t> data(1024); FillVectorWithRandomUBytes(&data); GLBuffer buffer; glBindBuffer(GL_ARRAY_BUFFER, buffer.get()); glBufferData(GL_ARRAY_BUFFER, data.size(), nullptr, GL_STATIC_DRAW); // Validate that other map flags don't work. void *badMapPtr = glMapBufferOES(GL_ARRAY_BUFFER, GL_MAP_READ_BIT); EXPECT_EQ(nullptr, badMapPtr); EXPECT_GL_ERROR(GL_INVALID_ENUM); // Map and write. void *mapPtr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); ASSERT_NE(nullptr, mapPtr); ASSERT_GL_NO_ERROR(); memcpy(mapPtr, data.data(), data.size()); glUnmapBufferOES(GL_ARRAY_BUFFER); // Validate data with EXT_map_buffer_range void *readMapPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, data.size(), GL_MAP_READ_BIT_EXT); ASSERT_NE(nullptr, readMapPtr); ASSERT_GL_NO_ERROR(); std::vector<uint8_t> actualData(data.size()); memcpy(actualData.data(), readMapPtr, data.size()); glUnmapBufferOES(GL_ARRAY_BUFFER); EXPECT_EQ(data, actualData); }
void Lights::load(GLBuffer& buffer, int bufferIdx, const glm::mat4& viewMatrix) { buffer.bind(GL_UNIFORM_BUFFER, bufferIdx); buffer.setSubData(&m_lightCount, LIGHT_COUNT_OFFSET, 1, bufferIdx); for ( size_t i = 0; i < m_lights.size(); ++i ) { LightInfo& info = m_lights[i]; // compute light position in view coordinates glm::vec3 position = (viewMatrix * glm::vec4(info.position, 1.0)).xyz(); // set buffer data buffer.setSubData(&position, LIGHT_ARRAY_OFFSET + i * LIGHT_ARRAY_STEP + LIGHT_ARRAY_POSITION_OFFSET, 1, bufferIdx); buffer.setSubData(&info.diffuse, LIGHT_ARRAY_OFFSET + i * LIGHT_ARRAY_STEP + LIGHT_ARRAY_DIFFUSE_OFFSET, 1, bufferIdx); buffer.setSubData(&info.specular, LIGHT_ARRAY_OFFSET + i * LIGHT_ARRAY_STEP + LIGHT_ARRAY_SPECULAR_OFFSET, 1, bufferIdx); buffer.setSubData(&info.ambient, LIGHT_ARRAY_OFFSET + i * LIGHT_ARRAY_STEP + LIGHT_ARRAY_AMBIENT_OFFSET, 1, bufferIdx); } GLBuffer::unbindBuffers(GL_UNIFORM_BUFFER); }
void GLVertexSource::setVertexBuffer(const GLBuffer& vertex_buffer) { glBindVertexArray(_vao_id); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.id()); glBindVertexArray(0); }
void GLVertexSource::setIndexBuffer(const GLBuffer& index_buffer) { glBindVertexArray(_vao_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.id()); glBindVertexArray(0); }
void P3DImporter::importMeshes( Scene* scene ) { int numMeshes = 0; fread( &m_framesPerSecond, sizeof( int ), 1, m_fh ); fread( &numMeshes, sizeof( int ), 1, m_fh ); for( int i = 0; i < numMeshes; ++i ) { int numAttribs = 0; int id = -1; int parentID = -1; int meshType = -1; fread( &id, sizeof( int ), 1, m_fh ); fread( &parentID, sizeof( int ), 1, m_fh ); fread( &meshType, sizeof( int ), 1, m_fh ); fread( &numAttribs, sizeof( int ), 1, m_fh ); BufferLayout* vtxLayout = new BufferLayout(); BufferLayout* idxLayout = new BufferLayout( 1, BufferLayout::INT ); for( int a = 0; a < numAttribs; ++a ) { int type = 0; fread( &type, sizeof( int ), 1, m_fh ); vtxLayout->pushAttribute( (BufferLayout::DataType )type ); } int numTriBatches = 0; fread( &numTriBatches, sizeof( int ), 1, m_fh ); Mesh* mesh = nullptr; for( int t = 0; t < numTriBatches; ++t ) { int matID = -1; int numIndices = 0; int numVertices = 0; fread( &matID, sizeof( int ), 1, m_fh ); fread( &numIndices, sizeof( int ), 1, m_fh ); fread( &numVertices, sizeof( int ), 1, m_fh ); int vtxBufferSize = vtxLayout->stride() * numVertices; int idxBufferSize = idxLayout->stride() * numIndices; char* vertices = new char[ vtxBufferSize ]; char* indices = new char[ idxBufferSize ]; fread( indices, sizeof( char ), idxBufferSize, m_fh ); fread( vertices, sizeof( char ), vtxBufferSize, m_fh ); GLBuffer* vtxBuffer = new GLBuffer( vertices, numVertices, vtxLayout, GL_ARRAY_BUFFER, GL_TRIANGLES, GL_STATIC_DRAW ); GLBuffer* idxBuffer = new GLBuffer( indices, numIndices, idxLayout, GL_ELEMENT_ARRAY_BUFFER, GL_TRIANGLES, GL_STATIC_DRAW ); std::string matName; if( matID == -1 ) if( meshType == 1 ) { matName = "SkinningMaterial"; //Renderer::getMaterial( matName )->changeShaderProgram( "SkinningShader" ); } else matName = "DiffuseMaterial"; else { matName = m_materials[matID]; if( meshType == 1 ) { Renderer::getMaterial( matName )->changeShaderProgram( "SkinningShader" ); } } if( mesh == nullptr ) { if( meshType == 1 ) mesh = new SkeletalMesh( vtxBuffer, idxBuffer, nullptr, matName, true ); else mesh = new Mesh( vtxBuffer, idxBuffer, nullptr, matName, true ); } else mesh->pushTriangleBatch( vtxBuffer, idxBuffer, nullptr, matName, true ); vtxBuffer->sendToOpenGL(); idxBuffer->sendToOpenGL(); } // create the actor for the mesh Actor* actor = new Actor( m_fileName + toString( i ), mesh ); int numFrames = 0; fread( &numFrames, sizeof( int ), 1, m_fh ); actor->setFrameCount( numFrames ); for( int f = 0; f < numFrames; ++f ) { vec3f translation; quatf rotation; vec3f scale; fread( &translation, sizeof( vec3f ), 1, m_fh ); fread( &rotation, sizeof( quatf ), 1, m_fh ); fread( &scale, sizeof( vec3f ), 1, m_fh ); actor->setFrame( Node::Frame( translation, mat3f::createMatrixFromQuaternion( rotation ), scale ), f ); } actor->setFrameRate( 1 / static_cast<float>(m_framesPerSecond) ); scene->actors.push_back( actor ); m_parentIDToActorIndex[ id ] = scene->actors.size() - 1; if( parentID != -1 ) { auto iter = m_parentIDToActorIndex.find( parentID ); if( iter != m_parentIDToActorIndex.end() ) { scene->actors[ iter->second ]->addChild( actor ); } } // If skeletal mesh if( meshType == 1 ) { SkeletalMesh* skelMesh = reinterpret_cast< SkeletalMesh* >( mesh ); skelMesh->setFrameRate( 1 / static_cast<float>(m_framesPerSecond) ); int numBones = 0; int numFrames = 0; fread( &numBones, sizeof( int ), 1, m_fh ); fread( &numFrames, sizeof( int ), 1, m_fh ); std::vector< mat4f > bone; for( int b = 0; b < numBones; ++b ) { bone.clear(); for( int bf = 0; bf < numFrames; ++bf ) { vec3f translation; quatf rotation; vec3f scale; fread( &translation, sizeof( vec3f ), 1, m_fh ); fread( &rotation, sizeof( quatf ), 1, m_fh ); fread( &scale, sizeof( vec3f ), 1, m_fh ); mat4f boneFrameTM( mat4f::IDENTITY ); boneFrameTM.scale( scale ); boneFrameTM.rotate( rotation ); boneFrameTM.translate( translation ); bone.push_back( boneFrameTM ); } skelMesh->addBone( bone ); } skelMesh->play(); } } }
void Lights::loadCount(GLBuffer& buffer, int bufferIdx) { buffer.bind(GL_UNIFORM_BUFFER, bufferIdx); buffer.setSubData(&m_lightCount, LIGHT_COUNT_OFFSET, 1, bufferIdx); GLBuffer::unbindBuffers(GL_UNIFORM_BUFFER); }
void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length) { GLuint srcId = dstBuffer.getGLBufferId(); glCopyBufferSubData(srcId, getGLBufferId(), srcOffset, dstOffset, length); }
// Checks gl_PointCoord and gl_PointSize // https://www.khronos.org/registry/webgl/sdk/tests/conformance/glsl/variables/gl-pointcoord.html TEST_P(PointSpritesTest, PointCoordAndPointSizeCompliance) { // TODO(jmadill): figure out why this fails if (IsIntel() && GetParam() == ES2_D3D9()) { std::cout << "Test skipped on Intel due to failures." << std::endl; return; } // TODO(jmadill): Investigate potential AMD driver bug. // http://anglebug.com/1643 if (IsAMD() && IsDesktopOpenGL() && IsWindows()) { std::cout << "Test skipped on desktop GL AMD Windows." << std::endl; return; } const std::string fs = R"(precision mediump float; void main() { gl_FragColor = vec4(gl_PointCoord.x, gl_PointCoord.y, 0, 1); })"; const std::string vs = R"(attribute vec4 vPosition; uniform float uPointSize; void main() { gl_PointSize = uPointSize; gl_Position = vPosition; })"; ANGLE_GL_PROGRAM(program, vs, fs); glUseProgram(program); GLfloat pointSizeRange[2] = {}; glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); GLfloat maxPointSize = pointSizeRange[1]; ASSERT_TRUE(maxPointSize >= 1); maxPointSize = floorf(maxPointSize); ASSERT_TRUE((int)maxPointSize % 1 == 0); maxPointSize = std::min(maxPointSize, 64.0f); GLfloat pointWidth = maxPointSize / windowWidth; GLint step = static_cast<GLint>(floorf(maxPointSize / 4)); GLint pointStep = std::max<GLint>(1, step); GLint pointSizeLoc = glGetUniformLocation(program, "uPointSize"); ASSERT_GL_NO_ERROR(); glUniform1f(pointSizeLoc, maxPointSize); ASSERT_GL_NO_ERROR(); GLfloat pixelOffset = ((int)maxPointSize % 2) ? (1.0f / (GLfloat)windowWidth) : 0; GLBuffer vertexObject; glBindBuffer(GL_ARRAY_BUFFER, vertexObject.get()); ASSERT_GL_NO_ERROR(); GLfloat thePoints[] = {-0.5f + pixelOffset, -0.5f + pixelOffset, 0.5f + pixelOffset, -0.5f + pixelOffset, -0.5f + pixelOffset, 0.5f + pixelOffset, 0.5f + pixelOffset, 0.5f + pixelOffset}; glBufferData(GL_ARRAY_BUFFER, sizeof(thePoints), thePoints, GL_STATIC_DRAW); ASSERT_GL_NO_ERROR(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArrays(GL_POINTS, 0, 4); ASSERT_GL_NO_ERROR(); std::string debugText; for (float py = 0; py < 2; ++py) { for (float px = 0; px < 2; ++px) { float pointX = -0.5f + px + pixelOffset; float pointY = -0.5f + py + pixelOffset; for (int yy = 0; yy < maxPointSize; yy += pointStep) { for (int xx = 0; xx < maxPointSize; xx += pointStep) { // formula for s and t from OpenGL ES 2.0 spec section 3.3 float xw = s2p(pointX); float yw = s2p(pointY); float u = xx / maxPointSize * 2 - 1; float v = yy / maxPointSize * 2 - 1; int xf = static_cast<int>(floorf(s2p(pointX + u * pointWidth))); int yf = static_cast<int>(floorf(s2p(pointY + v * pointWidth))); float s = 0.5f + (xf + 0.5f - xw) / maxPointSize; float t = 0.5f + (yf + 0.5f - yw) / maxPointSize; GLubyte color[4] = {static_cast<GLubyte>(floorf(s * 255)), static_cast<GLubyte>(floorf((1 - t) * 255)), 0, 255}; EXPECT_PIXEL_NEAR(xf, yf, color[0], color[1], color[2], color[3], 4); } } } } }
GLfloat maxPointSize = pointSizeRange[1]; ASSERT_TRUE(maxPointSize > 2); glClearColor(0, 0, 0, 1); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); GLint pointSizeLoc = glGetUniformLocation(program, "u_pointSize"); ASSERT_GL_NO_ERROR(); GLfloat pointSize = std::min<GLfloat>(20.0f, maxPointSize); glUniform1f(pointSizeLoc, pointSize); ASSERT_GL_NO_ERROR(); GLBuffer vertexObject; ASSERT_GL_NO_ERROR(); glBindBuffer(GL_ARRAY_BUFFER, vertexObject.get()); ASSERT_GL_NO_ERROR(); GLfloat thePoints[] = {0.0f, 0.0f}; glBufferData(GL_ARRAY_BUFFER, sizeof(thePoints), thePoints, GL_STATIC_DRAW); ASSERT_GL_NO_ERROR(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_POINTS, 0, 1); ASSERT_GL_NO_ERROR();