void CadScene::enableVertexFormat(int attrPos, int attrNormal) { glVertexAttribFormat(attrPos, 3,GL_FLOAT,GL_FALSE,0); glVertexAttribFormat(attrNormal, 3,GL_FLOAT,GL_FALSE,offsetof(CadScene::Vertex,normal)); glVertexAttribBinding(attrPos,0); glVertexAttribBinding(attrNormal,0); glEnableVertexAttribArray(attrPos); glEnableVertexAttribArray(attrNormal); glBindVertexBuffer(0,0,0,sizeof(CadScene::Vertex)); }
bool initVertexArray() { glGenVertexArrays(1, &VertexArrayName); glBindVertexArray(VertexArrayName); glVertexAttribFormat(glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(glf::semantic::attr::POSITION, glf::semantic::buffer::STATIC); glEnableVertexAttribArray(glf::semantic::attr::POSITION); glVertexAttribFormat(glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2)); glVertexAttribBinding(glf::semantic::attr::TEXCOORD, glf::semantic::buffer::STATIC); glEnableVertexAttribArray(glf::semantic::attr::TEXCOORD); glBindVertexArray(0); return glf::checkError("initVertexArray"); }
void PipelineImpl::setVertexState(GlState& state) const { if(state.m_stateHashes.m_vertex == m_hashes.m_vertex) { return; } state.m_stateHashes.m_vertex = m_hashes.m_vertex; for(U i = 0; i < m_in.m_vertex.m_attributeCount; ++i) { const Attribute& attrib = m_cache.m_attribs[i]; ANKI_ASSERT(attrib.m_type); glVertexAttribFormat( i, attrib.m_compCount, attrib.m_type, attrib.m_normalized, m_in.m_vertex.m_attributes[i].m_offset); glVertexAttribBinding(i, m_in.m_vertex.m_attributes[i].m_binding); } for(U i = 0; i < m_in.m_vertex.m_bindingCount; ++i) { ANKI_ASSERT(m_in.m_vertex.m_bindings[i].m_stride > 0); state.m_vertexBindingStrides[i] = m_in.m_vertex.m_bindings[i].m_stride; } if(m_in.m_vertex.m_bindingCount) { state.m_vertBindingCount = m_in.m_vertex.m_bindingCount; state.m_vertBindingsDirty = true; } }
void TopazSample::drawModel(GLenum mode, NvGLSLProgram& program, TopazGLModel& model) { glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, model.getModel()->getCompiledPositionOffset()); glVertexAttribBinding(VERTEX_POS, 0); glEnableVertexAttribArray(VERTEX_POS); program.enable(); program.bindTextureRect("pattern", 0, brushStyle->getTextureId()); glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OBJECT, model.getBufferID("ubo"), 0, sizeof(ObjectData)); glBindVertexBuffer(0, model.getBufferID("vbo"), 0, model.getModel()->getCompiledVertexSize() * sizeof(float)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getBufferID("ibo")); glDrawElements(mode, model.getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES), GL_UNSIGNED_INT, nullptr); if (model.cornerPointsExists()) { glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OBJECT, model.getCornerBufferID("ubo"), 0, sizeof(ObjectData)); glBindVertexBuffer(0, model.getCornerBufferID("vbo"), 0, sizeof(nv::vec3f)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getCornerBufferID("ibo")); glDrawElements(GL_LINE_STRIP, model.getCornerIndices().size(), GL_UNSIGNED_INT, nullptr); } program.disable(); glDisableVertexAttribArray(VERTEX_POS); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexBuffer(0, 0, 0, 0); }
void opengl_bind_vertex_array(const vertex_layout& layout) { auto iter = Stored_vertex_arrays.find(layout); if (iter != Stored_vertex_arrays.end()) { // Found existing vertex array! GL_state.BindVertexArray(iter->second); return; } GR_DEBUG_SCOPE("Create Vertex array"); GLuint vao; glGenVertexArrays(1, &vao); GL_state.BindVertexArray(vao); for (size_t i = 0; i < layout.get_num_vertex_components(); ++i) { auto component = layout.get_vertex_component(i); auto& bind_info = GL_array_binding_data[component->format_type]; auto& attrib_info = GL_vertex_attrib_info[bind_info.attribute_id]; auto attribIndex = attrib_info.attribute_id; glEnableVertexAttribArray(attribIndex); glVertexAttribFormat(attribIndex, bind_info.size, bind_info.data_type, bind_info.normalized, static_cast<GLuint>(component->offset)); // Currently, all vertex data comes from one buffer. glVertexAttribBinding(attribIndex, 0); } Stored_vertex_arrays.insert(std::make_pair(layout, vao)); }
void TransparencyManagerOITClosestArray::drawQuad() { glEnableVertexAttribArray( 0 ); glVertexAttribFormat( 0, 2, GL_FLOAT, GL_FALSE, 0 ); glVertexAttribBinding( 0, 0 ); glBindVertexBuffer( 0, m_fullScreenQuad->getGLId(), 0, 8 ); glDrawArrays( GL_QUADS, 0, 4 ); }
void TopazSample::updateCommandListState() { enum StateObjects { STATE_DRAW, STATE_GEOMETRY_DRAW, STATE_LINES_DRAW, STATES_COUNT }; if (cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation) { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1, 1); glEnableVertexAttribArray(VERTEX_POS); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, models.at(0)->getModel()->getCompiledPositionOffset()); glVertexAttribBinding(VERTEX_POS, 0); glBindVertexBuffer(0, 0, 0, models.at(0)->getModel()->getCompiledVertexSize() * sizeof(float)); if (hwsupport) { glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, 0, 0); glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, 0, 0); glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_OBJECT, 0, 0); glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_SCENE, 0, 0); } shaderPrograms["draw"]->enable(); glStateCaptureNV(cmdlist.stateObjects[STATE_DRAW], GL_TRIANGLES); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjects[STATE_LINES_DRAW], GL_LINES); glDisableVertexAttribArray(VERTEX_POS); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDisable(GL_DEPTH_TEST); } if (hwsupport && ( cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation || cmdlist.state.fboIncarnation != cmdlist.captured.fboIncarnation)) { NVTokenSequence &seq = cmdlist.tokenSequenceList; glCommandListSegmentsNV(cmdlist.tokenCmdList, 1); glListDrawCommandsStatesClientNV(cmdlist.tokenCmdList, 0, (const void**)&seq.offsets[0], &seq.sizes[0], &seq.states[0], &seq.fbos[0], int(seq.states.size())); glCompileCommandListNV(cmdlist.tokenCmdList); } cmdlist.captured = cmdlist.state; }
bool initVertexArray() { GLuint Bindingindex(0); glGenVertexArrays(1, &VertexArrayName); glBindVertexBuffer( Bindingindex, BufferName[buffer::VERTEX], 0, sizeof(glf::vertex_v2fv2f)); glVertexAttribBinding( glf::semantic::attr::POSITION, Bindingindex); glVertexAttribFormat( glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding( glf::semantic::attr::TEXCOORD, Bindingindex); glVertexAttribFormat( glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2)); glEnableVertexAttribArray( glf::semantic::attr::POSITION); glEnableVertexAttribArray( glf::semantic::attr::TEXCOORD); return true; }
bool initVertexArray() { glGenVertexArrays(1, &VertexArrayName); glBindVertexArray(VertexArrayName); glVertexAttribBinding(semantic::attr::POSITION, 0); glVertexAttribFormat(semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(semantic::attr::TEXCOORD, 0); glVertexAttribFormat(semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2)); glEnableVertexAttribArray(semantic::attr::POSITION); glEnableVertexAttribArray(semantic::attr::TEXCOORD); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferName[buffer::ELEMENT]); glBindVertexBuffer(0, BufferName[buffer::VERTEX], 0, sizeof(glf::vertex_v2fv2f)); glBindVertexArray(0); return true; }
/*OpenGL 4.3 version. */ GLuint vaoFactory(GLuint loc_attrib, GLuint normal_attrib, GLuint texcoord_attrib) { GLuint array; glGenVertexArrays(1, &array); // Enable my attributes glEnableVertexAttribArray(loc_attrib); glEnableVertexAttribArray(normal_attrib); glEnableVertexAttribArray(texcoord_attrib); // Set up the formats for my attributes glVertexAttribFormat(loc_attrib, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribFormat(normal_attrib, 3, GL_FLOAT, GL_FALSE, 12); glVertexAttribFormat(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 24); // Make my attributes all use binding 0 glVertexAttribBinding(loc_attrib, 0); glVertexAttribBinding(normal_attrib, 0); glVertexAttribBinding(texcoord_attrib, 0); return array; }
bool initVertexArray() { glGenVertexArrays(pipeline::MAX, &VertexArrayName[0]); glBindVertexArray(VertexArrayName[pipeline::TEXTURE]); glVertexAttribFormat(glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(glf::semantic::attr::POSITION, glf::semantic::buffer::STATIC); glEnableVertexAttribArray(glf::semantic::attr::POSITION); glVertexAttribFormat(glf::semantic::attr::TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2)); glVertexAttribBinding(glf::semantic::attr::TEXCOORD, glf::semantic::buffer::STATIC); glEnableVertexAttribArray(glf::semantic::attr::TEXCOORD); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferName[buffer::ELEMENT]); glBindVertexArray(0); glBindVertexArray(VertexArrayName[pipeline::SPLASH]); glBindVertexArray(0); return true; }
void piglit_init(int argc, char **argv) { GLuint prog, vbo, indirect; piglit_require_GLSL(); piglit_require_extension("GL_ARB_draw_indirect"); prog = piglit_build_simple_program(vs_text, fs_text); glUseProgram(prog); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &indirect); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect); glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirect_data), indirect_data, GL_STATIC_DRAW); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(rect), rect, GL_STATIC_DRAW); /* Enable 2 vertex attrib arrays. */ glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); /* Associate both arrays with binding 0. */ glVertexAttribBinding(0, 0); glVertexAttribBinding(1, 0); glBindVertexArray(0); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); }
bool initVertexArray() { glGenVertexArrays(program::MAX, &VertexArrayName[0]); glBindVertexArray(VertexArrayName[program::TRANSFORM]); glVertexAttribFormat(semantic::attr::POSITION, 4, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(semantic::attr::POSITION, semantic::buffer::STATIC); glEnableVertexAttribArray(semantic::attr::POSITION); glBindVertexArray(0); glBindVertexArray(VertexArrayName[program::FEEDBACK]); glVertexAttribFormat(semantic::attr::POSITION, 4, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(semantic::attr::POSITION, semantic::buffer::STATIC); glEnableVertexAttribArray(semantic::attr::POSITION); glVertexAttribFormat(semantic::attr::COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4)); glVertexAttribBinding(semantic::attr::COLOR, semantic::buffer::STATIC); glEnableVertexAttribArray(semantic::attr::COLOR); glBindVertexArray(0); return this->checkError("initVertexArray"); }
void _004_lua_test::init() { m_shader.init(); m_vao.init(); // init buffer with stuff core::t_vec4f vertices[] = { {-1.0, -1.0, -1.0, 1.0}, { 1.0, -1.0, -1.0, 1.0}, { 0.0, 1.0, -1.0, 1.0} }; m_buffer.init(); m_buffer.data(ATTRIBUTES::POSITION, sizeof(vertices), 0, GL_STATIC_DRAW); void* memory = m_buffer.map(ATTRIBUTES::POSITION, GL_WRITE_ONLY); std::memcpy(memory, vertices, sizeof(vertices)); m_buffer.unmap(ATTRIBUTES::POSITION); // init vao with attrib formats { auto v = m_vao.activate(); // setup attribute format glVertexAttribBinding(ATTRIBUTES::POSITION, BINDINGS::PRIMARY); glVertexAttribFormat(ATTRIBUTES::POSITION, 4, GL_FLOAT, GL_FALSE, 0); // enable attrib array glEnableVertexAttribArray(ATTRIBUTES::POSITION); // bind buffer glBindVertexBuffer(BINDINGS::PRIMARY, m_buffer.get_name(BUFFER::POSITION), 0, sizeof(core::t_vec4f)); // order between the 3 steps does not matter, but every step has to exist. } glClearColor(0.2f, 0.2f, 0.23f, 0.0f); m_lua_state = luaL_newstate(); luaL_openlibs(m_lua_state); std::cout << "start run lua file" << std::endl; luaL_dofile(m_lua_state, "data/script/manipulator.lua"); std::cout << "stop run lua file" << std::endl; lua_close(m_lua_state); }
bool EffectSkybox::initEffect() { program = XRShaderManger::getShaderProgram(XRShaderManger::XR_SHADER_PROGRAM_ENVIRONMENT_MAPPING); #pragma endregion //create and initialize vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); #pragma region setup position attribute { //create and initialize position vbo_pos glGenBuffers(1, &vbo_pos); glBindBuffer(GL_ARRAY_BUFFER, vbo_pos); XRMesh* mesh = (XRMesh*)object->getComponent(XR_COMPONENT_MESH); glBufferStorage(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * mesh->vertexNum, mesh->positions, GL_MAP_WRITE_BIT); //binding vertex attribute with vertex buffer object glVertexAttribBinding(VPOS, 0); glBindVertexBuffer(0, vbo_pos, 0, sizeof(GLfloat) * 3); glVertexAttribFormat(VPOS, 3, GL_FLOAT, GL_FALSE, 0); glEnableVertexAttribArray(VPOS); } #pragma endregion #pragma endregion //by now everything is recorded in the vao //so we will unbind the buffer //and unbind the vao glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); return true; }
void StateSystem::VertexFormatState::applyGL(GLbitfield changedFormat, GLbitfield changedBinding) const { for (GLuint i = 0; i < MAX_VERTEXATTRIBS; i++){ if (!isBitSet(changedFormat,i)) continue; switch(formats[i].mode){ case VERTEXMODE_FLOAT: glVertexAttribFormat(i, formats[i].size, formats[i].type, formats[i].normalized, formats[i].relativeoffset); break; case VERTEXMODE_INT: case VERTEXMODE_UINT: glVertexAttribIFormat(i, formats[i].size, formats[i].type, formats[i].relativeoffset); break; } glVertexAttribBinding(i,formats[i].binding); } for (GLuint i = 0; i < MAX_VERTEXBINDINGS; i++){ if (!isBitSet(changedBinding,i)) continue; glVertexBindingDivisor(i,bindings[i].divisor); glBindVertexBuffer(i,0,0,bindings[i].stride); } }
static FORCEINLINE void VertexAttribBinding(GLuint AttribIndex, GLuint BindingIndex) { glVertexAttribBinding(AttribIndex, BindingIndex); }
int main() { int w, h, c; unsigned char *datum = SOIL_load_image("materials/ok.jpg", &w, &h, &c, SOIL_LOAD_RGBA); GlRunner *runner = new GlRunner(RenderCB, w, h); GLuint VS = runner->BuildShaderProgram("shaders/quad.vert", GL_VERTEX_SHADER); GLuint FS = runner->BuildShaderProgram("shaders/cartoonify.frag", GL_FRAGMENT_SHADER); GLuint PPO = runner->BuildProgramPipeline(); glUseProgramStages(PPO, GL_FRAGMENT_SHADER_BIT, FS); glUseProgramStages(PPO, GL_VERTEX_SHADER_BIT, VS); glProgramUniform1i(FS, glGetUniformLocation(FS, "tColor2D"), 0); GLfloat pos_buf[] = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, }; GLuint posVBO; glGenBuffers(1, &posVBO); glBindBuffer(GL_ARRAY_BUFFER, posVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(pos_buf), pos_buf, GL_STATIC_DRAW); GLfloat texc_buf[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, }; GLuint TexcVBO; glGenBuffers(1, &TexcVBO); glBindBuffer(GL_ARRAY_BUFFER, TexcVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(texc_buf), texc_buf, GL_DYNAMIC_DRAW); GLuint VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(0, 0); glVertexAttribBinding(1, 1); glBindVertexBuffer(0, posVBO, 0, 2*sizeof(GLfloat)); glBindVertexBuffer(1, TexcVBO, 0, 2*sizeof(GLfloat)); GLuint srcTexObj; glGenTextures(1, &srcTexObj); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, srcTexObj); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, datum); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); runner->OnRender(); return 0; }
void TopazSample::initCommandListWeightBlended() { if (!isTokenInternalsInited) { hwsupport = init_NV_command_list(sysGetProcAddress) ? true : false; nvtokenInitInternals(hwsupport, bindlessVboUbo); isTokenInternalsInited = true; } enum States { STATE_CLEAR, STATE_OPAQUE, STATE_TRANSPARENT, STATE_TRASPARENT_LINES, STATE_COMPOSITE, STATES_COUNT }; if (hwsupport) { for (size_t i = 0; i < STATES_COUNT; i++) { glCreateStatesNV(1, &cmdlist.stateObjectsWeightBlended[i]); } glGenBuffers(1, &cmdlist.tokenBufferWeightBlended); glCreateCommandListsNV(1, &cmdlist.tokenCmdListWeightBlended); } NVTokenSequence& seq = cmdlist.tokenSequenceWeightBlended; std::string& stream = cmdlist.tokenDataWeightBlended; size_t offset = 0; { NVTokenUbo ubo; ubo.setBuffer(ubos.sceneUbo, ubos.sceneUbo64, 0, sizeof(SceneData)); ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_FRAGMENT); nvtokenEnqueue(stream, ubo); } // 1. render 'background' into framebuffer 'fbos.scene' { auto& model = models.at(0); setTokenBuffers(model.get(), stream); NVTokenDrawElems draw; draw.setParams(model->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES)); draw.setMode(GL_TRIANGLES); nvtokenEnqueue(stream, draw); pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_OPAQUE]); } // 2. geometry pass OIT for (auto model = models.begin() + 1; model != models.end(); model++) { // like call glClearBufferfv { NVTokenVbo vbo; vbo.setBinding(0); vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0); nvtokenEnqueue(stream, vbo); NVTokenUbo ubo; ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData)); ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); NVTokenDrawArrays draw; draw.setParams(4, 0); draw.setMode(GL_TRIANGLE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_CLEAR]); // 2. geometry pass { setTokenBuffers((*model).get(), stream); NVTokenDrawElems draw; draw.setParams((*model)->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES)); draw.setMode(GL_TRIANGLES); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT]); { setTokenBuffers((*model).get(), stream, true); NVTokenDrawElems draw; draw.setParams((*model)->getCornerIndices().size()); draw.setMode(GL_LINE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES]); // 3. composite pass { NVTokenVbo vbo; vbo.setBinding(0); vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0); nvtokenEnqueue(stream, vbo); NVTokenUbo ubo; ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData)); ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); NVTokenUbo uboWeightBlended; uboWeightBlended.setBuffer(ubos.weightBlendedUbo, ubos.weightBlendedUbo64, 0, sizeof(WeightBlendedData)); uboWeightBlended.setBinding(UBO_OIT, NVTOKEN_STAGE_FRAGMENT); nvtokenEnqueue(stream, uboWeightBlended); NVTokenDrawArrays draw; draw.setParams(4, 0); draw.setMode(GL_TRIANGLE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE]); } if (hwsupport) { glNamedBufferStorageEXT(cmdlist.tokenBufferWeightBlended, cmdlist.tokenDataWeightBlended.size(), &cmdlist.tokenDataWeightBlended.at(0), 0); cmdlist.tokenSequenceListWeightBlended = cmdlist.tokenSequenceWeightBlended; for (size_t i = 0; i < cmdlist.tokenSequenceListWeightBlended.offsets.size(); i++) { cmdlist.tokenSequenceListWeightBlended.offsets[i] += (GLintptr)&cmdlist.tokenDataWeightBlended.at(0); } } glEnableVertexAttribArray(VERTEX_POS); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnable(GL_DEPTH_TEST); // 1. opaque modes { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); shaderPrograms["draw"]->enable(); glBindVertexBuffer(0, 0, 0, 9 * sizeof(float)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_OPAQUE], GL_TRIANGLES); shaderPrograms["draw"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } glDisable(GL_DEPTH_TEST); // like a glClearBufferfv { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); shaderPrograms["clear"]->enable(); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_CLEAR], GL_TRIANGLES); shaderPrograms["clear"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // 2. oit first step { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); // ??? //glEnable(GL_POLYGON_STIPPLE); //glPolygonStipple(brushStyle->brushPattern8to32(QtStyles::DiagCrossPattern).data()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); shaderPrograms["weightBlended"]->enable(); glBindVertexBuffer(0, 0, 0, 9 * sizeof(float)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT], GL_TRIANGLES); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES], GL_LINES); shaderPrograms["weightBlended"]->disable(); // ??? //glDisable(GL_POLYGON_STIPPLE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // 3. oit second step { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glDisable(GL_BLEND); shaderPrograms["weightBlendedFinal"]->enable(); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE], GL_TRIANGLES); shaderPrograms["weightBlendedFinal"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // compile command list NVTokenSequence& sequenceList = cmdlist.tokenSequenceListWeightBlended; glCommandListSegmentsNV(cmdlist.tokenCmdListWeightBlended, 1); glListDrawCommandsStatesClientNV(cmdlist.tokenCmdListWeightBlended, 0, (const void**)&sequenceList.offsets[0], &sequenceList.sizes[0], &sequenceList.states[0], &sequenceList.fbos[0], int(sequenceList.states.size())); glCompileCommandListNV(cmdlist.tokenCmdListWeightBlended); }
static void redraw(struct glwin *win) { struct glwin_thread_state thread_state; glwin_get_thread_state(&thread_state); glwin_make_current(win, g_ctx); lua_State *L = g_L; static bool gl_init_attempted = false; static bool gl_init_result = false; if (!gl_init_attempted) { gl_init_result = glb_glcore_init(3, 3); } if (!gl_init_result) { printf("Failed to initialize OpenGL bindings\n"); exit(-1); return; } glViewport(0, 0, win->width, win->height); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); lua_getglobal(L, "b2l_data"); //1 if (!lua_istable(L, -1)) { lua_pop(L, 1); goto end; } lua_getfield(L, -1, "objects"); //2 lua_getglobal(L, "current_object"); //3 if (!lua_isstring(L, -1)) { lua_pop(L, 3); goto end; } const char *current_object = lua_tostring(L, -1); lua_getfield(L, -2, current_object); //4 if (lua_isnil(L, -1)) { lua_pop(L, 4); goto end; } lua_getfield(L, -1, "type"); //5 if(strcmp(lua_tostring(L, -1), "MESH")) { lua_pop(L, 5); goto end; } lua_getfield(L, -2, "data"); //6 lua_getfield(L, -6, "meshes"); //7 lua_getfield(L, -1, lua_tostring(L, -2)); //8 if (lua_isnil(L, -1)) { lua_pop(L, 8); goto end; } if (!g_gl_state.initialized) init_gl_state(); if (g_gl_state.recompile_shaders) g_gl_state.program_valid = recompile_shaders(); if (!g_gl_state.initialized || !g_gl_state.program_valid) { lua_pop(L, 8); goto end; } g_gl_state.recompile_shaders = false; glUseProgram(g_gl_state.program); glBindVertexArray(g_gl_state.vao); if (g_gl_state.blob_updated) { glBufferData(GL_ARRAY_BUFFER, g_gl_state.blob_size, g_gl_state.blob ,GL_STATIC_DRAW); g_gl_state.blob_updated = false; } lua_getfield(L, -1, "vertex_normal_array_offset"); //9 int vertex_normal_array_offset = lua_tointeger(L, -1); lua_getfield(L, -2, "uv_array_offset"); //10 int uv_array_offset = lua_tointeger(L, -1); lua_getfield(L, -3, "uv_layers"); //11 lua_len(L, -1); //12 int num_uv_layers = lua_tointeger(L, -1); int tangent_array_offset; if (num_uv_layers > 0) { lua_getfield(L, -5, "tangent_array_offset"); tangent_array_offset = lua_tointeger(L, -1); lua_pop(L, 1); } lua_getfield(L, -5, "vertex_co_array_offset"); //13 int vertex_co_array_offset = lua_tointeger(L, -1); lua_getfield(L, -6, "weights_per_vertex"); //14 int weights_per_vertex = lua_tointeger(L, -1); int weights_array_offset; if (weights_per_vertex > 0) { lua_getfield(L, -7, "weights_array_offset"); weights_array_offset = lua_tointeger(L, -1); lua_pop(L, 1); } else { weights_array_offset = -1; } lua_getfield(L, -11, "vertex_groups"); //15 int num_vertex_groups; if (lua_isnil(L, -1)) { num_vertex_groups = 0; } else { lua_len(L, -1); num_vertex_groups = lua_tointeger(L, -1); lua_pop(L, 1); } glBindVertexBuffer(NORMAL, g_gl_state.vbo, vertex_normal_array_offset, sizeof(float) * 3); if (num_uv_layers > 0) { glBindVertexBuffer(UV, g_gl_state.vbo, uv_array_offset, sizeof(float) * 2 * num_uv_layers); glBindVertexBuffer(TANGENT, g_gl_state.vbo, tangent_array_offset, sizeof(float) * 4); } glBindVertexBuffer(POS, g_gl_state.vbo, vertex_co_array_offset, sizeof(float) * 3); if (weights_per_vertex > 0) glBindVertexBuffer(WEIGHTS, g_gl_state.vbo, weights_array_offset, weights_per_vertex * 4); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_gl_state.vbo); if (g_gl_state.normal_index >= 0) { glEnableVertexAttribArray(g_gl_state.normal_index); glVertexAttribFormat(g_gl_state.normal_index, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.normal_index, NORMAL); } if (g_gl_state.uv_index >= 0) { glEnableVertexAttribArray(g_gl_state.uv_index); glVertexAttribFormat(g_gl_state.uv_index, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.uv_index, UV); } if (g_gl_state.pos_index >= 0) { glEnableVertexAttribArray(g_gl_state.pos_index); glVertexAttribFormat(g_gl_state.pos_index, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.pos_index, POS); } int i = 0; for (i = 0; i < 6; i++) { if (g_gl_state.weights_index[i] >= 0 && weights_per_vertex > 0) { glEnableVertexAttribArray(g_gl_state.weights_index[i]); glVertexAttribIFormat(g_gl_state.weights_index[i], 2, GL_SHORT, 4 * i); glVertexAttribBinding(g_gl_state.weights_index[i], WEIGHTS); } } if (num_uv_layers > 0 && g_gl_state.tangent_index >= 0) { glEnableVertexAttribArray(g_gl_state.tangent_index); glVertexAttribFormat(g_gl_state.tangent_index, 4, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.tangent_index, TANGENT); } struct mat4 view; struct mat4 model; struct quaternion next; quaternion_mul(&q_delta, &q_cur, &next); quaternion_to_mat4(&next, &view); view.v[3][3] = 1; mat4_identity(&model); model.v[3][0] = g_offset[0] + g_offset_next[0]; model.v[3][1] = g_offset[1] + g_offset_next[1]; model.v[3][2] = g_offset[2] + g_offset_next[2]; glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "model"), 1, GL_FALSE, (GLfloat *)&model); struct mat4 ident; mat4_identity(&ident); glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "view"), 1, GL_FALSE, (GLfloat *)&view); float zoom = exp(g_log_zoom); float zr = 100; struct mat4 proj; mat4_zero(&proj); proj.v[0][0] = 1.0/zoom; proj.v[1][1] = 1.0*win->width/(zoom*win->height); proj.v[2][2] = 1.0/zr; proj.v[3][3] = 1.0; glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "proj"), 1, GL_FALSE, (GLfloat *)&proj); if (weights_per_vertex > 0) { static int render_count = 0; render_count++; double frame; int frame_start; int frame_end; lua_getglobal(L, "frame_start"); //16 frame_start = lua_tointeger(L, -1); lua_getglobal(L, "frame_end"); //17 frame_end = lua_tointeger(L, -1); lua_getglobal(L, "frame_delta"); //18 frame = frame_start + lua_tonumber(L, -1); int frame_i = floorf(frame); double frame_fract = frame - frame_i; lua_getfield(L, -18, "scenes"); //19 lua_getglobal(L, "current_scene"); //20 lua_getfield(L, -2, lua_tostring(L, -1)); //21 if (!lua_istable(L, -1)) { lua_pop(L, 20); goto end; } lua_getfield(L, -1, "objects"); lua_getfield(L, -1, current_object); lua_getfield(L, -1, "vertex_group_transform_array_offset"); int offset = lua_tointeger(L, -1); lua_pop(L, 9); int stride = sizeof(float) * 4 * 4 * num_vertex_groups; int i; for (i = 0; i < num_vertex_groups; i++) { struct mat4 res; struct mat4 M1; struct mat4 M2; struct mat4 *base = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + frame_i * stride); struct mat4 *next = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + (frame_i + 1) * stride); if (frame_i == (frame_end-1)) { next = (struct mat4 *)(g_gl_state.blob + offset + i * sizeof(float) * 4 * 4 + (frame_start) * stride); } else if (frame_fract == 0) { next = base; } #if USE_SLERP struct mat4 temp; mat4_zero(&temp); temp.v[3][3] = 1; M1 = *base; M2 = *next; spherical_lerp(M1.v[0], M2.v[0], frame_fract, temp.v[0]); spherical_lerp(M1.v[1], M2.v[1], frame_fract, temp.v[1]); spherical_lerp(M1.v[2], M2.v[2], frame_fract, temp.v[2]); mat4_transpose(&temp, &res); float v1[3]; float v2[3]; v1[0] = M1.v[0][3]; v1[1] = M1.v[1][3]; v1[2] = M1.v[2][3]; v2[0] = M2.v[0][3]; v2[1] = M2.v[1][3]; v2[2] = M2.v[2][3]; lerp(v1, v2, frame_fract, res.v[3]); #else mat4_zero(&res); res.v[3][3] = 1; mat4_transpose(base, &M1); mat4_transpose(next, &M2); lerp(M1.v[0], M2.v[0], frame_fract, res.v[0]); lerp(M1.v[1], M2.v[1], frame_fract, res.v[1]); lerp(M1.v[2], M2.v[2], frame_fract, res.v[2]); lerp(M1.v[3], M2.v[3], frame_fract, res.v[3]); #endif glUniformMatrix4fv(g_gl_state.groups_index + i, 1, /*num_vertex_groups, */ GL_FALSE, (GLfloat *)&res); } } lua_getglobal(L, "controls"); //16 int controls = lua_gettop(L); lua_getglobal(L, "materials"); //17 int materials = lua_gettop(L); lua_getfield(L, -10, "index_array_offset"); //18 int index_array_offset = lua_tointeger(L, -1); lua_getfield(L, -11, "submeshes"); //19 lua_len(L, -1); //20 int num_submeshes = lua_tointeger(L, -1); for (i = 0; i < num_submeshes; i++) { lua_rawgeti(L, -2, i + 1); lua_getfield(L, -1, "material_name"); const char *material_name = lua_tostring(L, -1); lua_getfield(L, -2, "triangle_no"); int triangle_no = lua_tointeger(L, -1); lua_getfield(L, -3, "triangle_count"); int triangle_count = lua_tointeger(L, -1); lua_getfield(L, materials, material_name); lua_getfield(L, -1, "params"); lua_pushnil(L); /* first key */ while (lua_next(L, -2)) { int variable = lua_gettop(L); const char *variable_name = lua_tostring(L, variable - 1); int uniform_loc = glGetUniformLocation(g_gl_state.program, variable_name); if (uniform_loc == -1) { lua_pop(L, 1); continue; } lua_getfield(L, variable, "value"); int value = variable + 1; lua_getfield(L, variable, "datatype"); const char *datatype = strdup(lua_tostring(L, -1)); lua_pop(L, 1); if (!strcmp(datatype, "bool")) { int bool_value = lua_toboolean(L, value); glUniform1i(uniform_loc, bool_value); } else if (!strcmp(datatype, "vec3")) { lua_rawgeti(L, value, 1); lua_rawgeti(L, value, 2); lua_rawgeti(L, value, 3); float val[3]; val[0] = (float)lua_tonumber(L, -3); val[1] = (float)lua_tonumber(L, -2); val[2] = (float)lua_tonumber(L, -1); glUniform3fv(uniform_loc, 1, val); lua_pop(L, 3); } else if (!strcmp(datatype, "float")) { float fval = lua_tonumber(L, value); glUniform1f(uniform_loc, fval); } else if (!strcmp(datatype, "sampler2D")) { lua_getfield(L, controls, variable_name); int control = lua_gettop(L); lua_getfield(L, control, "needs_upload"); int needs_upload = lua_toboolean(L, -1); lua_pop(L, 1); if (needs_upload) { int texunit; GdkPixbuf *pbuf; lua_getfield(L, control, "texunit"); texunit = lua_tointeger(L, -1) - 1; lua_pop(L, 1); lua_getfield(L, control, "pbuf"); lua_getfield(L, -1, "_native"); pbuf = (GdkPixbuf *)lua_touserdata(L, -1); lua_pop(L, 2); glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, g_texture_names[texunit]); int width = gdk_pixbuf_get_width(pbuf); int height = gdk_pixbuf_get_height(pbuf); int n_chan = gdk_pixbuf_get_n_channels(pbuf); glPixelStorei(GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_rowstride(pbuf)/ n_chan); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, /* level */ n_chan > 3 ? GL_RGBA : GL_RGB, width, height, 0, /* border */ n_chan > 3 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pbuf)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); glUniform1i(uniform_loc, texunit); lua_pushboolean(L, 0); lua_setfield(L, control, "needs_upload"); } lua_pop(L, 1); } free((void *)datatype); lua_pop(L, 2); } //while (lua_next(L, -2) != 0) glDrawElements(GL_TRIANGLES, 3 * triangle_count, GL_UNSIGNED_SHORT, (void *)((int64_t)index_array_offset) + 3 * 2 * triangle_no); lua_pop(L, 6); } lua_pop(L, 20); end: { GLenum err = glGetError(); if (err) printf("render_scene GL error = %d\n", err); } glwin_swap_buffers(g_win); glwin_set_thread_state(&thread_state); g_need_redraw = false; return; }
void TopazSample::renderStandartWeightedBlendedOIT() { glEnable(GL_DEPTH_TEST); glDisable(GL_POLYGON_OFFSET_FILL); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_SCENE, ubos.sceneUbo); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_IDENTITY, ubos.identityUbo); glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); drawModel(GL_TRIANGLES, *shaderPrograms["draw"], *models.at(0)); glBindFramebuffer(GL_FRAMEBUFFER, 0); /* first pass oit */ glDisable(GL_DEPTH_TEST); // TODO : change on transparent list of models for (auto model = models.begin() + 1; model != models.end(); model++) { /* geometry pass */ { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); GLfloat clearColorZero[4] = { 0.0f }; GLfloat clearColorOne[4] = { 1.0f }; glClearBufferfv(GL_COLOR, 0, clearColorZero); glClearBufferfv(GL_COLOR, 1, clearColorOne); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData); objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData); drawModel(GL_TRIANGLES, *shaderPrograms["weightBlended"], **model); glDisable(GL_BLEND); CHECK_GL_ERROR(); } /* composition pass */ { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OIT, ubos.weightBlendedUbo, 0, sizeof(WeightBlendedData)); // check uniform buffer offset { const char* uniformNames[] = { "weightBlendedData.background", "weightBlendedData.colorTex0", "weightBlendedData.colorTex1" }; std::unique_ptr<GLint> parameters(new GLint[3]); std::unique_ptr<GLuint> uniformIndices(new GLuint[3]); glGetUniformIndices(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformNames, uniformIndices.get()); glGetActiveUniformsiv(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformIndices.get(), GL_UNIFORM_OFFSET, parameters.get()); GLint* offset = parameters.get(); } { shaderPrograms["weightBlendedFinal"]->enable(); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnableVertexAttribArray(VERTEX_POS); glBindVertexBuffer(0, fullScreenRectangle.vboFullScreen, 0, sizeof(nv::vec3f)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); shaderPrograms["weightBlendedFinal"]->disable(); } CHECK_GL_ERROR(); } } }
static void initVertexFormats() { // Specify vertex formats using ARB_vertex_attrib_binding glBindVertexArray(gctx.vtxformats[VERT_POS_NOR]); // Position glVertexAttribFormat(0, // Attribute index layout (location = 0) for pos 3, // Size 3 * floats GL_FLOAT, // Type of attrib GL_FALSE, // Normalised? 0 // Offset ); glVertexAttribBinding(0, 0); glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0); // NORMAL glVertexAttribBinding(1, 1); glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_T0]); glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); // POS glVertexAttribBinding(0, 0); glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0); // NORMAL glVertexAttribBinding(1, 1); glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 0); // TEXCOORD0 glVertexAttribBinding(2, 2); glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_STRIDED]); glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); // POS glVertexAttribBinding(0, 0); glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float)); // NORMAL glVertexAttribBinding(1, 0); glBindVertexArray(gctx.vtxformats[VERT_POS_NOR_T0_STRIDED]); glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); // POS glVertexAttribBinding(0, 0); glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float)); // NORMAL glVertexAttribBinding(1, 0); glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float)); // TEXCOORD0 glVertexAttribBinding(2, 0); glBindVertexArray(gctx.vtxformats[VERT_POS_T0_STRIDED]); glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0 * sizeof(float)); // POS glVertexAttribBinding(0, 0); glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float)); // NORMAL glVertexAttribBinding(1, 0); glBindVertexArray(0); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglVertexAttribBinding(JNIEnv *__env, jclass clazz, jint attribindex, jint bindingindex, jlong __functionAddress) { glVertexAttribBindingPROC glVertexAttribBinding = (glVertexAttribBindingPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glVertexAttribBinding(attribindex, bindingindex); }
ShovelerDrawable *shovelerDrawableTilesCreate(unsigned char width, unsigned char height) { Tiles *tiles = malloc(sizeof(Tiles)); tiles->width = width; tiles->height = height; tiles->vertices = malloc(4 * width * height * sizeof(TilesVertex)); tiles->triangles = malloc(2 * width * height * sizeof(TilesTriangle)); tiles->drawable.data = tiles; tiles->drawable.draw = drawTiles; tiles->drawable.free = freeTiles; for(unsigned char x = 0; x < width; x++) { for(unsigned char y = 0; y < height; y++) { unsigned int index = x * height + y; tiles->vertices[4 * index + 0].position[0] = x; tiles->vertices[4 * index + 0].position[1] = y; tiles->vertices[4 * index + 0].uv[0] = 0; tiles->vertices[4 * index + 0].uv[1] = 0; tiles->vertices[4 * index + 1].position[0] = x + 1; tiles->vertices[4 * index + 1].position[1] = y; tiles->vertices[4 * index + 1].uv[0] = 1; tiles->vertices[4 * index + 1].uv[1] = 0; tiles->vertices[4 * index + 2].position[0] = x; tiles->vertices[4 * index + 2].position[1] = y + 1; tiles->vertices[4 * index + 2].uv[0] = 0; tiles->vertices[4 * index + 2].uv[1] = 1; tiles->vertices[4 * index + 3].position[0] = x + 1; tiles->vertices[4 * index + 3].position[1] = y + 1; tiles->vertices[4 * index + 3].uv[0] = 1; tiles->vertices[4 * index + 3].uv[1] = 1; tiles->triangles[2 * index + 0].indices[0] = 4 * index + 1; tiles->triangles[2 * index + 0].indices[1] = 4 * index + 3; tiles->triangles[2 * index + 0].indices[2] = 4 * index + 0; tiles->triangles[2 * index + 1].indices[0] = 4 * index + 3; tiles->triangles[2 * index + 1].indices[1] = 4 * index + 2; tiles->triangles[2 * index + 1].indices[2] = 4 * index + 0; } } glGenVertexArrays(1, &tiles->vertexArrayObject); glBindVertexArray(tiles->vertexArrayObject); glEnableVertexAttribArray(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION); glEnableVertexAttribArray(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV); glVertexAttribFormat(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION, 2, GL_UNSIGNED_BYTE, GL_FALSE, offsetof(TilesVertex, position)); glVertexAttribFormat(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV, 2, GL_UNSIGNED_BYTE, GL_FALSE, offsetof(TilesVertex, uv)); glVertexAttribBinding(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_POSITION, 0); glVertexAttribBinding(SHOVELER_SHADER_PROGRAM_ATTRIBUTE_UV, 0); glGenBuffers(1, &tiles->vertexBuffer); glGenBuffers(1, &tiles->indexBuffer); glBindBuffer(GL_ARRAY_BUFFER, tiles->vertexBuffer); glBufferData(GL_ARRAY_BUFFER, 4 * width * height * sizeof(TilesVertex), tiles->vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tiles->indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * width * height * sizeof(TilesTriangle), tiles->triangles, GL_STATIC_DRAW); if(!shovelerOpenGLCheckSuccess()) { freeTiles(&tiles->drawable); return NULL; } return &tiles->drawable; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_glVertexAttribBinding(JNIEnv *__env, jclass clazz, jint attribindex, jint bindingindex) { glVertexAttribBindingPROC glVertexAttribBinding = (glVertexAttribBindingPROC)tlsGetFunction(911); UNUSED_PARAM(clazz) glVertexAttribBinding(attribindex, bindingindex); }
void GLVertexArrayObject::mapAttributeIndexToBindingIndex( GLuint attributeIndex, GLuint bindingIndex ) { glVertexAttribBinding( attributeIndex, bindingIndex ); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglVertexAttribBinding(JNIEnv *env, jclass clazz, jint attribindex, jint bindingindex, jlong function_pointer) { glVertexAttribBindingPROC glVertexAttribBinding = (glVertexAttribBindingPROC)((intptr_t)function_pointer); glVertexAttribBinding(attribindex, bindingindex); }
bool StaticMesh::loadFromFile(const std::string& infile) { Assimp::Importer imp; // Load scene and grab first mesh only imp.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT | aiPrimitiveType_POLYGON, nullptr); #ifdef DEBUG std::cout << "Calling Assimp::Importer::ReadFile...\n"; #endif // DEBUG const aiScene *scene = imp.ReadFile(infile, aiProcessPreset_TargetRealtime_Quality & (!aiProcess_SplitLargeMeshes)); #ifdef DEBUG std::cout << "Checking for a mesh...\n"; #endif // DEBUG if(scene == nullptr) return false; else if(!scene->HasMeshes()) return false; imp.ApplyPostProcessing(aiProcess_JoinIdenticalVertices); // Will only load one mesh const aiMesh *mesh = scene->mMeshes[0]; #ifdef DEBUG std::cout << "Checking mesh has what we need...\n"; #endif // DEBUG // Don't process special mesh types if(!mesh->HasPositions() || !mesh->HasFaces()) return false; vertexCount = mesh->mNumVertices; triangleCount = mesh->mNumFaces; // Check what attributes are in the mesh and // calculate total count of floats std::size_t componentCount = components.vertex = 3; if(mesh->HasNormals()) { componentCount += components.normal = 3; #ifdef DEBUG std::cout << "Has normals\n"; #endif // DEBUG } if(mesh->HasTangentsAndBitangents()) { componentCount += (components.tangentBitangent = 3) * 2; #ifdef DEBUG std::cout << "Has tangents and bitangents\n"; #endif // DEBUG } if(mesh->HasTextureCoords(0)) { componentCount += components.texture = 3; #ifdef DEBUG std::cout << "Has texture coordinates\n"; #endif // DEBUG } // Scale size for size of float std::size_t totalSize = componentCount * sizeof(float) * vertexCount; #ifdef DEBUG std::cout << totalSize << std::endl; std::cout << "Allocating and mapping vertex buffer...\n"; #endif // DEBUG // Set size and map buffer glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, totalSize, nullptr, GL_STATIC_DRAW); GLfloat *mapPtr = (GLfloat*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); // glNamedBufferDataEXT(buffer, totalSize, nullptr, GL_STATIC_DRAW); // GLfloat *mapPtr = (GLfloat*) glMapNamedBufferEXT(buffer, GL_WRITE_ONLY); if(mapPtr == nullptr) return false; #ifdef DEBUG std::cout << "Worked!\n"; #endif // DEBUG // Load all attributes into mapped buffer for(unsigned int i = 0; i < vertexCount; ++i) { GLfloat *head = mapPtr + i * componentCount; *head++ = mesh->mVertices[i].x; *head++ = mesh->mVertices[i].y; *head++ = mesh->mVertices[i].z; if(mesh->HasNormals()) { *head++ = mesh->mNormals[i].x; *head++ = mesh->mNormals[i].y; *head++ = mesh->mNormals[i].z; } if(mesh->HasTextureCoords(0)) { *head++ = mesh->mTextureCoords[0][i].x; *head++ = mesh->mTextureCoords[0][i].y; *head++ = mesh->mTextureCoords[0][i].z; } if(mesh->HasTangentsAndBitangents()) { *head++ = mesh->mTangents[i].x; *head++ = mesh->mTangents[i].y; *head++ = mesh->mTangents[i].z; *head++ = mesh->mBitangents[i].x; *head++ = mesh->mBitangents[i].y; *head++ = mesh->mBitangents[i].z; } } if(!glUnmapBuffer(GL_ARRAY_BUFFER)) return false; #ifdef DEBUG std::cout << "Allocating and mapping index buffer...\n"; #endif // DEBUG // Same for index buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangleCount*3*sizeof(GLshort), nullptr, GL_STATIC_DRAW); GLushort *indexMapPtr = (GLushort*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); // glNamedBufferDataEXT(indices, triangleCount * 3 * sizeof(GLushort), nullptr, GL_STATIC_DRAW); // GLushort *indexMapPtr = (GLushort*) glMapNamedBufferEXT(indices, GL_WRITE_ONLY); if(indexMapPtr == nullptr) return false; #ifdef DEBUG std::cout << "Worked!\n"; #endif // DEBUG for(unsigned int i = 0; i < triangleCount; ++i) { #ifdef DEBUG assert(mesh->mFaces[i].mNumIndices == 3); #endif // DEBUG unsigned int *indexArray = mesh->mFaces[i].mIndices; for(unsigned int j = 0; j < 3; ++j) { #ifdef DEBUG assert(*indexArray <= std::numeric_limits<GLushort>::max()); #endif // DEBUG *indexMapPtr++ = *indexArray++; } } if(!glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)) return false;; #ifdef DEBUG std::cout << "Loading mesh successful!\n"; std::cout << "Setting up vertex array...\n"; #endif // DEBUG glBindVertexArray(vertexArray); glBindVertexBuffer(0, buffer, 0, (components.vertex + components.normal + components.texture + components.tangentBitangent * 2) * sizeof(GLfloat)); glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(0, 0); glEnableVertexAttribArray(0); if(components.normal) { glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, components.vertex * sizeof(float)); glVertexAttribBinding(1, 0); glEnableVertexAttribArray(1); } if(components.texture) { glVertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, (components.vertex + components.normal) * sizeof(float)); glVertexAttribBinding(2, 0); glEnableVertexAttribArray(2); } if(components.tangentBitangent) { glVertexAttribFormat(3, 3, GL_FLOAT, GL_FALSE, (components.vertex + components.normal + components.texture) * sizeof(float)); glVertexAttribBinding(3, 0); glEnableVertexAttribArray(3); glVertexAttribFormat(4, 3, GL_FLOAT, GL_FALSE, (components.vertex + components.normal + components.texture + components.tangentBitangent) * sizeof(float)); glVertexAttribBinding(4, 0); glEnableVertexAttribArray(4); } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices); glBindVertexArray(0); #ifdef DEBUG std::cout << vertexCount << ' ' << triangleCount << std::endl; std::cout << +components.vertex << ' '; std::cout << +components.normal << ' '; std::cout << +components.texture << ' '; std::cout << +components.tangentBitangent << std::endl; #endif // DEBUG return true; }
inline void vertex_attrib_binding(uint32 attrib_index, uint32 binding_index) { ARC_GL_CLEAR_ERRORS(); glVertexAttribBinding(attrib_index, binding_index); ARC_GL_CHECK_FOR_ERRORS(); }