void Material::Bind() { GetShaderProgram().Bind(); GetShaderProgram().SetTexture(Albedo(), 0, "Texture"); if (Normal().IsValid()) { GetShaderProgram().SetTexture(Normal(), 1, "NormalsTexture"); } }
//----------------------------------------------------------------------- std::unique_ptr<NativeEffectReflection> GraphicsDeviceGL4::CreateEffectReflection( PipelineStateDescription const&, NativePipelineState & pipelineState) { auto const pipelineStateGL4 = dynamic_cast<PipelineStateGL4*>(&pipelineState); POMDOG_ASSERT(pipelineStateGL4 != nullptr); return std::make_unique<EffectReflectionGL4>( pipelineStateGL4->GetShaderProgram()); }
void Particle3d::Draw(const Math::Matrix4& viewFromWorld) const { if (_model == nullptr) { assertion(_model != nullptr); return; } auto shader = GetShaderProgram(); auto worldFromModel = _transform.GetWorldFromModel(); auto normalMatrix = worldFromModel.Inverse(); auto projectionFromModel = viewFromWorld*worldFromModel; shader->SendData(projectionFromModel.Transpose(), "projectionFromModel"); shader->SendData(_transform.GetPosition(), "vertexPosition"); shader->SendData(normalMatrix, "normalMatrix"); _model->Draw(); }
static void RenderImGuiDrawList(ImDrawData *data) { ImGuiIO& io = ImGui::GetIO(); GameMemory *memory = (GameMemory*)io.UserData; RenderState *rs = &memory->renderState; SystemInfo *system = &memory->systemInfo; memory->renderState.imgui_draw_data = data; glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, system->screenWidth, system->screenHeight); glUseProgram(GetShaderProgram(ShaderID_Sprite, &memory->assetManifest)); M4 screenProjection = Orthographic(0.0f, system->screenWidth, 0.0f, system->screenHeight, -1.0f, 100.0f, -1.0f); glUniformMatrix4fv(2, 1, GL_FALSE, &screenProjection[0][0]); glBindVertexArray(rs->imguiRenderGroup.vao); glActiveTexture(GL_TEXTURE0); ImDrawData *draw_data = rs->imgui_draw_data; for (int i = 0; i < rs->imgui_draw_data->CmdListsCount; i++) { const ImDrawList *draw_list = draw_data->CmdLists[i]; const ImDrawIdx *index_buffer_offset = 0; glBindBuffer(GL_ARRAY_BUFFER, rs->imguiRenderGroup.vbo); glBufferData(GL_ARRAY_BUFFER, draw_list->VtxBuffer.size() * sizeof(ImDrawVert), &draw_list->VtxBuffer.front(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rs->imguiRenderGroup.ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, draw_list->IdxBuffer.size() * sizeof(ImDrawIdx), &draw_list->IdxBuffer.Data[0], GL_DYNAMIC_DRAW); for (const ImDrawCmd* cmd = draw_list->CmdBuffer.begin(); cmd != draw_list->CmdBuffer.end(); cmd++) { glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr_t)cmd->TextureId); glDrawElements(GL_TRIANGLES, cmd->ElemCount, GL_UNSIGNED_SHORT, index_buffer_offset); index_buffer_offset += cmd->ElemCount; } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } glDisable(GL_SCISSOR_TEST); glUseProgram(0); }
void Renderer::UpdateScene(std::vector<RenderItemProxy> renderables) { for (size_t i = 0; i < m_numRenderItemCacheRequests; ++i) { auto& request = m_renderItemCacheQueue[i]; auto& newRenderItem = m_pImpl->m_renderItems[m_numRenderItems++]; newRenderItem.mesh = request.mesh; newRenderItem.shaderProgramId = GetShaderProgram(request.vertShader, request.pixelShader); } m_numRenderItemCacheRequests = 0; m_renderQueueEnd = 0; for (auto& renderable : renderables) { auto itemHandle = renderable.renderItemId; m_pImpl->m_renderItems[itemHandle].transform = renderable.transform; m_renderQueue[m_renderQueueEnd++] = itemHandle; } }
//***************************************************************************** // Render //***************************************************************************** void ParticleSystem::Render(Matrix* pMatrixVP) { int hProg = GetShaderProgram(PARTICLE_RENDER_PROGRAM); glWaitSync((GLsync)m_pSync, 0, GL_TIMEOUT_IGNORED); glDeleteSync((GLsync)m_pSync); glUseProgram(hProg); glBindBuffer(GL_ARRAY_BUFFER, m_arVBOs[!m_nUpdateBuffer]); // Assign vertex attributes glVertexAttribPointer(s_hRendPosition, 3, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, 0); glVertexAttribPointer(s_hRendColor, 4, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 24); glVertexAttribPointer(s_hRendLife, 1, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 40); glVertexAttribPointer(s_hRendSize, 1, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 44); // Enable the attrib arrays glEnableVertexAttribArray(s_hRendPosition); glEnableVertexAttribArray(s_hRendColor); glEnableVertexAttribArray(s_hRendLife); glEnableVertexAttribArray(s_hRendSize); // Setup the uniforms glUniformMatrix4fv(s_hRendMatrixVP, 1, GL_FALSE, pMatrixVP->GetArray()); if (m_pTexture == 0) { glUniform1i(s_hTexType, 0); } else { glUniform1i(s_hTexType, 1); } glUniform1i(s_hRendTexture, 0); // Bind texture if (m_pTexture != 0) { m_pTexture->Bind(); } glDrawArrays(GL_POINTS, 0, m_nParticleCount); }
//***************************************************************************** // Update //***************************************************************************** void ParticleSystem::Update() { float fDeltaTime = 0.0f; int hProg = GetShaderProgram(PARTICLE_UPDATE_PROGRAM); m_timer.Stop(); fDeltaTime = m_timer.Time(); glUseProgram(hProg); // Toggle the update buffer index m_nUpdateBuffer = !m_nUpdateBuffer; // Bind the correct buffers glBindBuffer(GL_ARRAY_BUFFER, m_arVBOs[m_nUpdateBuffer]); glBindBuffer ( GL_TRANSFORM_FEEDBACK_BUFFER, m_arVBOs[!m_nUpdateBuffer]); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_arVBOs[!m_nUpdateBuffer]); // Assign vertex attributes glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 12); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 24); glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 40); glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, PARTICLE_DATA_SIZE, (void*) 44); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); // Set Uniforms glUniform1f(s_hMinLifetime, m_fMinLifetime); glUniform1f(s_hMaxLifetime, m_fMaxLifetime); glUniform4fv(s_hMinColor, 1, m_arMinColor); glUniform4fv(s_hMaxColor, 1, m_arMaxColor); glUniform3fv(s_hMinVelocity, 1, m_arMinVelocity); glUniform3fv(s_hMaxVelocity, 1, m_arMaxVelocity); glUniform1f(s_hMinSize, m_fMinSize); glUniform1f(s_hMaxSize, m_fMaxSize); glUniform3fv(s_hGravity, 1, m_arGravity); glUniform1i(s_hSeed, rand()); glUniform1f(s_hDeltaTime, fDeltaTime); glUniform1i(s_hGenerate, m_nGenerate); glUniform3fv(s_hOrigin, 1, m_arOrigin); glUniform3fv(s_hSpawnVariance, 1, m_arSpawnVariance); // Since this shader is only being used for transform feedback, // we don't want anything to be drawn to the framebuffer. // To disable drawing, enable GL_RASTERIZE_DISCARD glEnable(GL_RASTERIZER_DISCARD); // Update particles with transform feedback glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, m_nParticleCount); glEndTransformFeedback(); // Since the rendering relies on the particle update being finished, // and the gpu does its processing asynchronously, we must wait until // the gpu processing is done by using a sync object. glFinish should // work too, but might not be as effectient. m_pSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); glDisable(GL_RASTERIZER_DISCARD); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); m_timer.Start(); }
//***************************************************************************** // Initialize //***************************************************************************** void ParticleSystem::Initialize() { int hProg = 0; char* pZeroBuffer = 0; // Perform static initialization if (s_nStaticInit == 0) { hProg = GetShaderProgram(PARTICLE_UPDATE_PROGRAM); s_hMinLifetime = glGetUniformLocation(hProg, "uMinLifetime"); s_hMaxLifetime = glGetUniformLocation(hProg, "uMaxLifetime"); s_hMinColor = glGetUniformLocation(hProg, "uMinColor"); s_hMaxColor = glGetUniformLocation(hProg, "uMaxColor"); s_hMinVelocity = glGetUniformLocation(hProg, "uMinVelocity"); s_hMaxVelocity = glGetUniformLocation(hProg, "uMaxVelocity"); s_hMinSize = glGetUniformLocation(hProg, "uMinSize"); s_hMaxSize = glGetUniformLocation(hProg, "uMaxSize"); s_hGravity = glGetUniformLocation(hProg, "uGravity"); s_hSeed = glGetUniformLocation(hProg, "uSeed"); s_hDeltaTime = glGetUniformLocation(hProg, "uDeltaTime"); s_hGenerate = glGetUniformLocation(hProg, "uGenerate"); s_hOrigin = glGetUniformLocation(hProg, "uOrigin"); s_hSpawnVariance = glGetUniformLocation(hProg, "uSpawnVariance"); s_hPosition = glGetAttribLocation(hProg, "aPosition"); s_hVelocity = glGetAttribLocation(hProg, "aVelocity"); s_hColor = glGetAttribLocation(hProg, "aColor"); s_hLife = glGetAttribLocation(hProg, "aLife"); s_hSize = glGetAttribLocation(hProg, "aSize"); hProg = GetShaderProgram(PARTICLE_RENDER_PROGRAM); s_hRendMatrixVP = glGetUniformLocation(hProg, "uMatrixVP"); s_hTexType = glGetUniformLocation(hProg, "uTexType"); s_hRendTexture = glGetUniformLocation(hProg, "uTexture"); s_hRendPosition = glGetAttribLocation(hProg, "aPosition"); s_hRendColor = glGetAttribLocation(hProg, "aColor"); s_hRendLife = glGetAttribLocation(hProg, "aLife"); s_hRendSize = glGetAttribLocation(hProg, "aSize"); #if defined (WINDOWS) // Lastly, we need to enable point size control in the vertex shader. // On windows, Vakz runs in a compatibility context, so it is necessary // to enable this setting so that the fixed function glPointSize() is not // used instead. On android (running a pure ES 3.0 environment) this call // is not needed and would probably produce an error if it was used. glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); #endif s_nStaticInit = 1; } // Kick off timer m_timer.Start(); // Create and allocate the two buffers that will be swapped // when performing transform feedback glGenBuffers(2, m_arVBOs); pZeroBuffer = new char[m_nParticleCount * PARTICLE_DATA_SIZE]; memset(pZeroBuffer, 0, m_nParticleCount * PARTICLE_DATA_SIZE); glBindBuffer(GL_ARRAY_BUFFER, m_arVBOs[0]); glBufferData(GL_ARRAY_BUFFER, PARTICLE_DATA_SIZE * m_nParticleCount, pZeroBuffer, GL_DYNAMIC_COPY); glBindBuffer(GL_ARRAY_BUFFER, m_arVBOs[1]); glBufferData(GL_ARRAY_BUFFER, PARTICLE_DATA_SIZE * m_nParticleCount, pZeroBuffer, GL_DYNAMIC_COPY); delete [] pZeroBuffer; }
//***************************************************************************** // Render //***************************************************************************** void Quad::Render() { int hProgram = GetShaderProgram(QUAD_PROGRAM); int hPosition = -1; int hTexCoord = -1; int hType = -1; int hColor = -1; int hTexture = -1; if (m_nVisible != 0) { // Unbind VBO (using client-side arrays) glBindBuffer(GL_ARRAY_BUFFER, 0); // Switch to the Quad program glUseProgram(hProgram); glActiveTexture(GL_TEXTURE0); // Retreive variable locations hPosition = glGetAttribLocation(hProgram, "aPosition"); hTexCoord = glGetAttribLocation(hProgram, "aTexCoord"); hType = glGetUniformLocation(hProgram, "uType"); hColor = glGetUniformLocation(hProgram, "uColor"); hTexture = glGetUniformLocation(hProgram, "uTexture"); // Set up vertex arrays glEnableVertexAttribArray(hPosition); glEnableVertexAttribArray(hTexCoord); glVertexAttribPointer(hPosition, 2, GL_FLOAT, GL_FALSE, 0, m_arPosition); glVertexAttribPointer(hTexCoord, 2, GL_FLOAT, GL_FALSE, 0, m_arTexCoord); // Set uniforms glUniform1i(hType, (m_pTexture == 0) ? 0 : 1); glUniform4fv(hColor, 1, m_arColor); glUniform1i(hTexture, 0); // Set texture unit to 0. // Bind texture if (m_pTexture != 0) { m_pTexture->Bind(); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // If the border is enabled, draw a border. if (m_nBorderEnable != 0) { // Disable any texture features as the border // cannot be rendered with a texture... or at least // it shouldn't be. glUniform1i(hType, 0); glBindTexture(GL_TEXTURE_2D, 0); glUniform4fv(hColor, 1, m_arBorderColor); glLineWidth(m_fBorderWidth); glDrawArrays(GL_LINE_LOOP, 0, 4); // Reset the line width glLineWidth(1.0f); } } }