fill in the rest of the GL functions. finally

master
jp9000 2013-10-12 20:18:05 -07:00
parent e591256922
commit 9577ddcf9b
12 changed files with 329 additions and 30 deletions

View File

@ -97,8 +97,8 @@ EXPORT void device_enable_blending(device_t device, bool enable);
EXPORT void device_enable_depthtest(device_t device, bool enable);
EXPORT void device_enable_stenciltest(device_t device, bool enable);
EXPORT void device_enable_stencilwrite(device_t device, bool enable);
EXPORT void device_enable_color(device_t device, bool red, bool blue,
bool green, bool alpha);
EXPORT void device_enable_color(device_t device, bool red, bool green,
bool blue, bool alpha);
EXPORT void device_blendfunction(device_t device, enum gs_blend_type src,
enum gs_blend_type dest);
EXPORT void device_depthfunction(device_t device, enum gs_depth_test test);
@ -125,7 +125,6 @@ EXPORT void device_frustum(device_t device, float left, float right,
float top, float bottom, float znear, float zfar);
EXPORT void device_perspective(device_t device, float fovy, float aspect,
float znear, float zfar);
EXPORT void device_set_view_matrix(device_t device, struct matrix3 *mat);
EXPORT void device_projection_push(device_t device);
EXPORT void device_projection_pop(device_t device);

View File

@ -1130,8 +1130,8 @@ void device_enable_stencilwrite(device_t device, bool enable)
device->zstencilStateChanged = true;
}
void device_enable_color(device_t device, bool red, bool blue,
bool green, bool alpha)
void device_enable_color(device_t device, bool red, bool green,
bool blue, bool alpha)
{
if (device->blendState.redEnabled == red &&
device->blendState.greenEnabled == green &&

View File

@ -91,8 +91,8 @@ EXPORT void device_enable_blending(device_t device, bool enable);
EXPORT void device_enable_depthtest(device_t device, bool enable);
EXPORT void device_enable_stenciltest(device_t device, bool enable);
EXPORT void device_enable_stencilwrite(device_t device, bool enable);
EXPORT void device_enable_color(device_t device, bool red, bool blue,
bool green, bool alpha);
EXPORT void device_enable_color(device_t device, bool red, bool green,
bool blue, bool alpha);
EXPORT void device_blendfunction(device_t device, enum gs_blend_type src,
enum gs_blend_type dest);
EXPORT void device_depthfunction(device_t device, enum gs_depth_test test);
@ -119,7 +119,6 @@ EXPORT void device_frustum(device_t device, float left, float right,
float top, float bottom, float znear, float zfar);
EXPORT void device_perspective(device_t device, float fovy, float aspect,
float znear, float zfar);
EXPORT void device_set_view_matrix(device_t device, struct matrix3 *mat);
EXPORT void device_projection_push(device_t device);
EXPORT void device_projection_pop(device_t device);

View File

@ -96,12 +96,24 @@ static inline bool gl_tex_param_i(GLenum target, GLenum param, GLint val)
return gl_success("glTexParameteri");
}
static inline bool gl_active_texture(GLenum texture)
static inline bool gl_active_texture(GLenum texture_id)
{
glActiveTexture(texture);
glActiveTexture(texture_id);
return gl_success("glActiveTexture");
}
static inline bool gl_enable(GLenum capability)
{
glEnable(capability);
return gl_success("glEnable");
}
static inline bool gl_disable(GLenum capability)
{
glDisable(capability);
return gl_success("glDisable");
}
extern bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels,
GLenum format, GLint internal_format, bool compressed,
uint32_t width, uint32_t height, uint32_t size, void ***p_data);

View File

@ -45,6 +45,7 @@ indexbuffer_t device_create_indexbuffer(device_t device,
ib->data = indices;
ib->dynamic = flags & GS_DYNAMIC;
ib->num = num;
ib->width = width;
ib->size = width * num;
ib->type = type;
ib->gl_type = type == GS_UNSIGNED_LONG ? GL_UNSIGNED_INT :

View File

@ -77,6 +77,9 @@ static bool gl_add_param(struct gs_shader *shader, struct shader_var *var,
if (!gl_success("glGetUniformLocation"))
return false;
if (param.type == SHADER_PARAM_TEXTURE)
glUniform1i(param.param, param.texture_id);
return true;
}
@ -155,6 +158,12 @@ static inline bool gl_add_attrib(struct gs_shader *shader,
if (attrib.attrib == -1)
return false;
if (attrib.type == ATTRIB_TARGET) {
glBindFragDataLocation(shader->program, 0, pa->name.array);
if (!gl_success("glBindFragDataLocation"))
return false;
}
da_push_back(shader->attribs, &attrib);
return true;
}

View File

@ -17,6 +17,18 @@
#include "gl-subsystem.h"
static void clear_textures(struct gs_device *device)
{
GLenum i;
for (i = 0; i < GS_MAX_TEXTURES; i++) {
if (device->cur_textures[i]) {
gl_active_texture(GL_TEXTURE0 + i);
gl_bind_texture(device->cur_textures[i]->gl_target, 0);
device->cur_textures[i] = NULL;
}
}
}
void convert_sampler_info(struct gs_sampler_state *sampler,
struct gs_sampler_info *info)
{
@ -45,6 +57,10 @@ device_t device_create(struct gs_init_data *info)
if (!gl_success("glBindProgramPipeline"))
goto fail;
#ifdef _DEBUG
gl_enable(GL_DEBUG_OUTPUT);
#endif
return device;
fail:
@ -63,6 +79,7 @@ void device_destroy(device_t device)
if (device->pipeline)
glDeleteProgramPipelines(1, &device->pipeline);
da_free(device->proj_stack);
da_free(device->fbos);
gl_platform_destroy(device->plat);
bfree(device);
@ -191,13 +208,16 @@ void device_load_texture(device_t device, texture_t tex, int unit)
{
struct shader_param *param;
struct gs_sampler_state *sampler;
struct gs_texture *cur_tex = device->cur_textures[unit];
/* need a pixel shader to properly bind textures */
if (!device->cur_pixel_shader)
tex = NULL;
if (device->cur_textures[unit] == tex)
if (cur_tex == tex)
return;
if (cur_tex && cur_tex->gl_target != tex->gl_target)
gl_bind_texture(cur_tex->gl_target, 0);
device->cur_textures[unit] = tex;
param = get_texture_param(device, unit);
@ -323,6 +343,7 @@ void device_load_pixelshader(device_t device, shader_t pixelshader)
if (!gl_success("glUseProgramStages"))
goto fail;
clear_textures(device);
return;
fail:
@ -581,144 +602,290 @@ fail:
void device_beginscene(device_t device)
{
clear_textures(device);
}
static inline bool can_render(device_t device)
{
if (!device->cur_vertex_buffer) {
blog(LOG_ERROR, "No vertex buffer specified");
return false;
}
if (!device->cur_vertex_buffer) {
blog(LOG_ERROR, "No vertex buffer specified");
return false;
}
if (!device->cur_vertex_buffer) {
blog(LOG_ERROR, "No vertex buffer specified");
return false;
}
return true;
}
void device_draw(device_t device, enum gs_draw_mode draw_mode,
uint32_t start_vert, uint32_t num_verts)
{
struct gs_index_buffer *ib = device->cur_index_buffer;
GLenum topology = convert_gs_topology(draw_mode);
if (!can_render(device))
goto fail;
if (ib) {
glDrawElements(topology, num_verts, ib->gl_type,
(const GLvoid*)(start_vert * ib->width));
if (!gl_success("glDrawElements"))
goto fail;
} else {
glDrawArrays(topology, start_vert, num_verts);
if (!gl_success("glDrawArrays"))
goto fail;
}
return;
fail:
blog(LOG_ERROR, "device_draw (GL) failed");
}
void device_endscene(device_t device)
{
}
void device_load_swapchain(device_t device, swapchain_t swapchain)
{
/* does nothing */
}
void device_clear(device_t device, uint32_t clear_flags,
struct vec4 *color, float depth, uint8_t stencil)
{
}
GLbitfield gl_flags = 0;
void device_present(device_t device)
{
if (clear_flags & GS_CLEAR_COLOR) {
glClearColor(color->x, color->y, color->x, color->w);
gl_flags |= GL_COLOR_BUFFER_BIT;
}
if (clear_flags & GS_CLEAR_DEPTH) {
glClearDepth(depth);
gl_flags |= GL_DEPTH_BUFFER_BIT;
}
if (clear_flags & GS_CLEAR_STENCIL) {
glClearStencil(stencil);
gl_flags |= GL_STENCIL_BUFFER_BIT;
}
glClear(clear_flags);
if (!gl_success("glClear"))
blog(LOG_ERROR, "device_clear (GL) failed");
}
void device_setcullmode(device_t device, enum gs_cull_mode mode)
{
if (device->cur_cull_mode == mode)
return;
if (device->cur_cull_mode == GS_NEITHER)
gl_enable(GL_CULL_FACE);
device->cur_cull_mode = mode;
if (mode == GS_BACK)
glCullFace(GL_BACK);
else if (mode == GS_FRONT)
glCullFace(GL_FRONT);
else
gl_disable(GL_CULL_FACE);
}
enum gs_cull_mode device_getcullmode(device_t device)
{
return device->cur_cull_mode;
}
void device_enable_blending(device_t device, bool enable)
{
if (enable)
gl_enable(GL_BLEND);
else
gl_disable(GL_BLEND);
}
void device_enable_depthtest(device_t device, bool enable)
{
if (enable)
gl_enable(GL_DEPTH_TEST);
else
gl_disable(GL_DEPTH_TEST);
}
void device_enable_stenciltest(device_t device, bool enable)
{
if (enable)
gl_enable(GL_STENCIL_TEST);
else
gl_disable(GL_STENCIL_TEST);
}
void device_enable_stencilwrite(device_t device, bool enable)
{
if (enable)
glStencilMask(0xFFFFFFFF);
else
glStencilMask(0);
}
void device_enable_color(device_t device, bool red, bool blue,
bool green, bool alpha)
void device_enable_color(device_t device, bool red, bool green,
bool blue, bool alpha)
{
glColorMask(red, green, blue, alpha);
}
void device_blendfunction(device_t device, enum gs_blend_type src,
enum gs_blend_type dest)
{
GLenum gl_src = convert_gs_blend_type(src);
GLenum gl_dst = convert_gs_blend_type(dest);
glBlendFunc(gl_src, gl_dst);
if (!gl_success("glBlendFunc"))
blog(LOG_ERROR, "device_blendfunction (GL) failed");
}
void device_depthfunction(device_t device, enum gs_depth_test test)
{
GLenum gl_test = convert_gs_depth_test(test);
glDepthFunc(gl_test);
if (!gl_success("glDepthFunc"))
blog(LOG_ERROR, "device_depthfunction (GL) failed");
}
void device_stencilfunction(device_t device, enum gs_stencil_side side,
enum gs_depth_test test)
{
GLenum gl_side = convert_gs_stencil_side(side);
GLenum gl_test = convert_gs_depth_test(test);
glStencilFuncSeparate(gl_side, gl_test, 0, 0xFFFFFFFF);
if (!gl_success("glStencilFuncSeparate"))
blog(LOG_ERROR, "device_stencilfunction (GL) failed");
}
void device_stencilop(device_t device, enum gs_stencil_side side,
enum gs_stencil_op fail, enum gs_stencil_op zfail,
enum gs_stencil_op zpass)
{
GLenum gl_side = convert_gs_stencil_side(side);
GLenum gl_fail = convert_gs_stencil_op(fail);
GLenum gl_zfail = convert_gs_stencil_op(zfail);
GLenum gl_zpass = convert_gs_stencil_op(zpass);
glStencilOpSeparate(gl_side, gl_fail, gl_zfail, gl_zpass);
if (!gl_success("glStencilOpSeparate"))
blog(LOG_ERROR, "device_stencilop (GL) failed");
}
void device_enable_fullscreen(device_t device, bool enable)
{
/* TODO */
}
int device_fullscreen_enabled(device_t device)
{
/* TODO */
return false;
}
void device_setdisplaymode(device_t device,
const struct gs_display_mode *mode)
{
/* TODO */
}
void device_getdisplaymode(device_t device,
struct gs_display_mode *mode)
{
/* TODO */
}
void device_setcolorramp(device_t device, float gamma, float brightness,
float contrast)
{
/* TODO */
}
void device_setviewport(device_t device, int x, int y, int width,
int height)
{
glViewport(x, y, width, height);
if (!gl_success("glViewport"))
blog(LOG_ERROR, "device_setviewport (GL) failed");
device->cur_viewport.x = x;
device->cur_viewport.y = y;
device->cur_viewport.cx = width;
device->cur_viewport.cy = height;
}
void device_getviewport(device_t device, struct gs_rect *rect)
{
*rect = device->cur_viewport;
}
void device_setscissorrect(device_t device, struct gs_rect *rect)
{
glScissor(rect->x, rect->y, rect->cx, rect->cy);
if (!gl_success("glScissor"))
blog(LOG_ERROR, "device_setscissorrect (GL) failed");
}
void device_ortho(device_t device, float left, float right,
float top, float bottom, float znear, float zfar)
{
matrix4_ortho(&device->cur_proj, left, right, top, bottom, znear, zfar);
}
void device_frustum(device_t device, float left, float right,
float top, float bottom, float znear, float zfar)
{
matrix4_frustum(&device->cur_proj, left, right, top, bottom,
znear, zfar);
}
void device_perspective(device_t device, float fovy, float aspect,
float znear, float zfar)
{
}
void device_set_view_matrix(device_t device, struct matrix3 *mat)
{
matrix4_perspective(&device->cur_proj, fovy, aspect, znear, zfar);
}
void device_projection_push(device_t device)
{
da_push_back(device->proj_stack, &device->cur_proj);
}
void device_projection_pop(device_t device)
{
struct matrix4 *end;
if (!device->proj_stack.num)
return;
end = da_end(device->proj_stack);
device->cur_proj = *end;
da_pop_back(device->proj_stack);
}
void swapchain_destroy(swapchain_t swapchain)
{
if (!swapchain)
return;
if (swapchain->device->cur_swap == swapchain)
device_load_swapchain(swapchain->device, NULL);
gl_windowinfo_destroy(swapchain->wi);
bfree(swapchain);
}
void volumetexture_destroy(texture_t voltex)

View File

@ -20,6 +20,7 @@
#include "util/darray.h"
#include "graphics/graphics.h"
#include "graphics/matrix4.h"
#include "glew/include/GL/glew.h"
#include "gl-helpers.h"
#include "gl-exports.h"
@ -116,6 +117,62 @@ static inline GLenum convert_zstencil_format(enum gs_zstencil_format format)
}
}
static inline GLenum convert_gs_depth_test(enum gs_depth_test test)
{
switch (test) {
default:
case GS_NEVER: return GL_NEVER;
case GS_LESS: return GL_LESS;
case GS_LEQUAL: return GL_LEQUAL;
case GS_EQUAL: return GL_EQUAL;
case GS_GEQUAL: return GL_GEQUAL;
case GS_GREATER: return GL_GREATER;
case GS_NOTEQUAL: return GL_NOTEQUAL;
case GS_ALWAYS: return GL_ALWAYS;
}
}
static inline GLenum convert_gs_stencil_op(enum gs_stencil_op op)
{
switch (op) {
default:
case GS_KEEP: return GL_KEEP;
case GS_ZERO: return GL_ZERO;
case GS_REPLACE: return GL_REPLACE;
case GS_INCR: return GL_INCR;
case GS_DECR: return GL_DECR;
case GS_INVERT: return GL_INVERT;
}
}
static inline GLenum convert_gs_stencil_side(enum gs_stencil_side side)
{
switch (side) {
default:
case GS_STENCIL_FRONT: return GL_FRONT;
case GS_STENCIL_BACK: return GL_BACK;
case GS_STENCIL_BOTH: return GL_FRONT_AND_BACK;
}
}
static inline GLenum convert_gs_blend_type(enum gs_blend_type type)
{
switch (type) {
default:
case GS_BLEND_ZERO: return GL_ZERO;
case GS_BLEND_ONE: return GL_ONE;
case GS_BLEND_SRCCOLOR: return GL_SRC_COLOR;
case GS_BLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
case GS_BLEND_SRCALPHA: return GL_SRC_ALPHA;
case GS_BLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
case GS_BLEND_DSTCOLOR: return GL_DST_COLOR;
case GS_BLEND_INVDSTCOLOR: return GL_ONE_MINUS_DST_COLOR;
case GS_BLEND_DSTALPHA: return GL_DST_ALPHA;
case GS_BLEND_INVDSTALPHA: return GL_ONE_MINUS_DST_ALPHA;
case GS_BLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
}
}
static inline GLenum convert_shader_type(enum shader_type type)
{
switch (type) {
@ -181,6 +238,18 @@ static inline GLint convert_address_mode(enum gs_address_mode mode)
}
}
static inline GLenum convert_gs_topology(enum gs_draw_mode mode)
{
switch (mode) {
default:
case GS_POINTS: return GL_POINTS;
case GS_LINES: return GL_LINES;
case GS_LINESTRIP: return GL_LINE_STRIP;
case GS_TRIS: return GL_TRIANGLES;
case GS_TRISTRIP: return GL_TRIANGLE_STRIP;
}
}
extern void convert_sampler_info(struct gs_sampler_state *sampler,
struct gs_sampler_info *info);
@ -274,6 +343,7 @@ struct gs_index_buffer {
device_t device;
void *data;
size_t num;
size_t width;
size_t size;
bool dynamic;
};
@ -369,6 +439,15 @@ struct gs_device {
shader_t cur_pixel_shader;
swapchain_t cur_swap;
enum gs_cull_mode cur_cull_mode;
struct gs_rect cur_viewport;
struct matrix4 cur_proj;
struct matrix4 cur_view;
struct matrix4 cur_viewproj;
DARRAY(struct matrix4) proj_stack;
DARRAY(struct fbo_info*) fbos;
struct fbo_info *cur_fbo;
};
@ -381,4 +460,6 @@ extern void gl_platform_destroy(struct gl_platform *platform);
extern struct gl_windowinfo *gl_windowinfo_create(struct gs_init_data *info);
extern void gl_windowinfo_destroy(struct gl_windowinfo *wi);
#endif

View File

@ -427,3 +427,34 @@ void gl_windowinfo_destroy(struct gl_windowinfo *wi)
bfree(wi);
}
}
void device_load_swapchain(device_t device, swapchain_t swap)
{
HDC hdc = device->plat->swap.wi->hdc;
if (device->cur_swap == swap)
return;
device->cur_swap = swap;
if (swap)
hdc = swap->wi->hdc;
if (!wglMakeCurrent(hdc, device->plat->hrc)) {
blog(LOG_ERROR, "wglMakeCurrent failed, GetLastError "
"returned %u", GetLastError());
blog(LOG_ERROR, "device_load_swapchain (GL) failed");
}
}
void device_present(device_t device)
{
HDC hdc = device->plat->swap.wi->hdc;
if (device->cur_swap)
hdc = device->cur_swap->wi->hdc;
if (!SwapBuffers(hdc)) {
blog(LOG_ERROR, "SwapBuffers failed, GetLastError "
"returned %u", GetLastError());
blog(LOG_ERROR, "device_present (GL) failed");
}
}

View File

@ -100,8 +100,8 @@ struct gs_exports {
void (*device_enable_depthtest)(device_t device, bool enable);
void (*device_enable_stenciltest)(device_t device, bool enable);
void (*device_enable_stencilwrite)(device_t device, bool enable);
void (*device_enable_color)(device_t device, bool red, bool blue,
bool green, bool alpha);
void (*device_enable_color)(device_t device, bool red, bool green,
bool blue, bool alpha);
void (*device_blendfunction)(device_t device, enum gs_blend_type src,
enum gs_blend_type dest);
void (*device_depthfunction)(device_t device, enum gs_depth_test test);

View File

@ -1035,11 +1035,11 @@ void gs_enable_stencilwrite(bool enable)
graphics->exports.device_enable_stencilwrite(graphics->device, enable);
}
void gs_enable_color(bool red, bool blue, bool green, bool alpha)
void gs_enable_color(bool red, bool green, bool blue, bool alpha)
{
graphics_t graphics = thread_graphics;
graphics->exports.device_enable_color(graphics->device, red, blue,
green, alpha);
graphics->exports.device_enable_color(graphics->device, red, green,
blue, alpha);
}
void gs_blendfunction(enum gs_blend_type src, enum gs_blend_type dest)

View File

@ -586,7 +586,7 @@ EXPORT void gs_enable_blending(bool enable);
EXPORT void gs_enable_depthtest(bool enable);
EXPORT void gs_enable_stenciltest(bool enable);
EXPORT void gs_enable_stencilwrite(bool enable);
EXPORT void gs_enable_color(bool red, bool blue, bool green, bool alpha);
EXPORT void gs_enable_color(bool red, bool green, bool blue, bool alpha);
EXPORT void gs_blendfunction(enum gs_blend_type src, enum gs_blend_type dest);
EXPORT void gs_depthfunction(enum gs_depth_test test);