mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-14 19:15:46 -04:00
GPU: More work on OpenGL renderer
This commit is contained in:
@ -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" />
|
||||
|
@ -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
171
src/common/gl_program.cpp
Normal 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
42
src/common/gl_program.h
Normal 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
29
src/common/gl_texture.cpp
Normal 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
24
src/common/gl_texture.h
Normal 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
|
Reference in New Issue
Block a user