GPU: More work on OpenGL renderer

This commit is contained in:
Connor McLaughlin
2019-09-13 00:18:13 +10:00
parent 4706a906d5
commit aea7a18ac2
20 changed files with 655 additions and 412 deletions

View File

@ -43,6 +43,8 @@
<ClInclude Include="display_renderer_gl.h" />
<ClInclude Include="display_timing.h" />
<ClInclude Include="fastjmp.h" />
<ClInclude Include="gl_program.h" />
<ClInclude Include="gl_texture.h" />
<ClInclude Include="hdd_image.h" />
<ClInclude Include="jit_code_buffer.h" />
<ClInclude Include="object.h" />
@ -59,6 +61,8 @@
<ClCompile Include="display_renderer.cpp" />
<ClCompile Include="display_renderer_gl.cpp" />
<ClCompile Include="display_timing.cpp" />
<ClCompile Include="gl_program.cpp" />
<ClCompile Include="gl_texture.cpp" />
<ClCompile Include="hdd_image.cpp" />
<ClCompile Include="jit_code_buffer.cpp" />
<ClCompile Include="object.cpp" />

View File

@ -17,6 +17,8 @@
<ClInclude Include="display_timing.h" />
<ClInclude Include="jit_code_buffer.h" />
<ClInclude Include="state_wrapper.h" />
<ClInclude Include="gl_program.h" />
<ClInclude Include="gl_texture.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="hdd_image.cpp" />
@ -31,6 +33,8 @@
<ClCompile Include="display_timing.cpp" />
<ClCompile Include="jit_code_buffer.cpp" />
<ClCompile Include="state_wrapper.cpp" />
<ClCompile Include="gl_program.cpp" />
<ClCompile Include="gl_texture.cpp" />
</ItemGroup>
<ItemGroup>
<Natvis Include="bitfield.natvis" />

171
src/common/gl_program.cpp Normal file
View File

@ -0,0 +1,171 @@
#include "gl_program.h"
#include "YBaseLib/Log.h"
#include <array>
Log_SetChannel(GL);
namespace GL {
Program::Program() = default;
Program::~Program()
{
Destroy();
}
GLuint Program::CompileShader(GLenum type, const char* source)
{
GLuint id = glCreateShader(type);
std::array<const GLchar*, 1> sources = {{source}};
std::array<GLint, 1> source_lengths = {{static_cast<GLint>(std::strlen(source))}};
glShaderSource(id, static_cast<GLsizei>(sources.size()), sources.data(), source_lengths.data());
glCompileShader(id);
GLint status = GL_FALSE;
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
GLint info_log_length = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
if (status == GL_FALSE || info_log_length > 0)
{
std::string info_log;
info_log.resize(info_log_length + 1);
glGetShaderInfoLog(id, info_log_length, &info_log_length, &info_log[0]);
if (status == GL_TRUE)
{
Log_ErrorPrintf("Shader compiled with warnings:\n%s", info_log.c_str());
}
else
{
Log_ErrorPrintf("Shader failed to compile:\n%s", info_log.c_str());
glDeleteShader(id);
return 0;
}
}
return id;
}
bool Program::Compile(const char* vertex_shader, const char* fragment_shader)
{
GLuint vertex_shader_id = CompileShader(GL_VERTEX_SHADER, vertex_shader);
if (vertex_shader_id == 0)
return false;
GLuint fragment_shader_id = CompileShader(GL_FRAGMENT_SHADER, fragment_shader);
if (fragment_shader_id == 0)
{
glDeleteShader(vertex_shader_id);
return false;
}
m_program_id = glCreateProgram();
glAttachShader(m_program_id, vertex_shader_id);
glAttachShader(m_program_id, fragment_shader_id);
return true;
}
void Program::BindAttribute(GLuint index, const char* name)
{
glBindAttribLocation(m_program_id, index, name);
}
void Program::BindDefaultAttributes()
{
BindAttribute(0, "a_position");
BindAttribute(1, "a_texcoord");
BindAttribute(2, "a_color");
}
void Program::BindFragData(GLuint index /*= 0*/, const char* name /*= "ocol0"*/)
{
glBindFragDataLocation(m_program_id, index, name);
}
bool Program::Link()
{
glLinkProgram(m_program_id);
glDeleteShader(m_vertex_shader_id);
m_vertex_shader_id = 0;
glDeleteShader(m_fragment_shader_id);
m_fragment_shader_id = 0;
GLint status = GL_FALSE;
glGetProgramiv(m_program_id, GL_LINK_STATUS, &status);
GLint info_log_length = 0;
glGetProgramiv(m_program_id, GL_INFO_LOG_LENGTH, &info_log_length);
if (status == GL_FALSE || info_log_length > 0)
{
std::string info_log;
info_log.resize(info_log_length + 1);
glGetProgramInfoLog(m_program_id, info_log_length, &info_log_length, &info_log[0]);
if (status == GL_TRUE)
{
Log_ErrorPrintf("Program linked with warnings:\n%s", info_log.c_str());
}
else
{
Log_ErrorPrintf("Program failed to link:\n%s", info_log.c_str());
glDeleteProgram(m_program_id);
m_program_id = 0;
return false;
}
}
return true;
}
void Program::Bind()
{
glUseProgram(m_program_id);
}
void Program::Destroy()
{
if (m_vertex_shader_id != 0)
{
glDeleteShader(m_vertex_shader_id);
m_vertex_shader_id = 0;
}
if (m_fragment_shader_id != 0)
{
glDeleteShader(m_fragment_shader_id);
m_fragment_shader_id = 0;
}
if (m_program_id != 0)
{
glDeleteProgram(m_program_id);
m_program_id = 0;
}
}
u32 Program::RegisterUniform(const char* name)
{
u32 id = static_cast<u32>(m_uniform_locations.size());
m_uniform_locations.push_back(glGetUniformLocation(m_program_id, name));
return id;
}
void Program::Uniform1ui(u32 index, u32 value)
{
Assert(index < m_uniform_locations.size());
const int location = m_uniform_locations[index];
if (location >= 0)
glUniform1ui(location, value);
}
void Program::Uniform4f(u32 index, float x, float y, float z, float w)
{
Assert(index < m_uniform_locations.size());
const int location = m_uniform_locations[index];
if (location >= 0)
glUniform4f(location, x, y, z, w);
}
} // namespace GL

42
src/common/gl_program.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include "glad.h"
#include "types.h"
#include <vector>
namespace GL {
class Program
{
public:
Program();
~Program();
static GLuint CompileShader(GLenum type, const char* source);
bool IsVaild() const { return m_program_id != 0; }
bool Compile(const char* vertex_shader, const char* fragment_shader);
void BindAttribute(GLuint index, const char* name);
void BindDefaultAttributes();
void BindFragData(GLuint index = 0, const char* name = "ocol0");
bool Link();
void Bind();
void Destroy();
u32 RegisterUniform(const char* name);
void Uniform1ui(u32 index, u32 value);
void Uniform4f(u32 index, float x, float y, float z, float w);
private:
GLuint m_program_id = 0;
GLuint m_vertex_shader_id = 0;
GLuint m_fragment_shader_id = 0;
std::vector<GLint> m_uniform_locations;
};
} // namespace GL

29
src/common/gl_texture.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "gl_texture.h"
#include "YBaseLib/Log.h"
Log_SetChannel(GL);
namespace GL {
Texture::Texture(u32 width, u32 height, GLenum format, GLenum type, const void* data /* = nullptr */,
bool linear_filter /* = false */)
: m_width(width), m_height(height)
{
glGenTextures(1, &m_id);
glBindTexture(GL_TEXTURE_2D, m_id);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
}
Texture::~Texture()
{
glDeleteTextures(1, &m_id);
}
void Texture::Bind()
{
glBindTexture(GL_TEXTURE_2D, m_id);
}
} // namespace GL

24
src/common/gl_texture.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include "glad.h"
#include "types.h"
namespace GL {
class Texture
{
public:
Texture(u32 width, u32 height, GLenum format, GLenum type, const void* data = nullptr, bool linear_filter = false);
~Texture();
GLuint GetGLId() const { return m_id; }
u32 GetWidth() const { return m_width; }
u32 GetHeight() const { return m_height; }
void Bind();
private:
GLuint m_id;
u32 m_width;
u32 m_height;
};
} // namespace GL