void OpenGLWrapper::DrawMultiPolygon(std::vector<float> const& points, std::vector<int> &start, std::vector<int> &count, Vector2D video_pos, Vector2D video_size, bool invert) { GL_EXT(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); float real_line_a = line_a; line_a = 0; // The following is nonzero winding-number PIP based on stencils // Draw to stencil only glEnable(GL_STENCIL_TEST); glColorMask(0, 0, 0, 0); // GL_INCR_WRAP was added in 1.4, so instead set the entire stencil to 128 // and wobble from there glStencilFunc(GL_NEVER, 128, 0xFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); Vector2D video_max = video_pos + video_size; DrawRectangle(video_pos, video_max); // Increment the winding number for each forward facing triangle glStencilOp(GL_INCR, GL_INCR, GL_INCR); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &points[0]); glMultiDrawArrays(GL_TRIANGLE_FAN, &start[0], &count[0], start.size()); // Decrement the winding number for each backfacing triangle glStencilOp(GL_DECR, GL_DECR, GL_DECR); glCullFace(GL_FRONT); glMultiDrawArrays(GL_TRIANGLE_FAN, &start[0], &count[0], start.size()); glDisable(GL_CULL_FACE); // Draw the actual rectangle glColorMask(1, 1, 1, 1); // VSFilter draws when the winding number is nonzero, so we want to draw the // mask when the winding number is zero (where 128 is zero due to the lack of // wrapping combined with unsigned numbers) glStencilFunc(invert ? GL_EQUAL : GL_NOTEQUAL, 128, 0xFF); DrawRectangle(video_pos, video_max); glDisable(GL_STENCIL_TEST); // Draw lines line_a = real_line_a; SetModeLine(); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &points[0]); glMultiDrawArrays(GL_LINE_LOOP, &start[0], &count[0], start.size()); glDisableClientState(GL_VERTEX_ARRAY); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL14C_nglMultiDrawArrays__IJJI(JNIEnv *__env, jclass clazz, jint mode, jlong firstAddress, jlong countAddress, jint primcount) { glMultiDrawArraysPROC glMultiDrawArrays = (glMultiDrawArraysPROC)tlsGetFunction(426); intptr_t first = (intptr_t)firstAddress; intptr_t count = (intptr_t)countAddress; UNUSED_PARAM(clazz) glMultiDrawArrays(mode, first, count, primcount); }
inline void multiDrawArrays( MultiDrawArraysMode mode , const GLint * first , const GLsizei * count , GLsizei drawcount) { glMultiDrawArrays(GLenum(mode),first,count,drawcount); }
/* * @overload multi_draw_arrays(primitive, first, count) * @param primitive (see #draw_arrays) * @param [Ray::GL::IntArray] first Indices of the first vertex * @param [Ray::GL::IntArray] count Ammount of vertices to draw */ static VALUE ray_gl_multi_draw_arrays(VALUE self, VALUE primitive, VALUE rb_first, VALUE rb_count) { mo_array *first = ray_rb2int_array(rb_first); mo_array *count = ray_rb2int_array(rb_count); if (first->size != count->size) rb_raise(rb_eArgError, "first and count arrays should have the same size"); glMultiDrawArrays(NUM2INT(rb_hash_aref(ray_gl_primitives, primitive)), mo_array_at(first, 0), mo_array_at(count, 0), first->size); return Qnil; }
void Mist::draw() { #if USE_MIST_DEBUG glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mist_tex); glUseProgram(prog); glBindVertexArray(vao); glUniformMatrix4fv(glGetUniformLocation(prog, "u_pm"), 1, GL_FALSE, effects.ortho_pm.ptr()); #define MIST_ROTATE_SHAPES 1 #define MIST_MULTI_DRAW 0 #if MIST_ROTATE_SHAPES for(std::vector<MistShape>::iterator it = shapes.begin(); it != shapes.end(); ++it) { MistShape& shape = *it; float perc = 1.0f; glUniform1f(u_time, rx_millis() * shape.rotate_speed); glUniform1f(u_perc, perc); shape.mm.identity(); shape.mm.translate(shape.x, shape.y, 0.0f); glUniformMatrix4fv(glGetUniformLocation(prog, "u_mm"), 1, GL_FALSE, shape.mm.ptr()); glDrawArrays(GL_TRIANGLES, shape.offset, shape.count); } #elif MIST_MULTI_DRAW mat4 mm; glUniformMatrix4fv(glGetUniformLocation(prog, "u_mm"), 1, GL_FALSE, mm.ptr()); glUniform1f(u_time, rx_millis() * 0.1); glMultiDrawArrays(GL_TRIANGLE_STRIP, &offsets.front(), &counts.front(), counts.size()); #else mat4 mm; glUniformMatrix4fv(glGetUniformLocation(prog, "u_mm"), 1, GL_FALSE, mm.ptr()); for(size_t i = 0; i < counts.size(); ++i) { glUniform1f(u_time, rx_millis() * 0.1 * i); glDrawArrays(GL_TRIANGLE_STRIP, offsets[i], counts[i]); } #endif glDisable(GL_BLEND); }
static bool test_MultiDrawArrays(GLenum dlmode) { GLint first = 0, count = 4; GLuint list; glClear(GL_COLOR_BUFFER_BIT); list = glGenLists(1); glNewList(list, dlmode); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, verts); glMultiDrawArrays(GL_TRIANGLE_FAN, &first, &count, 1); glEndList(); return test_list(list, dlmode, "glMultiDrawArrays"); }
void grBatchDraw(void) { if (!count) return; glBindVertexArray(quad_vao); glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, count * 8 * sizeof(float), lvert); glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, count * 8 * sizeof(float), ltc); glBindBuffer(GL_ARRAY_BUFFER, color_vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, count * 4 * sizeof(unsigned int), lcolor); /* draw points 0-3 from the currently bound VAO with current in-use shader */ glMultiDrawArrays(GL_TRIANGLE_FAN, indices, counts, count); //printf("Batch %d\n", count); count = 0; }
void RenderableFieldlines::render(const RenderData& data) { _program->activate(); _program->setUniform("modelViewProjection", data.camera.viewProjectionMatrix()); _program->setUniform("modelTransform", glm::mat4(1.0)); _program->setUniform("cameraViewDir", glm::vec3(data.camera.viewDirectionWorldSpace())); glDisable(GL_CULL_FACE); setPscUniforms(*_program, data.camera, data.position); _program->setUniform("classification", _classification); if (!_classification) _program->setUniform("fieldLineColor", _fieldlineColor); glBindVertexArray(_fieldlineVAO); glMultiDrawArrays( GL_LINE_STRIP_ADJACENCY, &_lineStart[0], &_lineCount[0], static_cast<GLsizei>(_lineStart.size()) ); glBindVertexArray(0); glEnable(GL_CULL_FACE); _program->deactivate(); }
void render() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Light only the obstructions; wave lighting is in the colors kernel. glEnable(GL_LIGHTING); glCallList(BLOCKLIST); glDisable(GL_LIGHTING); glBindBuffer(GL_ARRAY_BUFFER,OGL_VBO); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // This calls a sequence of LENGTH-1 glDrawArray()s, where the ith array // starts at index first[i] and ends at first[i]+count[i]-1. // A triangle strip has 2N vertices, arranged as: // v0 -- v2 -- v4 ---- // | / \ / \ etc. // | / \ / \ // v1 ----- v3 --- v5 -- // glMultiDrawArrays(GL_TRIANGLE_STRIP,first,count,LENGTH-1); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glutSwapBuffers(); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL14_nglMultiDrawArrays(JNIEnv *env, jclass clazz, jint mode, jlong piFirst, jlong piCount, jint primcount, jlong function_pointer) { GLint *piFirst_address = (GLint *)(intptr_t)piFirst; GLsizei *piCount_address = (GLsizei *)(intptr_t)piCount; glMultiDrawArraysPROC glMultiDrawArrays = (glMultiDrawArraysPROC)((intptr_t)function_pointer); glMultiDrawArrays(mode, piFirst_address, piCount_address, primcount); }
static void itemview_render( GWidget* wp ) { EX_PTR; UBuffer* fcBuf; int n; n = ep->modVbo; fcBuf = &ep->fc[ n ]; glBindBuffer( GL_ARRAY_BUFFER, ep->vbo[ n ] ); if( ep->updateMethod == IV_UPDATE_2 ) { UThread* ut = glEnv.guiUT; const UBuffer* items = ur_buffer( ep->dataBlkN ); ep->itemCount = items->used; if( items->used != fcBuf->used - DECORATION_GROUPS ) { if( items->used ) itemview_rebuildAttr( ut, ep, items, n ); else fcBuf->used = 0; } else { // Update two items... } } if( fcBuf->used ) { const int16_t* trans = gui_parentTranslation( wp ); // Scissor works in window coordinates so matrix rotations cannot // be supported and translation (e.g. window dragging) must be applied // manually. glScissor( wp->area.x + trans[0], wp->area.y + trans[1], wp->area.w, wp->area.h ); glEnable( GL_SCISSOR_TEST ); #if 0 glEnableVertexAttribArray( ALOC_POS ); glEnableVertexAttribArray( ALOC_UV ); glVertexAttribPointer( ALOC_POS, 3, GL_FLOAT, GL_FALSE, 5, NULL + 0 ); glVertexAttribPointer( ALOC_UV, 2, GL_FLOAT, GL_FALSE, 5, NULL + 3 ); #else glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glEnableClientState( GL_COLOR_ARRAY ); glVertexPointer ( 3, GL_FLOAT, AttrCount * sizeof(GLfloat), NULL + 0 ); glTexCoordPointer( 2, GL_FLOAT, AttrCount * sizeof(GLfloat), NULL + 3 * sizeof(GLfloat) ); glColorPointer( 3, GL_FLOAT, AttrCount * sizeof(GLfloat), NULL + 5 * sizeof(GLfloat) ); #endif glPushMatrix(); glTranslatef( (GLfloat) wp->area.x, (GLfloat) wp->area.y + ep->scrollY, 0.0f ); glUniform1i( ep->use_color, 1 ); glMultiDrawArrays( GL_TRIANGLES, (GLint*) fcBuf->ptr.i, (GLsizei*) (fcBuf->ptr.i + fcBuf->used), fcBuf->used ); glUniform1i( ep->use_color, 0 ); glPopMatrix(); glDisableClientState( GL_COLOR_ARRAY ); glDisable( GL_SCISSOR_TEST ); } }
void VertexArray::multiDrawArrays(const GLenum mode, GLint* first, const GLsizei* count, const GLsizei drawCount) const { bind(); glMultiDrawArrays(mode, first, count, drawCount); }
/** * edges using geometry shader. */ int build_triangle_edges(lulog *log, GLuint *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "flat_model_g.vert", &shaders)); try(compile_shader_from_file(log, GL_GEOMETRY_SHADER, "edge_lines.geom", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_colour.frag", &shaders)); try(link_program(log, shaders, program)); finally: status = free_shaders(log, &shaders, status); return status; } /** * copy a frame by rendering a texture directly (needs a quad to select the area). */ int build_direct_texture(lulog *log, direct_texture *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_texture.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); finally: status = free_shaders(log, &shaders, status); return status; } /** * merge two frames via textures. */ int build_merge_frames(lulog *log, merge_frames *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "merge_frames.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame1", &program->frame1, 0)); try(set_uniform(log, program->name, "frame2", &program->frame2, 1)); finally: status = free_shaders(log, &shaders, status); return status; } /** * blur a frame (roughly uniform over 5 pixels radius). */ int build_blur(lulog *log, blur *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "blur.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); try(set_uniform(log, program->name, "horizontal", &program->horizontal, 1)); finally: status = free_shaders(log, &shaders, status); return status; } int draw_triangle_edges(lulog *log, model *model, programs *programs) { int status = LU_OK; gl_try(glBindVertexArray(model->vao)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); gl_try(glUseProgram(programs->triangle_edges)); gl_try(glMultiDrawArrays(GL_TRIANGLE_STRIP, model->offsets->i, model->counts->i, model->counts->mem.used)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); finally: GL_CLEAN(glBindVertexArray(0)) GL_CLEAN(glUseProgram(0)) return status; }
void DisplayDeviceOpenGL::render(const Renderable* r) const { if(!r->isEnabled()) { // Renderable item not enabled then early return. return; } StencilScopePtr stencil_scope; if(r->hasClipSettings()) { ModelManager2D mm(r->getPosition().x, r->getPosition().y); auto clip_shape = r->getStencilMask(); bool cam_set = false; if(clip_shape->getCamera() == nullptr && r->getCamera() != nullptr) { cam_set = true; clip_shape->setCamera(r->getCamera()); } stencil_scope.reset(new StencilScopeOGL(r->getStencilSettings())); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); glClear(GL_STENCIL_BUFFER_BIT); render(clip_shape.get()); stencil_scope->applyNewSettings(keep_stencil_settings); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); if(cam_set) { clip_shape->setCamera(nullptr); } } auto shader = r->getShader(); shader->makeActive(); BlendEquationScopeOGL be_scope(*r); BlendModeScopeOGL bm_scope(*r); // apply lighting/depth check/depth write here. bool use_lighting = r->isLightingStateSet() ? r->useLighting() : false; // Set the depth enable. if(r->isDepthEnableStateSet()) { if(get_current_depth_enable() != r->isDepthEnabled()) { if(r->isDepthEnabled()) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } get_current_depth_enable() = r->isDepthEnabled(); } } else { // We assume that depth is disabled if not specified. if(get_current_depth_enable() == true) { glDisable(GL_DEPTH_TEST); get_current_depth_enable() = false; } } glm::mat4 pmat(1.0f); glm::mat4 vmat(1.0f); if(r->getCamera()) { // set camera here. pmat = r->getCamera()->getProjectionMat(); vmat = r->getCamera()->getViewMat(); } else if(get_default_camera() != nullptr) { pmat = get_default_camera()->getProjectionMat(); vmat = get_default_camera()->getViewMat(); } if(use_lighting) { for(auto lp : r->getLights()) { /// xxx need to set lights here. } } if(r->getRenderTarget()) { r->getRenderTarget()->apply(); } if(shader->getPUniform() != ShaderProgram::INVALID_UNIFORM) { shader->setUniformValue(shader->getPUniform(), glm::value_ptr(pmat)); } if(shader->getMvUniform() != ShaderProgram::INVALID_UNIFORM) { glm::mat4 mvmat = vmat; if(is_global_model_matrix_valid() && !r->ignoreGlobalModelMatrix()) { mvmat *= get_global_model_matrix() * r->getModelMatrix(); } else { mvmat *= r->getModelMatrix(); } shader->setUniformValue(shader->getMvUniform(), glm::value_ptr(mvmat)); } if(shader->getMvpUniform() != ShaderProgram::INVALID_UNIFORM) { glm::mat4 pvmat(1.0f); if(is_global_model_matrix_valid() && !r->ignoreGlobalModelMatrix()) { pvmat = pmat * vmat * get_global_model_matrix() * r->getModelMatrix(); } else { pvmat = pmat * vmat * r->getModelMatrix(); } shader->setUniformValue(shader->getMvpUniform(), glm::value_ptr(pvmat)); } if(shader->getColorUniform() != ShaderProgram::INVALID_UNIFORM) { if(r->isColorSet()) { shader->setUniformValue(shader->getColorUniform(), r->getColor().asFloatVector()); } else { shader->setUniformValue(shader->getColorUniform(), ColorScope::getCurrentColor().asFloatVector()); } } shader->setUniformsForTexture(r->getTexture()); // XXX we should make this either or with setting the mvp/color uniforms above. auto uniform_draw_fn = shader->getUniformDrawFunction(); if(uniform_draw_fn) { uniform_draw_fn(shader); } // Loop through uniform render variables and set them. /*for(auto& urv : r->UniformRenderVariables()) { for(auto& rvd : urv->VariableDescritionList()) { auto rvdd = std::dynamic_pointer_cast<RenderVariableDeviceData>(rvd->GetDisplayData()); ASSERT_LOG(rvdd != nullptr, "Unable to cast DeviceData to RenderVariableDeviceData."); shader->SetUniformValue(rvdd->GetActiveMapIterator(), urv->Value()); } }*/ // Need to figure the interaction with shaders. /// XXX Need to create a mapping between attributes and the index value below. for(auto as : r->getAttributeSet()) { //ASSERT_LOG(as->getCount() > 0, "No (or negative) number of vertices in attribute set. " << as->getCount()); if((!as->isMultiDrawEnabled() && as->getCount() <= 0) || (as->isMultiDrawEnabled() && as->getMultiDrawCount() <= 0)) { //LOG_WARN("No (or negative) number of vertices in attribute set. " << as->getCount()); continue; } GLenum draw_mode = convert_drawing_mode(as->getDrawMode()); // apply blend, if any, from attribute set. BlendEquationScopeOGL be_scope(*as); BlendModeScopeOGL bm_scope(*as); if(shader->getColorUniform() != ShaderProgram::INVALID_UNIFORM && as->isColorSet()) { shader->setUniformValue(shader->getColorUniform(), as->getColor().asFloatVector()); } for(auto& attr : as->getAttributes()) { if(attr->isEnabled()) { shader->applyAttribute(attr); } } if(as->isInstanced()) { if(as->isIndexed()) { as->bindIndex(); // XXX as->GetIndexArray() should be as->GetIndexArray()+as->GetOffset() glDrawElementsInstanced(draw_mode, static_cast<GLsizei>(as->getCount()), convert_index_type(as->getIndexType()), as->getIndexArray(), as->getInstanceCount()); as->unbindIndex(); } else { glDrawArraysInstanced(draw_mode, static_cast<GLint>(as->getOffset()), static_cast<GLsizei>(as->getCount()), as->getInstanceCount()); } } else { if(as->isIndexed()) { as->bindIndex(); // XXX as->GetIndexArray() should be as->GetIndexArray()+as->GetOffset() glDrawElements(draw_mode, static_cast<GLsizei>(as->getCount()), convert_index_type(as->getIndexType()), as->getIndexArray()); as->unbindIndex(); } else { if(as->isMultiDrawEnabled()) { glMultiDrawArrays(draw_mode, as->getMultiOffsetArray().data(), as->getMultiCountArray().data(), as->getMultiDrawCount()); } else { glDrawArrays(draw_mode, static_cast<GLint>(as->getOffset()), static_cast<GLsizei>(as->getCount())); } } } shader->cleanUpAfterDraw(); glBindBuffer(GL_ARRAY_BUFFER, 0); } if(r->getRenderTarget()) { r->getRenderTarget()->unapply(); } }
void VertexArrayObject::multiDrawArrays(GLenum mode, GLint* first, const GLsizei* count, GLsizei drawCount) { bind(); glMultiDrawArrays(mode, first, count, drawCount); CheckGLError(); }