mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
add rudimentary shaders and machinery
This commit is contained in:
parent
bc99cc867b
commit
d61deae68d
31
cmake/shaders.cmake
Normal file
31
cmake/shaders.cmake
Normal file
@ -0,0 +1,31 @@
|
||||
file(WRITE ${shaders_h} "#pragma once
|
||||
#include <string_view>
|
||||
namespace shaders {
|
||||
")
|
||||
|
||||
set(idx 0)
|
||||
set(idx_is_path FALSE)
|
||||
while(${idx} LESS ${CMAKE_ARGC})
|
||||
if(idx_is_path)
|
||||
set(shader_path ${CMAKE_ARGV${idx}})
|
||||
cmake_path(GET shader_path STEM shader_name)
|
||||
file(READ ${shader_path} content)
|
||||
file(APPEND ${shaders_h} "
|
||||
inline constexpr std::string_view ${shader_name} = R\"shader(${content}
|
||||
)shader\";
|
||||
")
|
||||
else()
|
||||
if(${CMAKE_ARGV${idx}} STREQUAL "--")
|
||||
set(idx_is_path TRUE)
|
||||
endif()
|
||||
endif()
|
||||
math(EXPR idx "${idx} + 1")
|
||||
endwhile()
|
||||
|
||||
foreach(idx RANGE ${CMAKE_ARGC})
|
||||
endforeach()
|
||||
|
||||
file(APPEND ${shaders_h} "
|
||||
} // namespace shaders
|
||||
")
|
||||
|
41
misc/holder.h
Normal file
41
misc/holder.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
template <typename T, void (*Deleter)(T)>
|
||||
struct MoveOnlyHolder {
|
||||
MoveOnlyHolder(T t)
|
||||
: t_{std::move(t)} {}
|
||||
|
||||
MoveOnlyHolder(MoveOnlyHolder&& other)
|
||||
: t_{std::exchange(other.t_, {})} {}
|
||||
|
||||
~MoveOnlyHolder() noexcept {
|
||||
Deleter(t_);
|
||||
}
|
||||
|
||||
operator T() const {
|
||||
return t_;
|
||||
}
|
||||
|
||||
private:
|
||||
T t_;
|
||||
};
|
@ -1,6 +1,21 @@
|
||||
cmake_path(SET GENERATED_HEADERS NORMALIZE ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
cmake_path(SET SHADERS_H NORMALIZE ${GENERATED_HEADERS}/shaders.h)
|
||||
set(SHADERS
|
||||
shaders/fragment.glsl
|
||||
shaders/vertex.glsl
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${SHADERS_H}
|
||||
COMMAND ${CMAKE_COMMAND} -Dshaders_h=${SHADERS_H} -P ../cmake/shaders.cmake -- ${SHADERS}
|
||||
DEPENDS ../cmake/shaders.cmake ${SHADERS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
dyna_gl.h
|
||||
HardwareInternal.h
|
||||
ShaderProgram.h
|
||||
${SHADERS_H}
|
||||
)
|
||||
set(CPPS
|
||||
HardwareClipper.cpp
|
||||
@ -15,12 +30,8 @@ set(CPPS
|
||||
lnxscreenmode.cpp
|
||||
)
|
||||
|
||||
# These are excluded.
|
||||
#opengl.cpp
|
||||
#renderer.cpp
|
||||
#Direct3D.cpp
|
||||
|
||||
add_library(renderer STATIC ${HEADERS} ${CPPS})
|
||||
target_include_directories(renderer PRIVATE ${GENERATED_HEADERS})
|
||||
target_link_libraries(renderer PRIVATE
|
||||
SDL2::SDL2
|
||||
bitmap
|
||||
|
@ -21,12 +21,16 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <SDL.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define DECLARE_OPENGL
|
||||
#include "dyna_gl.h"
|
||||
|
||||
#include "byteswap.h"
|
||||
#include "pserror.h"
|
||||
#include "mono.h"
|
||||
@ -43,9 +47,8 @@
|
||||
#include "HardwareInternal.h"
|
||||
#include "../Descent3/args.h"
|
||||
#include "NewBitmap.h"
|
||||
|
||||
#define DECLARE_OPENGL
|
||||
#include "dyna_gl.h"
|
||||
#include "shaders.h"
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#include "win/arb_extensions.h"
|
||||
@ -64,6 +67,21 @@ extern uint8_t Renderer_initted;
|
||||
renderer_type Renderer_type = RENDERER_OPENGL;
|
||||
int WindowGL = 0;
|
||||
|
||||
struct Renderer {
|
||||
Renderer() : shader_{shaders::vertex, shaders::fragment, {
|
||||
vertexAttrib(3, GL_FLOAT, GL_FALSE, &PosColorUV2Vertex::pos, "in_pos"),
|
||||
vertexAttrib(4, GL_FLOAT, GL_FALSE, &PosColorUV2Vertex::color, "in_color"),
|
||||
vertexAttrib(2, GL_FLOAT, GL_FALSE, &PosColorUV2Vertex::uv0, "in_uv0"),
|
||||
vertexAttrib(2, GL_FLOAT, GL_FALSE, &PosColorUV2Vertex::uv1, "in_uv1")
|
||||
}} {
|
||||
shader_.Use();
|
||||
}
|
||||
|
||||
private:
|
||||
ShaderProgram<PosColorUV2Vertex> shader_;
|
||||
};
|
||||
std::optional<Renderer> gRenderer;
|
||||
|
||||
#ifndef GL_UNSIGNED_SHORT_5_5_5_1
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#endif
|
||||
@ -502,6 +520,8 @@ int opengl_Setup(oeApplication *app, int *width, int *height) {
|
||||
reinterpret_cast<oeLnxApplication *>(ParentApplication)->set_sizepos(0, 0, *width, *height);
|
||||
}
|
||||
|
||||
gRenderer.emplace();
|
||||
|
||||
Already_loaded = 1;
|
||||
return 1;
|
||||
}
|
||||
@ -700,6 +720,8 @@ void opengl_Close(const bool just_resizing) {
|
||||
|
||||
mem_free(delete_list);
|
||||
|
||||
gRenderer.reset();
|
||||
|
||||
if (GSDLGLContext) {
|
||||
SDL_GL_MakeCurrent(NULL, NULL);
|
||||
SDL_GL_DeleteContext(GSDLGLContext);
|
||||
|
179
renderer/ShaderProgram.h
Normal file
179
renderer/ShaderProgram.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "dyna_gl.h"
|
||||
#include "holder.h"
|
||||
|
||||
template <typename E>
|
||||
struct VertexAttrib {
|
||||
using EnclosingType = E;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLboolean normalized;
|
||||
uintptr_t offset;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
template <typename EnclosingType, typename MemberType>
|
||||
VertexAttrib<EnclosingType> vertexAttrib(GLint size, GLenum type, GLboolean normalized, MemberType EnclosingType::*member, std::string name) {
|
||||
EnclosingType e;
|
||||
return VertexAttrib<EnclosingType>{
|
||||
size,
|
||||
type,
|
||||
normalized,
|
||||
reinterpret_cast<uintptr_t>(&(e.*member)) - reinterpret_cast<uintptr_t>(&e),
|
||||
std::move(name)
|
||||
};
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
struct VertexBuffer {
|
||||
VertexBuffer(GLuint program,
|
||||
std::vector<VertexAttrib<V>> attribs,
|
||||
size_t vertex_count,
|
||||
GLenum bufferType,
|
||||
V const* initialData = nullptr)
|
||||
: vao_{outval(dglGenVertexArrays)},
|
||||
vbo_{outval(dglGenBuffers)} {
|
||||
dglBindVertexArray(vao_);
|
||||
dglBindBuffer(GL_ARRAY_BUFFER, vbo_);
|
||||
dglBufferData(GL_ARRAY_BUFFER,
|
||||
vertex_count * sizeof(PosColorUV2Vertex),
|
||||
initialData,
|
||||
bufferType);
|
||||
|
||||
for (GLint i{}; i < attribs.size(); i++) {
|
||||
dglEnableVertexAttribArray(i);
|
||||
dglVertexAttribPointer(i,
|
||||
attribs[i].size,
|
||||
attribs[i].type,
|
||||
attribs[i].normalized,
|
||||
sizeof(V),
|
||||
reinterpret_cast<void*>(attribs[i].offset));
|
||||
dglBindAttribLocation(program, i, attribs[i].name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateData(size_t vtx_offset, size_t vtx_count, V const* vertices) const {
|
||||
dglBindBuffer(GL_ARRAY_BUFFER, vbo_);
|
||||
dglBufferSubData(GL_ARRAY_BUFFER, vtx_offset * sizeof(V), vtx_count * sizeof(V), vertices);
|
||||
}
|
||||
|
||||
private:
|
||||
static void DeleteBuffer(GLuint id) {
|
||||
dglDeleteBuffers(1, &id);
|
||||
}
|
||||
static void DeleteVertexArray(GLuint id) {
|
||||
dglDeleteVertexArrays(1, &id);
|
||||
}
|
||||
template <typename Generator>
|
||||
GLuint outval(Generator&& gen) {
|
||||
GLuint id;
|
||||
gen(1, &id);
|
||||
return id;
|
||||
}
|
||||
|
||||
MoveOnlyHolder<GLuint, DeleteVertexArray> vao_;
|
||||
MoveOnlyHolder<GLuint, DeleteBuffer> vbo_;
|
||||
};
|
||||
|
||||
template <GLenum kType>
|
||||
struct Shader {
|
||||
static_assert(kType == GL_VERTEX_SHADER || kType == GL_FRAGMENT_SHADER);
|
||||
|
||||
explicit Shader(std::string_view src)
|
||||
: id_{dglCreateShader(kType)} {
|
||||
if (id_ == 0) {
|
||||
throw std::runtime_error("failed to create shader");
|
||||
}
|
||||
|
||||
char const* srcptr = src.data();
|
||||
GLint srclen = src.size();
|
||||
dglShaderSource(id_, 1, &srcptr, &srclen);
|
||||
dglCompileShader(id_);
|
||||
|
||||
GLint compile_result;
|
||||
dglGetShaderiv(id_, GL_COMPILE_STATUS, &compile_result);
|
||||
if (compile_result != GL_TRUE) {
|
||||
GLsizei log_length = 0;
|
||||
GLchar message[1024];
|
||||
dglGetShaderInfoLog(id_, 1024, &log_length, message);
|
||||
throw std::runtime_error(std::string{message, static_cast<size_t>(log_length)});
|
||||
}
|
||||
}
|
||||
|
||||
GLuint id() const {
|
||||
ASSERT(id_ != 0);
|
||||
return id_;
|
||||
}
|
||||
|
||||
private:
|
||||
static void DeleteShader(GLuint id) {
|
||||
dglDeleteShader(id);
|
||||
}
|
||||
MoveOnlyHolder<GLuint, DeleteShader> id_;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct ShaderProgram {
|
||||
explicit ShaderProgram(std::string_view vertexSrc, std::string_view fragmentSrc, std::vector<VertexAttrib<V>> attribs)
|
||||
: id_{dglCreateProgram()}, vertex_{vertexSrc}, fragment_{fragmentSrc}, vbo_{id_, std::move(attribs), MAX_POINTS_IN_POLY, GL_DYNAMIC_DRAW} {
|
||||
if (id_ == 0) {
|
||||
throw std::runtime_error("error creating GL program");
|
||||
}
|
||||
|
||||
dglAttachShader(id_, vertex_.id());
|
||||
dglAttachShader(id_, fragment_.id());
|
||||
|
||||
dglLinkProgram(id_);
|
||||
|
||||
GLint link_result;
|
||||
dglGetProgramiv(id_, GL_LINK_STATUS, &link_result);
|
||||
if (link_result != GL_TRUE)
|
||||
{
|
||||
GLsizei log_length = 0;
|
||||
GLchar message[1024];
|
||||
dglGetProgramInfoLog(id_, 1024, &log_length, message);
|
||||
throw std::runtime_error(std::string{message, static_cast<size_t>(log_length)});
|
||||
}
|
||||
}
|
||||
|
||||
void Use() const {
|
||||
dglUseProgram(id_);
|
||||
}
|
||||
|
||||
void Unuse() const {
|
||||
dglUseProgram(0);
|
||||
}
|
||||
|
||||
private:
|
||||
static void DeleteProgram(GLuint id) {
|
||||
dglDeleteProgram(id);
|
||||
}
|
||||
|
||||
MoveOnlyHolder<GLuint, DeleteProgram> id_;
|
||||
Shader<GL_VERTEX_SHADER> vertex_;
|
||||
Shader<GL_FRAGMENT_SHADER> fragment_;
|
||||
VertexBuffer<V> vbo_;
|
||||
};
|
@ -146,15 +146,28 @@ static module *LoadOpenGLDLL(const char *dllname) {
|
||||
#define DYNAEXTERN(Name) extern FnPtr<decltype(Name)> const d##Name
|
||||
#endif
|
||||
|
||||
DYNAEXTERN(glAttachShader);
|
||||
DYNAEXTERN(glBindAttribLocation);
|
||||
DYNAEXTERN(glBindBuffer);
|
||||
DYNAEXTERN(glBindTexture);
|
||||
DYNAEXTERN(glBindVertexArray);
|
||||
DYNAEXTERN(glBlendFunc);
|
||||
DYNAEXTERN(glBufferData);
|
||||
DYNAEXTERN(glBufferSubData);
|
||||
DYNAEXTERN(glClear);
|
||||
DYNAEXTERN(glClearColor);
|
||||
DYNAEXTERN(glColor3ub);
|
||||
DYNAEXTERN(glColor4f);
|
||||
DYNAEXTERN(glColor4ub);
|
||||
DYNAEXTERN(glColorPointer);
|
||||
DYNAEXTERN(glCompileShader);
|
||||
DYNAEXTERN(glCreateProgram);
|
||||
DYNAEXTERN(glCreateShader);
|
||||
DYNAEXTERN(glDeleteBuffers);
|
||||
DYNAEXTERN(glDeleteProgram);
|
||||
DYNAEXTERN(glDeleteShader);
|
||||
DYNAEXTERN(glDeleteTextures);
|
||||
DYNAEXTERN(glDeleteVertexArrays);
|
||||
DYNAEXTERN(glDepthFunc);
|
||||
DYNAEXTERN(glDepthMask);
|
||||
DYNAEXTERN(glDepthRange);
|
||||
@ -163,15 +176,23 @@ DYNAEXTERN(glDisableClientState);
|
||||
DYNAEXTERN(glDrawArrays);
|
||||
DYNAEXTERN(glEnable);
|
||||
DYNAEXTERN(glEnableClientState);
|
||||
DYNAEXTERN(glEnableVertexAttribArray);
|
||||
DYNAEXTERN(glFlush);
|
||||
DYNAEXTERN(glFogf);
|
||||
DYNAEXTERN(glFogfv);
|
||||
DYNAEXTERN(glFogi);
|
||||
DYNAEXTERN(glGenBuffers);
|
||||
DYNAEXTERN(glGenVertexArrays);
|
||||
DYNAEXTERN(glGetError);
|
||||
DYNAEXTERN(glGetIntegerv);
|
||||
DYNAEXTERN(glGetProgramInfoLog);
|
||||
DYNAEXTERN(glGetProgramiv);
|
||||
DYNAEXTERN(glGetShaderInfoLog);
|
||||
DYNAEXTERN(glGetShaderiv);
|
||||
DYNAEXTERN(glGetString);
|
||||
DYNAEXTERN(glGetStringi);
|
||||
DYNAEXTERN(glHint);
|
||||
DYNAEXTERN(glLinkProgram);
|
||||
DYNAEXTERN(glLoadIdentity);
|
||||
DYNAEXTERN(glLoadMatrixf);
|
||||
DYNAEXTERN(glMatrixMode);
|
||||
@ -180,6 +201,7 @@ DYNAEXTERN(glPixelStorei);
|
||||
DYNAEXTERN(glPolygonOffset);
|
||||
DYNAEXTERN(glReadPixels);
|
||||
DYNAEXTERN(glScissor);
|
||||
DYNAEXTERN(glShaderSource);
|
||||
DYNAEXTERN(glTexCoord2f);
|
||||
DYNAEXTERN(glTexCoord4fv);
|
||||
DYNAEXTERN(glTexCoordPointer);
|
||||
@ -187,9 +209,8 @@ DYNAEXTERN(glTexEnvf);
|
||||
DYNAEXTERN(glTexImage2D);
|
||||
DYNAEXTERN(glTexParameteri);
|
||||
DYNAEXTERN(glTexSubImage2D);
|
||||
DYNAEXTERN(glVertex2i);
|
||||
DYNAEXTERN(glVertex3f);
|
||||
DYNAEXTERN(glVertex3fv);
|
||||
DYNAEXTERN(glUseProgram);
|
||||
DYNAEXTERN(glVertexAttribPointer);
|
||||
DYNAEXTERN(glVertexPointer);
|
||||
DYNAEXTERN(glViewport);
|
||||
|
||||
|
26
renderer/shaders/fragment.glsl
Normal file
26
renderer/shaders/fragment.glsl
Normal file
@ -0,0 +1,26 @@
|
||||
#version 150 core
|
||||
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(0);
|
||||
}
|
29
renderer/shaders/vertex.glsl
Normal file
29
renderer/shaders/vertex.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
#version 150 core
|
||||
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
in vec3 in_pos;
|
||||
in vec4 in_color;
|
||||
in vec2 in_uv0;
|
||||
in vec2 in_uv1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user