OpenGL

贡献者:Sadalmelik 类别:代码 时间:2019-12-13 11:39:11 收藏数:227 评分:8.3
返回上页 举报此文章
请选择举报理由:




收藏到我的文章 改错字
//Application
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include<fstream>
#include<string>
#include<sstream>
#include "Renderer.h"
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
#include "IndexBuffer.h"
#include "VertexArray.h"
#include "Shader.h"
#include "Texture.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "imgui/imgui.h"
#include "imgui/imgui_impl_opengl3.h"
#include "imgui/imgui_impl_glfw.h"
#include "tests/TestClearColor.h"
#include "tests/TestMenu.h"
#include "tests/TestTexture2D.h"
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
// Decide GL+GLSL versions
#if __APPLE__
// GL 3.2 + GLSL 150
const char* glsl_version = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
#else
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
#endif
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(960, 540, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
/*Initialize glew library*/
if (glewInit() != GLEW_OK)
{
std::cout << "GLEW init error!" << std::endl;
}
std::cout << glGetString(GL_VERSION) << std::endl;
{
GLCall(glEnable(GL_BLEND));
GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
//GLCall(glBlendFunc(GL_ZERO,GL_ONE ));
Renderer renderer;
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
ImGui::StyleColorsDark();
test::Test * currentTest = nullptr;
test::TestMenu * testMenu = new test::TestMenu(currentTest);
currentTest = testMenu;
testMenu->RegisterTest<test::TestClearColor>("Clear Color");
testMenu->RegisterTest<test::TestTexture2D>("Texture 2D" );
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
renderer.Clear();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
if (currentTest)
{
currentTest->OnUpdate(0.0f);
currentTest->OnRender();
ImGui::Begin("Test");
if (currentTest != testMenu && ImGui::Button("<-"))
{
delete currentTest;
currentTest = testMenu;
}
currentTest->OnImGuiRender();
ImGui::End();
}
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
delete currentTest;
if (currentTest != testMenu)
{
delete testMenu;
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
glfwTerminate();
return 0;
}
//IndexBuffer
#include "IndexBuffer.h"
#include "Renderer.h"
IndexBuffer::IndexBuffer(const unsigned int * data, unsigned int count)
:m_Count(count)
{
ASSERT(sizeof(unsigned int) == sizeof(GLuint));
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof (unsigned int),
data, GL_STATIC_DRAW));
}
IndexBuffer::~IndexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void IndexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
}
void IndexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
//Renderer
#include "Renderer.h"
#include <iostream>
void GLClearError()
{
while (glGetError() != GL_NO_ERROR);
}
bool GLLogCall(const char* function, const char*file, int line)
{
while (GLenum error = glGetError())
{
std::cout << "[OpenGL Error] " << error << " " << function << " "
<< file << " " << ":" << line << std::endl;
return false;
}
return true;
}
void Renderer::Draw(const VertexArray & va, const IndexBuffer & ib, const Shader & shader) const
{
shader.Bind();
va.Bind();
ib.Bind();
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr));
}
void Renderer::Clear() const
{
glClear(GL_COLOR_BUFFER_BIT);
}
//Shader
#include "Shader.h"
#include "GL/glew.h"
#include <iostream>
#include<fstream>
#include<sstream>
#include"Renderer.h"
Shader::Shader(const std::string & filepath)
:m_FilePath(filepath), m_RendererID(0)
{
auto [vertexSource,fragmentSource] = ParseShader();
m_RendererID = CreateShader(vertexSource, fragmentSource);
}
Shader::~Shader()
{
GLCall(glDeleteProgram(m_RendererID));
}
void Shader::Bind() const
{
GLCall(glUseProgram(m_RendererID));
}
void Shader::UnBind() const
{
GLCall(glUseProgram(0));
}
void Shader::SetUniform4f(const std::string & name, float v0, float v1, float v2, float v3)
{
GLCall(glUniform4f(GetUniformLocation(name), v0, v1, v2, v3));
}
void Shader::SetUniform1i(const std::string & name, int value)
{
GLCall(glUniform1i(GetUniformLocation(name), value));
}
void Shader::SetUniformMat4f(const std::string & name, const glm::mat4 & matrix)
{
GLCall(glUniformMatrix4fv(GetUniformLocation(name), 1,GL_FALSE,&matrix[0][0]));
}
bool Shader::CompileShader()
{
return false;
}
int Shader::GetUniformLocation(const std::string & name)
{
if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
{
return m_UniformLocationCache[name];
}
GLCall(int location = glGetUniformLocation(m_RendererID, name.c_str()));
if (location == -1)
{
std::cout << "Warning: uniform '" << name << "' doesn't exist!" << std::endl;
}
m_UniformLocationCache[name] = location;
return location;
}
std::tuple<std::string,std::string> Shader::ParseShader()
{
std::ifstream stream(m_FilePath);
enum class ShaderType
{
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
std::string line;
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != std::string::npos)
{
if (line.find("vertex") != std::string::npos)
{
//set mode to vertex
type = ShaderType::VERTEX;
}
else if (line.find("fragment") != std::string::npos)
{
//set mode to fragment
type = ShaderType::FRAGMENT;
}
}
else
{
ss[(int)type] << line << '\n';
}
}
return { ss[0].str(),ss[1].str() };
}
unsigned int Shader::CompileShader(unsigned int type, const std::string& source)
{
GLCall(unsigned int id = glCreateShader(type));
const char* src = source.c_str();
GLCall(glShaderSource(id, 1, &src, nullptr));
GLCall(glCompileShader(id));
//TODO: Error handling
int result;
GLCall(glGetShaderiv(id, GL_COMPILE_STATUS, &result));
if (result == GL_FALSE)
{
int length;
GLCall(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length));
char* message = (char*)alloca(length * sizeof(char));
GLCall(glGetShaderInfoLog(id, length, &length, message));
std::cout << "Failed to compile shader!"
<< (type == GL_VERTEX_SHADER ? "vertex" : "fragment")
<< " shader!"
<< std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(id));
return 0;
}
return id;
}
unsigned int Shader::CreateShader(const std::string& vertexShader,
const std::string& fragmentShader)
{
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
//Texture
#include "Texture.h"
#include "stb_image/stb_image.h"
Texture::Texture(const std::string& path)
:m_RendererID(0),m_FilePath(path),m_Width(0),m_Height(0),m_BPP(0)
{
stbi_set_flip_vertically_on_load(1);
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);
GLCall(glGenTextures(1,&m_RendererID));
GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer));
GLCall(glBindTexture(GL_TEXTURE_2D, 0));
if (m_LocalBuffer)
{
stbi_image_free(m_LocalBuffer);
}
}
Texture::~Texture()
{
GLCall(glDeleteTextures(1, &m_RendererID));
}
void Texture::Bind(unsigned int slot) const
{
GLCall(glActiveTexture(GL_TEXTURE0 + slot));
GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
}
void Texture::Unbind() const
{
GLCall(glBindTexture(GL_TEXTURE_2D, 0));
}
//VertexArray
#include "VertexArray.h"
#include "Renderer.h"
#include "VertexBufferLayout.h"
VertexArray::VertexArray()
{
GLCall(glGenVertexArrays(1, &m_RendererID));
GLCall(glBindVertexArray(m_RendererID));
}
VertexArray::~VertexArray()
{
GLCall(glDeleteVertexArrays(1, &m_RendererID));
}
void VertexArray::AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout)
{
Bind();
vb.Bind();
const auto& elements = layout.GetElements();
unsigned int offset = 0;
for (unsigned int i = 0; i<elements.size(); i++ )
{
const auto& element = elements[i];
GLCall(glEnableVertexAttribArray(i));
GLCall(glVertexAttribPointer(i, element.count, element.type,
element.normalized,layout.GetStride(), (const void*)offset));
offset += element.count * VertexBufferElement::GetSizeOfType(element.type);
}
}
void VertexArray::Bind() const
{
GLCall(glBindVertexArray(m_RendererID));
}
void VertexArray::UnBind() const
{
GLCall(glBindVertexArray(0));
}
//VertexBuffer
#include "VertexBuffer.h"
#include "Renderer.h"
VertexBuffer::VertexBuffer(const void * data, unsigned int size)
{
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
GLCall(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
}
VertexBuffer::~VertexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void VertexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
}
void VertexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
//VertexBufferLayout
#pragma once
#include <vector>
#include "Renderer.h"
struct VertexBufferElement
{
unsigned int type;
unsigned int count;
unsigned char normalized;
static unsigned int GetSizeOfType(unsigned int type)
{
switch (type)
{
case GL_FLOAT: return 4;
case GL_UNSIGNED_INT: return 4;
case GL_UNSIGNED_BYTE: return 1;
}
ASSERT(false);
return 0;
}
};
class VertexBufferLayout
{
private:
std::vector<VertexBufferElement> m_Elements;
unsigned int m_Stride;
public:
VertexBufferLayout() :m_Stride(0) {}
//~VertexBufferLayout();
template<typename T>
void Push(unsigned int count)
{
static_assert(false);
}
template <>
void Push<float>(unsigned int count)
{
m_Elements.push_back({ GL_FLOAT , count , GL_FALSE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_FLOAT)*count;
}
template <>
void Push<unsigned int>(unsigned int count)
{
m_Elements.push_back({ GL_UNSIGNED_INT , count , GL_FALSE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_UNSIGNED_INT)*count;
}
template <>
void Push<unsigned char>(unsigned int count)
{
m_Elements.push_back({ GL_UNSIGNED_BYTE , count , GL_TRUE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_UNSIGNED_BYTE)*count;
}
inline unsigned int GetStride() const { return m_Stride; }
inline std::vector<VertexBufferElement> GetElements() const { return m_Elements; }
};
//TestClearColor
#include "TestClearColor.h"
#include "Renderer.h"
#include "imgui/imgui.h"
namespace test {
TestClearColor::TestClearColor(): m_ClearColor{0.2f,0.3f,0.4f,1.0f}
{
}
TestClearColor::~TestClearColor()
{
}
void TestClearColor::OnUpdate(float deltaTime)
{
}
void TestClearColor::OnRender()
{
GLCall(glClearColor(m_ClearColor[0], m_ClearColor[1],
m_ClearColor[2], m_ClearColor[3]));
GLCall(glClear(GL_COLOR_BUFFER_BIT));
}
void TestClearColor::OnImGuiRender()
{
ImGui::ColorEdit4("Clear Color", m_ClearColor);
}
}
//TestMenu
#include "TestMenu.h"
#include "imgui/imgui.h"
namespace test {
TestMenu::TestMenu(Test *& currentTestPointer)
:m_CurrentTest(currentTestPointer)
{
}
TestMenu::~TestMenu()
{
}
void TestMenu::OnImGuiRender()
{
for (auto& test : m_Tests)
{
if(ImGui::Button(test.first.c_str()))
{
m_CurrentTest= test.second();
}
}
}
}
//TestTexture2D
#include "TestTexture2D.h"
namespace test {
TestTexture2D::TestTexture2D() :
m_TranslationA(200, 200, 0),
m_TranslationB(400, 200, 0),
m_Positions{
-50.0f, -50.9f, 0.0f, 0.0f,//0
50.0f, -50.0f, 1.0f, 0.0f,//1
50.0f, 50.0f, 1.0f, 1.0f,//2
-50.0f, 50.0f, 0.0f, 1.0f//3
},
m_Indices{
0, 1, 2,
2, 3, 0
},
m_Proj(glm::ortho(0.0f, 960.0f, 0.0f, 540.0f, -1.0f, 1.0f)),
m_View(glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0)))
{
GLCall(glEnable(GL_BLEND));
GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
m_Va = std::make_unique<VertexArray>();
m_Vb = std::make_unique<VertexBuffer>(m_Positions,4*4*sizeof(float));
VertexBufferLayout layout;
layout.Push<float>(2);
layout.Push<float>(2);
m_Va->AddBuffer(*m_Vb, layout);
m_Ib = std::make_unique<IndexBuffer>(m_Indices, 6);
m_Shader= std::make_unique<Shader>("res/shaders/Basic.shader");
m_Shader->Bind();
m_Texture=std::make_unique<Texture>("res/textures/HZJT.png");
m_Shader->SetUniform4f("u_Color", 0.8f, 0.3f, 0.8f, 1.0f);
m_Shader->SetUniform1i("u_Texture", 0);
}
TestTexture2D::~TestTexture2D()
{
}
void TestTexture2D::OnUpdate(float deltaTime)
{
}
void TestTexture2D::OnRender()
{
GLCall(glClearColor(0.0f,0.0f,0.0f,0.0f));
Renderer renderer;
m_Texture->Bind();
{
/* m_ModelA = glm::translate(glm::mat4(1.0f),m_TranslationA);
m_MvpA = m_Proj * m_View *m_ModelA;
m_Shader->Bind();
m_Shader->SetUniformMat4f("u_MVP", m_MvpA);*/
auto modelA = glm::translate(glm::mat4(1.0f), m_TranslationA);
auto mvpA = m_Proj * m_View*modelA;
m_Shader->Bind();
m_Shader->SetUniformMat4f("u_MVP", mvpA);
renderer.Draw(*m_Va, *m_Ib, *m_Shader);
}
{
/* m_ModelB = glm::translate(glm::mat4(1.0f), m_TranslationB);
m_MvpB = m_Proj * m_View *m_ModelB;
m_Shader->Bind();
m_Shader->SetUniformMat4f("u_MVP", m_MvpB);*/
auto modelB = glm::translate(glm::mat4(1.0f), m_TranslationB);
auto mvpB = m_Proj * m_View*modelB;
m_Shader->Bind();
m_Shader->SetUniformMat4f("u_MVP", mvpB);
renderer.Draw(*m_Va, *m_Ib, *m_Shader);
}
}
void TestTexture2D::OnImGuiRender()
{
ImGui::SliderFloat3("Translation A", &m_TranslationA.x, 0.0f, 960.0f);
ImGui::SliderFloat3("Translation B", &m_TranslationB.x, 0.0f, 960.0f);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}
}
//shader
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texCoord;
out vec2 v_TexCoord;
uniform mat4 u_MVP;
void main()
{
gl_Position = u_MVP*position;
v_TexCoord = texCoord;
};
#shader fragment
#version 330 core
layout (location = 0) out vec4 color;
in vec2 v_TexCoord;
uniform vec4 u_Color;
uniform sampler2D u_Texture;
void main()
{
vec4 texColor = texture(u_Texture, v_TexCoord);
color = texColor;
};
声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。
文章热度:
文章难度:
文章质量:
说明:系统根据文章的热度、难度、质量自动认证,已认证的文章将参与打字排名!

本文打字排名TOP20

用户更多文章推荐