665 lines
20 KiB
C++
665 lines
20 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "glad/gl.h"
|
|
#include "opengl.h"
|
|
#include "directxmath/directxmath.h"
|
|
#include "test.h"
|
|
#include "font.h"
|
|
#include "window.h"
|
|
#include "bresenham.h"
|
|
#include "file.h"
|
|
#include "world.h"
|
|
#include "view.h"
|
|
#include "non_block.h"
|
|
#include "minecraft.h"
|
|
#include "hud.h"
|
|
|
|
struct line_location {
|
|
struct {
|
|
unsigned int position;
|
|
unsigned int normal;
|
|
unsigned int texture;
|
|
unsigned int block_position;
|
|
} attrib;
|
|
struct {
|
|
unsigned int transform;
|
|
} uniform;
|
|
};
|
|
static unsigned int line_program;
|
|
static line_location line_location;
|
|
static unsigned int line_vertex_array_object;
|
|
static unsigned int line_instance_buffer;
|
|
|
|
struct quad_location {
|
|
struct {
|
|
unsigned int texture_sampler;
|
|
} uniform;
|
|
};
|
|
static unsigned int quad_program;
|
|
static quad_location quad_location;
|
|
|
|
struct lighting_location {
|
|
struct {
|
|
unsigned int position_sampler;
|
|
unsigned int normal_sampler;
|
|
unsigned int color_sampler;
|
|
unsigned int quadratic;
|
|
unsigned int linear;
|
|
unsigned int eye;
|
|
unsigned int mouse_position;
|
|
unsigned int mouse_position2;
|
|
|
|
unsigned int lights;
|
|
} uniform;
|
|
struct {
|
|
unsigned int lights;
|
|
} binding;
|
|
};
|
|
static unsigned int lighting_program;
|
|
static lighting_location lighting_location;
|
|
|
|
static XMFLOAT3 mouse_position;
|
|
static bool mouse_position_sample = true;
|
|
static XMVECTOR mouse_ray_position;
|
|
|
|
static unsigned int light_uniform_buffer;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// globals
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
unsigned int empty_vertex_array_object = -1;
|
|
unsigned int quad_index_buffer = -1;
|
|
|
|
float current_time;
|
|
float last_frame_time;
|
|
|
|
font::font * terminus_fonts;
|
|
|
|
void load_quad_index_buffer()
|
|
{
|
|
uint8_t const data[] = {
|
|
1, 0, 2, 3,
|
|
};
|
|
int const data_size = (sizeof (data));
|
|
|
|
glGenBuffers(1, &quad_index_buffer);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void load_quad_program()
|
|
{
|
|
unsigned int program = compile_from_files("shader/quad.vert",
|
|
NULL,
|
|
"shader/quad.frag");
|
|
|
|
quad_location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler");
|
|
printf("quad program:\n");
|
|
printf(" uniforms:\n texture_sampler %u\n",
|
|
quad_location.uniform.texture_sampler);
|
|
|
|
quad_program = program;
|
|
}
|
|
|
|
void load_lighting_program()
|
|
{
|
|
unsigned int program = compile_from_files("shader/quad.vert",
|
|
NULL,
|
|
"shader/lighting.frag");
|
|
|
|
lighting_location.uniform.position_sampler = glGetUniformLocation(program, "PositionSampler");
|
|
lighting_location.uniform.normal_sampler = glGetUniformLocation(program, "NormalSampler");
|
|
lighting_location.uniform.color_sampler = glGetUniformLocation(program, "ColorSampler");
|
|
lighting_location.uniform.quadratic = glGetUniformLocation(program, "Quadratic");
|
|
lighting_location.uniform.linear = glGetUniformLocation(program, "Linear");
|
|
lighting_location.uniform.eye = glGetUniformLocation(program, "Eye");
|
|
lighting_location.uniform.mouse_position = glGetUniformLocation(program, "MousePosition");
|
|
lighting_location.uniform.mouse_position2 = glGetUniformLocation(program, "MousePosition2");
|
|
lighting_location.uniform.lights = glGetUniformBlockIndex(program, "Lights");
|
|
|
|
fprintf(stderr, "lighting program:\n");
|
|
fprintf(stderr, " uniforms:\n position_sampler %u normal_sampler %u color_sampler %u lights %u\n",
|
|
lighting_location.uniform.position_sampler,
|
|
lighting_location.uniform.normal_sampler,
|
|
lighting_location.uniform.color_sampler,
|
|
lighting_location.uniform.lights);
|
|
|
|
lighting_location.binding.lights = 0;
|
|
glUniformBlockBinding(program, lighting_location.uniform.lights, lighting_location.binding.lights);
|
|
|
|
lighting_program = program;
|
|
}
|
|
|
|
void load_light_uniform_buffer()
|
|
{
|
|
light_uniform_buffer = load_uniform_buffer("minecraft/global.lights.vtx");
|
|
}
|
|
|
|
struct target_name {
|
|
enum {
|
|
POSITION = 0,
|
|
NORMAL = 1,
|
|
COLOR = 2,
|
|
};
|
|
};
|
|
|
|
template <int render_target_count>
|
|
struct geometry_buffer {
|
|
unsigned int framebuffer;
|
|
unsigned int target[render_target_count]; // textures
|
|
unsigned int renderbuffer;
|
|
int initialized;
|
|
int width;
|
|
int height;
|
|
};
|
|
|
|
struct target_type {
|
|
GLint internal_format;
|
|
GLenum attachment;
|
|
};
|
|
|
|
static geometry_buffer<3> geometry_buffer_pnc = {};
|
|
static target_type const geometry_buffer_pnc_types[3] = {
|
|
[target_name::POSITION] = { GL_RGBA16F, GL_COLOR_ATTACHMENT0 },
|
|
[target_name::NORMAL] = { GL_RGBA16F, GL_COLOR_ATTACHMENT1 },
|
|
[target_name::COLOR] = { GL_RGBA8, GL_COLOR_ATTACHMENT2 },
|
|
};
|
|
|
|
template <int render_target_count>
|
|
void init_geometry_buffer(geometry_buffer<render_target_count>& geometry_buffer, target_type const * const types)
|
|
{
|
|
int width = window::width;
|
|
int height = window::height;
|
|
|
|
if ((geometry_buffer.initialized == 1) && (width == geometry_buffer.width) && (height == geometry_buffer.height)) {
|
|
return;
|
|
}
|
|
|
|
if (geometry_buffer.initialized) {
|
|
glDeleteFramebuffers(1, &geometry_buffer.framebuffer);
|
|
glDeleteTextures(render_target_count, geometry_buffer.target);
|
|
glDeleteRenderbuffers(1, &geometry_buffer.renderbuffer);
|
|
}
|
|
glGenFramebuffers(1, &geometry_buffer.framebuffer);
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, geometry_buffer.framebuffer);
|
|
|
|
glGenTextures(render_target_count, geometry_buffer.target);
|
|
for (int i = 0; i < render_target_count; i++) {
|
|
glBindTexture(GL_TEXTURE_2D, geometry_buffer.target[i]);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, types[i].internal_format, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, types[i].attachment, GL_TEXTURE_2D, geometry_buffer.target[i], 0);
|
|
}
|
|
static_assert(render_target_count == 3);
|
|
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
|
glDrawBuffers(3, attachments); // bound to GL_DRAW_FRAMEBUFFER
|
|
|
|
glGenRenderbuffers(1, &geometry_buffer.renderbuffer);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, geometry_buffer.renderbuffer);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, geometry_buffer.renderbuffer);
|
|
|
|
assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
|
|
geometry_buffer.initialized = 1;
|
|
geometry_buffer.width = width;
|
|
geometry_buffer.height = height;
|
|
}
|
|
|
|
extern "C" {
|
|
void * SDL_GL_GetProcAddress(const char *proc);
|
|
}
|
|
|
|
struct short_point {
|
|
short x;
|
|
short y;
|
|
short z;
|
|
};
|
|
static_assert((sizeof (short_point)) == 6);
|
|
|
|
short_point line_points[128];
|
|
static int line_point_ix = 0;
|
|
|
|
void append_line_point(int x, int y, int z)
|
|
{
|
|
if (line_point_ix == 1)
|
|
return;
|
|
|
|
global_entry * const entry = world_lookup(x, y, z);
|
|
if (entry != NULL) {
|
|
line_points[line_point_ix].x = x;
|
|
line_points[line_point_ix].y = y;
|
|
line_points[line_point_ix].z = z;
|
|
line_point_ix += 1;
|
|
}
|
|
}
|
|
|
|
void load_line_program()
|
|
{
|
|
unsigned int program = compile_from_files("shader/line.vert",
|
|
NULL,
|
|
"shader/line.frag");
|
|
|
|
line_location.attrib.position = glGetAttribLocation(program, "Position");
|
|
line_location.attrib.normal = glGetAttribLocation(program, "Normal");
|
|
line_location.attrib.texture = glGetAttribLocation(program, "Texture");
|
|
|
|
line_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
|
|
|
|
printf("line program:\n");
|
|
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n",
|
|
line_location.attrib.position,
|
|
line_location.attrib.normal,
|
|
line_location.attrib.texture,
|
|
line_location.attrib.block_position);
|
|
|
|
line_location.uniform.transform = glGetUniformLocation(program, "Transform");
|
|
printf(" uniforms:\n transform %u\n\n",
|
|
line_location.uniform.transform);
|
|
|
|
line_program = program;
|
|
}
|
|
|
|
void load_line_vertex_attributes()
|
|
{
|
|
glGenVertexArrays(1, &line_vertex_array_object);
|
|
glBindVertexArray(line_vertex_array_object);
|
|
|
|
glVertexBindingDivisor(0, 0);
|
|
glVertexBindingDivisor(1, 1);
|
|
|
|
glEnableVertexAttribArray(line_location.attrib.position);
|
|
glVertexAttribFormat(line_location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
|
|
glVertexAttribBinding(line_location.attrib.position, 0);
|
|
|
|
glEnableVertexAttribArray(line_location.attrib.normal);
|
|
glVertexAttribFormat(line_location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
|
|
glVertexAttribBinding(line_location.attrib.normal, 0);
|
|
|
|
glEnableVertexAttribArray(line_location.attrib.texture);
|
|
glVertexAttribFormat(line_location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
|
|
glVertexAttribBinding(line_location.attrib.texture, 0);
|
|
|
|
glEnableVertexAttribArray(line_location.attrib.block_position);
|
|
glVertexAttribFormat(line_location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
|
|
glVertexAttribBinding(line_location.attrib.block_position, 1);
|
|
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
void load_line_instance_buffer()
|
|
{
|
|
glBindBuffer(GL_ARRAY_BUFFER, line_instance_buffer);
|
|
glBufferData(GL_ARRAY_BUFFER, (sizeof (short_point)) * line_point_ix, line_points, GL_STATIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
struct line_state {
|
|
struct {
|
|
int x;
|
|
int y;
|
|
int z;
|
|
} point[2];
|
|
};
|
|
static line_state line_state = {};
|
|
|
|
void load_line()
|
|
{
|
|
line_point_ix = 0;
|
|
bresenham(line_state.point[0].x, line_state.point[0].y, line_state.point[0].z,
|
|
line_state.point[1].x, line_state.point[1].y, line_state.point[1].z,
|
|
append_line_point);
|
|
|
|
load_line_instance_buffer();
|
|
}
|
|
|
|
void load_line_point_from_eye(int point_ix)
|
|
{
|
|
int x = XMVectorGetX(view::state.eye);
|
|
int y = XMVectorGetY(view::state.eye);
|
|
int z = XMVectorGetZ(view::state.eye);
|
|
|
|
line_state.point[point_ix].x = x;
|
|
line_state.point[point_ix].y = z;
|
|
line_state.point[point_ix].z = y;
|
|
|
|
load_line();
|
|
}
|
|
|
|
void load(const char * source_path)
|
|
{
|
|
g_source_path_length = strlen(source_path);
|
|
assert(source_path[g_source_path_length - 1] != '/');
|
|
g_source_path = source_path;
|
|
|
|
fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress);
|
|
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// minecraft (drawing data)
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
minecraft::load();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// world (collision data)
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
load_world();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// view
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
view::load();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// font
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
font::load_shader();
|
|
|
|
terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length);
|
|
font::load_fonts(terminus_fonts, font::terminus, font::terminus_length);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// quad
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
glGenVertexArrays(1, &empty_vertex_array_object);
|
|
load_quad_program();
|
|
load_quad_index_buffer();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// lighting
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
load_lighting_program();
|
|
load_light_uniform_buffer();
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// line
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
load_line_program();
|
|
load_line_vertex_attributes();
|
|
|
|
glGenBuffers(1, &line_instance_buffer);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// non_block
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
non_block::load_program();
|
|
non_block::load_index_buffer();
|
|
non_block::load_per_vertex_buffer();
|
|
non_block::load_vertex_attributes();
|
|
}
|
|
|
|
float _ry = 0.0;
|
|
|
|
struct light_parameters {
|
|
float quadratic;
|
|
float linear;
|
|
};
|
|
light_parameters lighting = {
|
|
.quadratic = 1.0,
|
|
.linear = 1.0
|
|
};
|
|
|
|
void update_keyboard(int up, int down, int left, int right)
|
|
{
|
|
//float forward = (0.1f * up + -0.1f * down);
|
|
//float strafe = (-0.1f * left + 0.1f * right);
|
|
//view::third_person::apply_translation(forward, strafe, 0);
|
|
}
|
|
|
|
const int max_joysticks = 8;
|
|
static int last_frame_start[max_joysticks] = {};
|
|
|
|
void update_joystick(int joystick_index,
|
|
float lx, float ly, float rx, float ry, float tl, float tr,
|
|
int up, int down, int left, int right,
|
|
int a, int b, int x, int y,
|
|
int leftshoulder, int rightshoulder,
|
|
int start)
|
|
{
|
|
float forward = -ly * 0.5;
|
|
float strafe = lx * 0.5;
|
|
float elevation = (tl - tr) * 0.5;
|
|
float delta_yaw = rx * -0.035;
|
|
float delta_pitch = ry * -0.035;
|
|
view::third_person::apply_transform(forward, strafe, elevation,
|
|
delta_yaw, delta_pitch);
|
|
view::apply_fov(0.01 * up + -0.01 * down);
|
|
|
|
lighting.quadratic += 0.01 * a + -0.01 * b;
|
|
if (lighting.quadratic < 0.0f)
|
|
lighting.quadratic = 0.0f;
|
|
lighting.linear += 0.01 * x + -0.01 * y;
|
|
if (lighting.linear < 0.0f)
|
|
lighting.linear = 0.0f;
|
|
|
|
if (leftshoulder) {
|
|
load_line_point_from_eye(0);
|
|
}
|
|
if (rightshoulder) {
|
|
load_line_point_from_eye(1);
|
|
}
|
|
if (start && (start != last_frame_start[joystick_index])) {
|
|
mouse_position_sample = !mouse_position_sample;
|
|
printf("mouse_position_sample: %d\n", mouse_position_sample);
|
|
}
|
|
last_frame_start[joystick_index] = start;
|
|
}
|
|
|
|
void update(float time)
|
|
{
|
|
current_time = time;
|
|
|
|
view::update_transforms();
|
|
}
|
|
|
|
void draw_quad()
|
|
{
|
|
glUseProgram(quad_program);
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[1]);
|
|
|
|
glUniform1i(quad_location.uniform.texture_sampler, 0);
|
|
|
|
glBindVertexArray(empty_vertex_array_object);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
|
|
|
|
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
|
|
}
|
|
|
|
static inline bool near_zero(float a)
|
|
{
|
|
return (fabsf(a) < 0.00001f);
|
|
}
|
|
|
|
void draw_lighting()
|
|
{
|
|
glUseProgram(lighting_program);
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[0]);
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[1]);
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[2]);
|
|
|
|
glUniform1i(lighting_location.uniform.position_sampler, 0);
|
|
glUniform1i(lighting_location.uniform.normal_sampler, 1);
|
|
glUniform1i(lighting_location.uniform.color_sampler, 2);
|
|
|
|
float quadratic = near_zero(lighting.quadratic) ? 0.0 : 1.0f / lighting.quadratic;
|
|
float linear = near_zero(lighting.linear) ? 0.0 : 1.0f / lighting.linear;
|
|
glUniform1f(lighting_location.uniform.quadratic, quadratic);
|
|
glUniform1f(lighting_location.uniform.linear, linear);
|
|
|
|
|
|
XMFLOAT3 eye;
|
|
XMStoreFloat3(&eye, view::state.eye);
|
|
glUniform3fv(lighting_location.uniform.eye, 1, (float*)&eye);
|
|
glUniform3fv(lighting_location.uniform.mouse_position, 1, (float*)&mouse_position);
|
|
/*
|
|
printf("m0: %f %f %f\nm1: %f %f %f\n",
|
|
mouse_position.x, mouse_position.y, mouse_position.z,
|
|
position2.x, position2.y, position2.z);
|
|
*/
|
|
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, lighting_location.binding.lights, light_uniform_buffer);
|
|
|
|
glBindVertexArray(empty_vertex_array_object);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
|
|
|
|
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
|
|
}
|
|
|
|
static inline int popcount(int x)
|
|
{
|
|
return __builtin_popcount(x);
|
|
}
|
|
|
|
/*
|
|
void draw_line()
|
|
{
|
|
if (line_point_ix == 0)
|
|
return;
|
|
|
|
glUseProgram(line_program);
|
|
|
|
glBlendFunc(GL_ONE, GL_ZERO);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glUniformMatrix4fv(line_location.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
|
|
|
//glEnable(GL_CULL_FACE);
|
|
//glCullFace(GL_FRONT);
|
|
//glFrontFace(GL_CCW);
|
|
|
|
glBindVertexArray(line_vertex_array_object);
|
|
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
|
int line_instance_vertex_size = (sizeof (short_point));
|
|
glBindVertexBuffer(1, line_instance_buffer, 0, line_instance_vertex_size);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
|
|
|
int configuration = 63;
|
|
int element_count = 6 * popcount(configuration);
|
|
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
|
int instance_count = line_point_ix;
|
|
int base_instance = 0;
|
|
if (instance_count - base_instance <= 0)
|
|
return;
|
|
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count - base_instance, base_instance);
|
|
}
|
|
*/
|
|
|
|
int clamp(int n, int high)
|
|
{
|
|
if (n < 0)
|
|
return 0;
|
|
if (n >= high)
|
|
return high;
|
|
return n;
|
|
}
|
|
|
|
void update_mouse(int x, int y)
|
|
{
|
|
if (!mouse_position_sample)
|
|
return;
|
|
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, geometry_buffer_pnc.framebuffer);
|
|
glReadBuffer(geometry_buffer_pnc_types[target_name::POSITION].attachment);
|
|
|
|
/*
|
|
x = clamp(x, geometry_buffer_pnc.width);
|
|
y = clamp(y, geometry_buffer_pnc.height);
|
|
glReadPixels(x,
|
|
geometry_buffer_pnc.height - y,
|
|
1, // width
|
|
1, // height
|
|
GL_RGB,
|
|
GL_FLOAT,
|
|
(void*)&mouse_position);
|
|
*/
|
|
|
|
{
|
|
float mx = (2.0f * (float)x) / geometry_buffer_pnc.width - 1.0f;
|
|
float my = 1.0f - (2.0f * (float)y) / geometry_buffer_pnc.height;
|
|
/*
|
|
XMVECTOR mouse_world = XMVector3Transform(mouse_clip, inverse);
|
|
XMVECTOR ray = XMVector3Normalize(mouse_world - view::state.eye);
|
|
mouse_ray_position = ray;
|
|
|
|
XMVECTOR ray_start = view::state.eye;
|
|
XMVECTOR ray_end = ray_start + ray * 20.0f;
|
|
*/
|
|
|
|
XMVECTOR mouse_clip = XMVectorSet(mx, my, -1, 0);
|
|
|
|
XMMATRIX projection_inverse = XMMatrixInverse(NULL, view::state.projection_transform);
|
|
XMMATRIX view_inverse = XMMatrixInverse(NULL, view::state.view_transform);
|
|
|
|
XMVECTOR mouse_view = XMVector3Transform(mouse_clip, projection_inverse);
|
|
mouse_ray_position = mouse_view;
|
|
|
|
mouse_view = XMVectorSetZ(mouse_view, -1);
|
|
XMVECTOR ray = XMVector3Normalize(XMVector3TransformNormal(mouse_view, view_inverse));
|
|
|
|
XMVECTOR ray_start = view::state.eye;
|
|
XMVECTOR ray_end = ray_start + ray * 20.0f;
|
|
|
|
line_state.point[0].x = roundf(XMVectorGetX(ray_start));
|
|
line_state.point[0].z = roundf(XMVectorGetY(ray_start));
|
|
line_state.point[0].y = roundf(XMVectorGetZ(ray_start));
|
|
|
|
line_state.point[1].x = roundf(XMVectorGetX(ray_end));
|
|
line_state.point[1].z = roundf(XMVectorGetY(ray_end));
|
|
line_state.point[1].y = roundf(XMVectorGetZ(ray_end));
|
|
load_line();
|
|
}
|
|
}
|
|
|
|
void draw()
|
|
{
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClearDepth(-1.0f);
|
|
|
|
// possibly re-initialize geometry buffer if window width/height changes
|
|
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, geometry_buffer_pnc.framebuffer);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
minecraft::draw();
|
|
//draw_line();
|
|
non_block::draw();
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
draw_lighting();
|
|
//draw_quad();
|
|
hud::draw();
|
|
|
|
last_frame_time = current_time;
|
|
}
|