OpenGL Core support. Introduction of material based draw system. Rewrote geometry batcher.

This commit is contained in:
SamuelCho committed 2016-08-17 00:13:19 -07:00
1 parent d840f9d0c7
commit a481999a24
102 files changed
+11303 -3189

No files matched your search

+5 -3
View File
@@ -19,8 +19,7 @@
#include "io/timer.h"
#include "pcxutils/pcxutils.h"
#include "render/3d.h"
#include "graphics/material.h"
static color Color_xparent;
@@ -505,7 +504,10 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
else {
g3_rotate_vertex(&image_vertex,instance->world_pos);
Assert(instance->radius != 0.0f);
g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
//g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D);
material mat_params;
material_set_unlit(&mat_params, bitmap_id, 1.0f, false, false);
g3_render_rect_screen_aligned_2d(&mat_params, &image_vertex, 0, instance->radius*1.5f);
}
instance->last_bitmap = bitmap_id;
+1
View File
@@ -80,6 +80,7 @@ extern bool Cmdline_fb_thrusters;
extern bool Cmdline_no_batching;
extern int Cmdline_shadow_quality;
extern int Cmdline_no_deferred_lighting;
extern int Cmdline_no_emissive;
// Game Speed related
extern int Cmdline_cache_bitmaps;
+22 -10
View File
@@ -16,7 +16,7 @@
#include "graphics/gropenglstate.h"
#include "graphics/gropenglshader.h"
#include "graphics/gropengltexture.h"
#include "graphics/gropengltnl.h"
#include "io/key.h"
#include "io/timer.h"
#include "osapi/osapi.h"
@@ -67,6 +67,7 @@ void *g_vBuffers = NULL;
void *g_vBackBuf1, *g_vBackBuf2;
ushort *pixelbuf = NULL;
static GLuint GLtex = 0;
static int buffer_handle = -1;
static GLfloat gl_screenYH = 0;
static GLfloat gl_screenXW = 0;
static GLfloat glVertices[4][4] = {{0}};
@@ -458,13 +459,17 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
scale_by = (float)gr_screen.center_w / (float)g_width;
}
buffer_handle = gr_create_vertex_buffer(true);
// don't bother setting anything if we aren't going to need it
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
vec3d scale;
glScalef( scale_by, scale_by, 1.0f );
scale.xyz.x = scale_by;
scale.xyz.y = scale_by;
scale.xyz.z = 1.0f;
gr_push_scale_matrix(&scale);
mve_scale_video = 1;
}
@@ -507,9 +512,12 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
vertex_layout vertex_def;
vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), 0);
vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), sizeof(GLfloat) * 2);
gr_update_buffer_data(buffer_handle, sizeof(glVertices[0]) * 4, glVertices);
opengl_bind_buffer_object(buffer_handle);
opengl_bind_vertex_layout(vertex_def);
}
@@ -689,7 +697,9 @@ int mve_video_init(ubyte *data)
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB5_A1, g_screenWidth, g_screenHeight, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
// set our color so that we can make sure that it's correct
GL_state.Color(255, 255, 255, 255);
if ( !is_minimum_GLSL_version() ) {
GL_state.Color(255, 255, 255, 255);
}
}
memset(g_palette, 0, 768);
@@ -778,10 +788,12 @@ void mve_shutdown()
{
if (gr_screen.mode == GR_OPENGL) {
if (mve_scale_video) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
gr_pop_scale_matrix();
}
gr_delete_buffer(buffer_handle);
buffer_handle = -1;
GL_state.Texture.Disable();
GL_state.Texture.Delete(GLtex);
glDeleteTextures(1, &GLtex);
+31 -18
View File
@@ -20,6 +20,7 @@
#include "graphics/gropenglshader.h"
#include "graphics/gropenglstate.h"
#include "graphics/gropengltexture.h"
#include "graphics/gropengltnl.h"
#include "io/key.h"
#include "io/timer.h"
#include "osapi/osapi.h"
@@ -50,6 +51,7 @@ static GLint gl_screenXW = 0;
static GLfloat gl_screenU = 0;
static GLfloat gl_screenV = 0;
static GLfloat glVertices[4][4] = {{0}};
static int buffer_handle = -1;
static int timer_started = 0;
static longlong base_time = -1;
@@ -335,10 +337,11 @@ static void OGG_video_init(theora_info *tinfo)
g_screenWidth = tinfo->frame_width;
g_screenHeight = tinfo->frame_height;
if (gr_screen.mode == GR_OPENGL) {
opengl_set_texture_target(GL_TEXTURE_2D);
buffer_handle = gr_create_vertex_buffer(true);
if(!is_minimum_GLSL_version())
use_shaders = false;
@@ -405,7 +408,7 @@ static void OGG_video_init(theora_info *tinfo)
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 2048, 2048, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RED, 2048, 2048, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
GL_state.Texture.SetActiveUnit(1);
GL_state.Texture.SetTarget(GL_texture_target);
@@ -416,7 +419,7 @@ static void OGG_video_init(theora_info *tinfo)
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RED, 1024, 1024, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
GL_state.Texture.SetActiveUnit(2);
GL_state.Texture.SetTarget(GL_texture_target);
@@ -427,7 +430,7 @@ static void OGG_video_init(theora_info *tinfo)
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RED, 1024, 1024, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
}
float screen_ratio = (float)gr_screen.center_w / (float)gr_screen.center_h;
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
@@ -439,16 +442,20 @@ static void OGG_video_init(theora_info *tinfo)
// don't bother setting anything if we aren't going to need it
if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
vec3d scale;
scale.xyz.x = scale_by;
scale.xyz.y = scale_by;
scale.xyz.z = -1.0f;
glScalef( scale_by, scale_by, -1.0f );
gr_push_scale_matrix(&scale);
scale_video = 1;
}
// set our color so that we can make sure that it's correct
GL_state.Color(255, 255, 255, 255);
if ( !is_minimum_GLSL_version() ) {
GL_state.Color(255, 255, 255, 255);
}
}
if(!use_shaders) {
@@ -487,6 +494,9 @@ static void OGG_video_init(theora_info *tinfo)
GL_state.Uniform.setUniformi("ytex", 0);
GL_state.Uniform.setUniformi("utex", 1);
GL_state.Uniform.setUniformi("vtex", 2);
GL_state.Uniform.setUniformMatrix4f("projMatrix", GL_projection_matrix);
GL_state.Uniform.setUniformMatrix4f("modelViewMatrix", GL_model_view_matrix);
}
glVertices[0][0] = (GLfloat)g_screenX;
@@ -509,13 +519,14 @@ static void OGG_video_init(theora_info *tinfo)
glVertices[3][2] = gl_screenU;
glVertices[3][3] = gl_screenV;
GL_state.Array.BindArrayBuffer(0);
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), sizeof(GLfloat) * 2);
gr_update_buffer_data(buffer_handle, sizeof(glVertices[0]) * 4, glVertices);
opengl_bind_buffer_object(buffer_handle);
opengl_bind_vertex_layout(vert_def);
}
if(!use_shaders && tinfo->frame_height > 450) {
@@ -532,10 +543,12 @@ static void OGG_video_close()
if (gr_screen.mode == GR_OPENGL) {
if (scale_video) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
gr_pop_scale_matrix();
}
gr_delete_buffer(buffer_handle);
buffer_handle = -1;
GL_state.Texture.Disable();
if(use_shaders) {
GL_state.Texture.Delete(ytex);
@@ -654,11 +667,11 @@ static void OGG_video_draw(theora_state *tstate)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if(use_shaders) {
GL_state.Texture.SetActiveUnit(0);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.y_stride, yuv.y_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.y);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.y_stride, yuv.y_height, GL_RED, GL_UNSIGNED_BYTE, yuv.y);
GL_state.Texture.SetActiveUnit(1);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.u);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_RED, GL_UNSIGNED_BYTE, yuv.u);
GL_state.Texture.SetActiveUnit(2);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.v);
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_RED, GL_UNSIGNED_BYTE, yuv.v);
} else {
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
}
+6 -4
View File
@@ -1,7 +1,9 @@
fragIn vec4 fragTexCoord;
uniform sampler2D bloomed;
uniform float bloom_intensity;
uniform int levels;
void main() { // Global constant
void main() {
// Global constant
vec4 color_out = vec4(0.0, 0.0, 0.0, 1.0);
// Bloom
if (bloom_intensity > 0.0) {
@@ -10,10 +12,10 @@ void main() { // Global constant
for (int mipmap = 0; mipmap < levels; ++mipmap) {
float scale = 1.0/exp2(float(mipmap));
factor += scale;
bloom += texture2DLod(bloomed, gl_TexCoord[0].xy, float(mipmap)).rgb * scale;
bloom += tex2DLod(bloomed, fragTexCoord.xy, float(mipmap)).rgb * scale;
}
bloom /= factor;
color_out.rgb += bloom * bloom_intensity;
}
gl_FragColor = color_out;
}
fragOut0 = color_out;
};
+8 -7
View File
@@ -1,6 +1,7 @@
uniform float texSize;
uniform float tapSize;
uniform int level;
fragIn vec4 fragTexCoord;
uniform sampler2D tex;
// Gaussian Blur
// 2 passes required
@@ -15,18 +16,18 @@ void main()
BlurWeights[2] = 0.1120;
BlurWeights[1] = 0.1297;
BlurWeights[0] = 0.1362;
vec4 sum = texture2DLod(tex, gl_TexCoord[0].xy, float(level)) * BlurWeights[0];
vec4 sum = tex2DLod(tex, fragTexCoord.xy, float(level)) * BlurWeights[0];
#ifdef PASS_0
for (int i = 1; i < 6; i++) {
sum += texture2DLod(tex, vec2(clamp(gl_TexCoord[0].x - float(i) * (texSize) * tapSize, 0.0, 1.0), gl_TexCoord[0].y), float(level)) * BlurWeights[i];
sum += texture2DLod(tex, vec2(clamp(gl_TexCoord[0].x + float(i) * (texSize) * tapSize, 0.0, 1.0), gl_TexCoord[0].y), float(level)) * BlurWeights[i];
sum += tex2DLod(tex, vec2(clamp(fragTexCoord.x - float(i) * (texSize) * tapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
sum += tex2DLod(tex, vec2(clamp(fragTexCoord.x + float(i) * (texSize) * tapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
}
#endif
#ifdef PASS_1
for (int i = 1; i < 6; i++) {
sum += texture2DLod(tex, vec2(gl_TexCoord[0].x, clamp(gl_TexCoord[0].y - float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += texture2DLod(tex, vec2(gl_TexCoord[0].x, clamp(gl_TexCoord[0].y + float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += tex2DLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y - float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += tex2DLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y + float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
}
#endif
gl_FragColor = vec4(sum.rgb, 1.0);
}
fragOut0 = sum;
};
+4 -4
View File
@@ -1,3 +1,4 @@
fragIn vec4 fragTexCoord;
uniform sampler2D tex;
const float Luminance = 0.08;
const float fMiddleGray = 0.2;
@@ -9,13 +10,12 @@ float luminance(vec3 color)
return dot(color, vec3(0.299, 0.587, 0.114));
}
void main() {
vec4 ColorOut = texture2D(tex, gl_TexCoord[0].xy);
vec4 ColorOut = tex2D(tex, fragTexCoord.xy);
//ColorOut *= fMiddleGray / (Luminance + 0.001);
//ColorOut *= (1.0 + (ColorOut / (fWhiteCutoff * fWhiteCutoff)));
//ColorOut -= 6.0;
//ColorOut /= (10.0 + ColorOut);
gl_FragColor.rgb = max(vec3(0.0, 0.0, 0.0), ColorOut.rgb - vec3(1.0, 1.0, 1.0));
gl_FragColor.a = 1.0;
fragOut0 = vec4(max(vec3(0.0, 0.0, 0.0), ColorOut.rgb - vec3(1.0, 1.0, 1.0)), 1.0);
//float luminance = luminance(ColorOut.rgb);
//gl_FragColor.rgb = luminance > threshold ? ColorOut.rgb : vec3(0.0);
}
};
+5 -5
View File
@@ -1,7 +1,7 @@
void main()
{
gl_FragData[0] = vec4(0.0, 0.0, 0.0, 1.0); // color
gl_FragData[1] = vec4(0.0, 0.0, -1000000.0, 1.0); // position
gl_FragData[2] = vec4(0.0, 0.0, 0.0, 1.0); // normal
gl_FragData[3] = vec4(0.0, 0.0, 0.0, 0.0); // specular
}
fragOut0 = vec4(0.0, 0.0, 0.0, 1.0); // color
fragOut1 = vec4(0.0, 0.0, -1000000.0, 1.0); // position
fragOut2 = vec4(0.0, 0.0, 0.0, 1.0); // normal
fragOut3 = vec4(0.0, 0.0, 0.0, 0.0); // specular
};
+3 -5
View File
@@ -1,7 +1,5 @@
vertIn vec4 vertPosition;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
gl_FrontColor = vec4(1.0);
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
}
gl_Position = vertPosition;
};
+10 -11
View File
@@ -6,9 +6,9 @@ uniform float specFactor;
uniform float invScreenWidth;
uniform float invScreenHeight;
uniform int lightType;
varying vec3 lightPosition;
fragIn vec3 lightPosition;
uniform float lightRadius;
varying vec3 beamVec;
fragIn vec3 beamVec;
uniform vec3 diffuseLightColor;
uniform vec3 specLightColor;
uniform float coneAngle;
@@ -39,7 +39,7 @@ vec4 SpecularLegacy(vec4 specColor, vec3 normal, vec3 halfVec, float specPower)
void main()
{
vec2 screenPos = gl_FragCoord.xy * vec2(invScreenWidth, invScreenHeight);
vec3 position = texture2D(PositionBuffer, screenPos).xyz;
vec3 position = tex2D(PositionBuffer, screenPos).xyz;
if(abs(dot(position, position)) < 0.1)
discard;
@@ -63,9 +63,9 @@ void main()
}
if(dist > lightRadius && lightType != 1)
discard;
vec3 color = texture2D(ColorBuffer, screenPos).rgb;
vec4 normal = texture2D(NormalBuffer, screenPos);
vec4 specColor = texture2D(SpecBuffer, screenPos);
vec3 color = tex2D(ColorBuffer, screenPos).rgb;
vec4 normal = tex2D(NormalBuffer, screenPos);
vec4 specColor = tex2D(SpecBuffer, screenPos);
float gloss = specColor.a;
vec3 eyeDir = normalize(-position);
@@ -86,8 +86,7 @@ void main()
vec3 halfVec = normalize(lightDir + eyeDir);
float NdotHV = clamp(dot(normal.xyz, halfVec), 0.0, 1.0);
float NdotL = clamp(dot(normal.xyz, lightDir), 0.0, 1.0);
gl_FragData[0].rgb = color * (diffuseLightColor * NdotL * attenuation);
gl_FragData[0].rgb += SpecularBlinnPhong(specLightColor, lightDir, normal.xyz, halfVec, exp2(10.0 * gloss + 1.0), NdotL).rgb * specColor.rgb * attenuation;
gl_FragData[0].a = 1.0;
gl_FragData[0] = max(gl_FragData[0], vec4(0.0));
}
vec4 fragmentColor = vec4(color * (diffuseLightColor * NdotL * attenuation), 1.0);
fragmentColor.rgb += SpecularBlinnPhong(specLightColor, lightDir, normal.xyz, halfVec, exp2(10.0 * gloss + 1.0), NdotL).rgb * specColor.rgb * attenuation;
fragOut0 = max(fragmentColor, vec4(0.0));
};
+9 -8
View File
@@ -1,13 +1,14 @@
vertIn vec4 vertPosition;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform vec3 scale;
uniform int lightType;
varying vec3 lightPosition;
varying vec3 beamVec;
vertOut vec3 lightPosition;
vertOut vec3 beamVec;
void main()
{
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(gl_Vertex.xyz * scale,1.0);
lightPosition = gl_ModelViewMatrix[3].xyz;
gl_Position = projMatrix * modelViewMatrix * vec4(vertPosition.xyz * scale, 1.0);
lightPosition = modelViewMatrix[3].xyz;
if(lightType == 1)
beamVec = vec3(gl_ModelViewMatrix * vec4(0.0, 0.0, -scale.z, 0.0));
}
beamVec = vec3(modelViewMatrix * vec4(0.0, 0.0, -scale.z, 0.0));
};
+8 -6
View File
@@ -1,17 +1,19 @@
fragIn vec4 fragTexCoord;
fragIn vec4 fragColor;
fragIn float fragOffset;
uniform sampler2D baseMap;
uniform sampler2D depthMap;
uniform float window_width;
uniform float window_height;
uniform sampler2D distMap;
uniform sampler2D frameBuffer;
varying float offset_out;
void main()
{
vec2 depthCoord = vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height);
vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a;
vec2 distortion = texture2D(distMap, gl_TexCoord[0].xy+vec2(0.0, offset_out)).rg;
vec4 fragmentColor = tex2D(baseMap, fragTexCoord.xy) * fragColor.a;
vec2 distortion = tex2D(distMap, fragTexCoord.xy+vec2(0.0, fragOffset)).rg;
float alpha = clamp(dot(fragmentColor.rgb,vec3(0.3333))*10.0,0.0,1.0);
distortion = ((distortion - 0.5) * 0.01) * alpha;
gl_FragColor = texture2D(frameBuffer,depthCoord+distortion);
gl_FragColor.a = alpha;
}
fragOut0 = tex2D(frameBuffer,depthCoord+distortion);
fragOut0.a = alpha;
};
+14 -12
View File
@@ -1,15 +1,17 @@
attribute float radius;
varying float offset_out;
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertIn vec4 vertColor;
vertIn float vertRadius;
vertOut vec4 fragTexCoord;
vertOut vec4 fragColor;
vertOut float fragOffset;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform float use_offset;
void main()
{
gl_Position = ftransform();
offset_out = radius * use_offset;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
#ifdef __GLSL_CG_DATA_TYPES
// Check necessary for ATI specific behavior
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);
#endif
}
gl_Position = projMatrix * modelViewMatrix * vertPosition;
fragOffset = vertRadius * use_offset;
fragTexCoord = vertTexCoord;
fragColor = vertColor;
};
+5 -3
View File
@@ -1,7 +1,9 @@
fragIn vec4 fragTexCoord;
fragIn vec4 fragColor;
uniform sampler2D baseMap;
uniform int textured;
void main()
{
vec4 fragmentColor = mix(gl_Color, texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a, (float)textured);
gl_FragColor = fragmentColor;
}
vec4 fragmentColor = mix(fragColor, texture2D(baseMap, fragTexCoord.xy)*fragColor.a, (float)textured);
fragOut0 = fragmentColor;
};
+16 -13
View File
@@ -5,38 +5,41 @@ uniform float window_height;
uniform float nearZ;
uniform float farZ;
uniform int linear_depth;
uniform int srgb;uniform int blend_alpha;
varying float radius_p;
varying vec4 position_p;
uniform int srgb;
uniform int blend_alpha;
fragIn float fragRadius;
fragIn vec4 fragPosition;
fragIn vec4 fragTexCoord;
fragIn vec4 fragColor;
#define SRGB_GAMMA 2.2
void main()
{
vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy);
vec4 fragmentColor = tex2D(baseMap, fragTexCoord.xy);
fragmentColor.rgb = mix(fragmentColor.rgb, pow(fragmentColor.rgb, vec3(SRGB_GAMMA)), float(srgb));
fragmentColor *= mix(gl_Color, vec4(pow(gl_Color.rgb, vec3(SRGB_GAMMA)), gl_Color.a), float(srgb));
vec2 offset = vec2(radius_p * abs(0.5 - gl_TexCoord[0].x) * 2.0, radius_p * abs(0.5 - gl_TexCoord[0].y) * 2.0);
fragmentColor *= mix(fragColor, vec4(pow(fragColor.rgb, vec3(SRGB_GAMMA)), fragColor.a), float(srgb));
vec2 offset = vec2(fragRadius * abs(0.5 - fragTexCoord.x) * 2.0, fragRadius * abs(0.5 - fragTexCoord.y) * 2.0);
float offset_len = length(offset);
if ( offset_len > radius_p ) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
if ( offset_len > fragRadius ) {
fragOut0 = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
vec2 depthCoord = vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height );
vec4 sceneDepth = texture2D(depthMap, depthCoord);
vec4 sceneDepth = tex2D(depthMap, depthCoord);
float sceneDepthLinear;
float fragDepthLinear;
if ( linear_depth == 1 ) {
sceneDepthLinear = -sceneDepth.z;
fragDepthLinear = -position_p.z;
fragDepthLinear = -fragPosition.z;
} else {
sceneDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - sceneDepth.x * (farZ-nearZ) );
fragDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - gl_FragCoord.z * (farZ-nearZ) );
}
// assume UV of 0.5, 0.5 is the centroid of this sphere volume
float depthOffset = sqrt(pow(radius_p, 2.0) - pow(offset_len, 2.0));
float depthOffset = sqrt(pow(fragRadius, 2.0) - pow(offset_len, 2.0));
float frontDepth = fragDepthLinear - depthOffset;
float backDepth = fragDepthLinear + depthOffset;
float intensity = smoothstep(max(nearZ, frontDepth), backDepth, sceneDepthLinear);
fragmentColor.rgb *= (srgb == 1) ? 1.5 : 1.0;
fragmentColor = (blend_alpha == 1) ? vec4(fragmentColor.rgb, fragmentColor.a * intensity) : vec4(fragmentColor.rgb * intensity, fragmentColor.a);
gl_FragColor = max(fragmentColor, vec4(0.0));
}
fragOut0 = max(fragmentColor, vec4(0.0));
};
+40 -35
View File
@@ -1,46 +1,51 @@
#extension GL_EXT_geometry_shader4 : enable
varying in vec3 up_g[];
varying in float radius_g[];
varying out float radius_p;
varying out vec4 position_p;
#extension GL_ARB_geometry_shader4 : enable
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in vec3 geoUvec[];
in float geoRadius[];
in vec4 geoColor[];
out float fragRadius;
out vec4 fragPosition;
out vec4 fragTexCoord;
out vec4 fragColor;
uniform mat4 projMatrix;
void main(void)
{
vec3 forward_vec = vec3(0.0, 0.0, 1.0);
vec3 up_vec = normalize(up_g[0]);
vec3 up_vec = normalize(geoUvec[0]);
vec3 right_vec = cross(forward_vec, up_vec);
vec4 pos = vec4(0.0, 0.0, 0.0, 0.0);
right_vec = normalize(right_vec);
pos = (gl_PositionIn[0] - vec4(radius_g[0] * up_vec, 0.0) - vec4(radius_g[0] * right_vec, 0.0));
gl_Position = gl_ProjectionMatrix * pos;
position_p = pos;
gl_TexCoord[0] = vec4(0.0, 0.0, 0.0, 0.0);
radius_p = radius_g[0];
gl_FrontColor = gl_FrontColorIn[0];
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
pos = (gl_in[0].gl_Position - vec4(geoRadius[0] * up_vec, 0.0) - vec4(geoRadius[0] * right_vec, 0.0));
gl_Position = projMatrix * pos;
fragPosition = pos;
fragTexCoord = vec4(0.0, 0.0, 0.0, 0.0);
fragRadius = geoRadius[0];
fragColor = geoColor[0];
EmitVertex();
pos = (gl_PositionIn[0] - vec4(radius_g[0] * up_vec, 0.0) + vec4(radius_g[0] * right_vec, 0.0));
gl_Position = gl_ProjectionMatrix * pos;
position_p = pos;
gl_TexCoord[0] = vec4(0.0, 1.0, 0.0, 0.0);
radius_p = radius_g[0];
gl_FrontColor = gl_FrontColorIn[0];
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
pos = (gl_in[0].gl_Position - vec4(geoRadius[0] * up_vec, 0.0) + vec4(geoRadius[0] * right_vec, 0.0));
gl_Position = projMatrix * pos;
fragPosition = pos;
fragTexCoord = vec4(0.0, 1.0, 0.0, 0.0);
fragRadius = geoRadius[0];
fragColor = geoColor[0];
EmitVertex();
pos = (gl_PositionIn[0] + vec4(radius_g[0] * up_vec, 0.0) - vec4(radius_g[0] * right_vec, 0.0));
gl_Position = gl_ProjectionMatrix * pos;
position_p = pos;
gl_TexCoord[0] = vec4(1.0, 0.0, 0.0, 0.0);
radius_p = radius_g[0];
gl_FrontColor = gl_FrontColorIn[0];
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
pos = (gl_in[0].gl_Position + vec4(geoRadius[0] * up_vec, 0.0) - vec4(geoRadius[0] * right_vec, 0.0));
gl_Position = projMatrix * pos;
fragPosition = pos;
fragTexCoord = vec4(1.0, 0.0, 0.0, 0.0);
fragRadius = geoRadius[0];
fragColor = geoColor[0];
EmitVertex();
pos = (gl_PositionIn[0] + vec4(radius_g[0] * up_vec, 0.0) + vec4(radius_g[0] * right_vec, 0.0));
gl_Position = gl_ProjectionMatrix * pos;
position_p = pos;
gl_TexCoord[0] = vec4(1.0, 1.0, 0.0, 0.0);
radius_p = radius_g[0];
gl_FrontColor = gl_FrontColorIn[0];
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
pos = (gl_in[0].gl_Position + vec4(geoRadius[0] * up_vec, 0.0) + vec4(geoRadius[0] * right_vec, 0.0));
gl_Position = projMatrix * pos;
fragPosition = pos;
fragTexCoord = vec4(1.0, 1.0, 0.0, 0.0);
fragRadius = geoRadius[0];
fragColor = geoColor[0];
EmitVertex();
EndPrimitive();
}
};
+26 -22
View File
@@ -1,35 +1,39 @@
attribute float radius;
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertIn vec4 vertColor;
vertIn float vertRadius;
#ifdef FLAG_EFFECT_GEOMETRY
attribute vec3 uvec;
varying vec3 up_g;
varying float radius_g;
vertIn vec3 vertUvec;
vertOut vec3 geoUvec;
vertOut float geoRadius;
vertOut vec4 geoColor;
#else
varying float radius_p;
varying vec4 position_p;
vertOut float fragRadius;
vertOut vec4 fragPosition;
vertOut vec4 fragTexCoord;
vertOut vec4 fragColor;
#endif
#ifdef FLAG_EFFECT_DISTORTION
varying float offset_out;
vertOut float fragOffset;
uniform float use_offset;
#endif
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
#ifdef FLAG_EFFECT_GEOMETRY
radius_g = radius;
up_g = uvec;
gl_Position = gl_ModelViewMatrix * gl_Vertex;
geoRadius = vertRadius;
geoUvec = vertUvec;
gl_Position = modelViewMatrix * vertPosition;
geoColor = vertColor;
#else
radius_p = radius;
gl_Position = ftransform();
position_p = gl_ModelViewMatrix * gl_Vertex;
fragRadius = vertRadius;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
fragPosition = modelViewMatrix * vertPosition;
fragTexCoord = vertTexCoord;
fragColor = vertColor;
#endif
#ifdef FLAG_EFFECT_DISTORTION
offset_out = radius * use_offset;
fragOffset = vertRadius * use_offset;
#endif
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
#ifdef __GLSL_CG_DATA_TYPES
// Check necessary for ATI specific behavior
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);
#endif
}
};
+6 -6
View File
@@ -177,8 +177,8 @@
#endif
#endif
#if (FXAA_GLSL_130 == 1)
#define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#if (FXAA_GATHER4_ALPHA == 1)
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
@@ -503,8 +503,8 @@ FxaaFloat4 FxaaPixelShader(
#endif
}
uniform sampler2D tex0;
varying vec2 v_rcpFrame;
noperspective varying vec2 v_pos;
fragIn vec2 v_rcpFrame;
noperspective fragIn vec2 v_pos;
void main() {
gl_FragColor = FxaaPixelShader(v_pos, tex0, v_rcpFrame, FXAA_QUALITY_SUBPIX, FXAA_QUALITY_EDGE_THRESHOLD, FXAA_QUALITY_EDGE_THRESHOLD_MIN);
}
fragOut0 = FxaaPixelShader(v_pos, tex0, v_rcpFrame, FXAA_QUALITY_SUBPIX, FXAA_QUALITY_EDGE_THRESHOLD, FXAA_QUALITY_EDGE_THRESHOLD_MIN);
};
+6 -5
View File
@@ -1,10 +1,11 @@
#extension GL_EXT_gpu_shader4 : enable
vertIn vec4 vertPosition;
uniform float rt_w;
uniform float rt_h;
varying vec2 v_rcpFrame;
noperspective varying vec2 v_pos;
vertOut vec2 v_rcpFrame;
noperspective vertOut vec2 v_pos;
void main() {
gl_Position = gl_Vertex;
gl_Position = vertPosition;
v_rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
v_pos = gl_Vertex.xy*0.5 + 0.5;
}
v_pos = vertPosition.xy*0.5 + 0.5;
};
+4 -3
View File
@@ -1,5 +1,6 @@
fragIn vec4 fragTexCoord;
uniform sampler2D tex;
void main() {
vec4 color = texture2D(tex, gl_TexCoord[0].xy);
gl_FragColor = vec4(color.rgb, dot(color.rgb, vec3(0.299, 0.587, 0.114)) );
}
vec4 color = tex2D(tex, fragTexCoord.xy);
fragOut0 = vec4(color.rgb, dot(color.rgb, vec3(0.299, 0.587, 0.114)) );
};
+108 -89
View File
@@ -1,8 +1,24 @@
#extension GL_EXT_texture_array : enable
#if __VERSION__ == 120
#define MAX_LIGHTS 2
#else
#define MAX_LIGHTS 8
#endif
#define LT_DIRECTIONAL 0
#define LT_POINT 1
#define LT_TUBE 2
uniform vec4 color;
#ifdef FLAG_LIGHT
uniform vec4 lightPosition[MAX_LIGHTS];
uniform vec3 lightDirection[MAX_LIGHTS];
uniform vec3 lightDiffuseColor[MAX_LIGHTS];
uniform vec3 lightSpecColor[MAX_LIGHTS];
uniform int lightType[MAX_LIGHTS];
uniform float lightAttenuation[MAX_LIGHTS];
uniform int n_lights;
uniform float light_factor;
uniform float defaultGloss;
uniform vec3 ambientFactor;
uniform vec3 diffuseFactor;
uniform vec3 emissionFactor;
#endif
#ifdef FLAG_DIFFUSE_MAP
uniform sampler2D sBasemap;
@@ -27,17 +43,20 @@ uniform bool gammaSpec;
#ifdef FLAG_ENV_MAP
uniform samplerCube sEnvmap;
uniform bool envGloss;
uniform bool alpha_spec;
varying vec3 envReflect;
fragIn vec3 fragEnvReflect;
#endif
#ifdef FLAG_NORMAL_MAP
uniform sampler2D sNormalmap;
varying mat3 tbnMatrix;
fragIn mat3 fragTangentMatrix;
#endif
#ifdef FLAG_AMBIENT_MAP
uniform sampler2D sAmbientmap;
#endif
#ifdef FLAG_FOG
varying float fogDist;
uniform vec4 fogColor;
fragIn float fragFogDist;
#endif
#ifdef FLAG_ANIMATED
uniform sampler2D sFramebuffer;
@@ -47,7 +66,8 @@ uniform float vpwidth;
uniform float vpheight;
#endif
#ifdef FLAG_TRANSFORM
varying float not_visible;
#extension GL_ARB_texture_buffer_object : enable
fragIn float fragNotVisible;
#endif
#ifdef FLAG_TEAMCOLOR
uniform vec3 base_color;
@@ -59,8 +79,9 @@ vec2 teamMask = vec2(0.0, 0.0);
uniform sampler2D sMiscmap;
#endif
#ifdef FLAG_SHADOWS
varying vec4 shadow_vec[4];
varying vec4 pos_shadow;
#extension GL_EXT_texture_array : enable
fragIn vec4 fragShadowUV[4];
fragIn vec4 fragShadowPos;
//uniform sampler2DArrayShadow shadow_map;
uniform sampler2DArray shadow_map;
//uniform sampler2D shadow_map;
@@ -73,20 +94,14 @@ uniform float fardist;
#endif
#ifdef FLAG_CLIP
uniform int use_clip_plane;
varying float clip_distance;
fragIn float fragClipDistance;
#endif
varying vec4 position;
varying vec3 lNormal;
#if __VERSION__ == 120
#define MAX_LIGHTS 2
#else
#define MAX_LIGHTS 8
#ifdef FLAG_NORMAL_ALPHA
uniform vec2 normalAlphaMinMax;
#endif
#define SPEC_INTENSITY_POINT 5.3 // Point light
#define SPEC_INTENSITY_DIRECTIONAL 3.0 // Directional light
#define SPECULAR_FACTOR 1.75
#define SPECULAR_ALPHA 0.1
#define SPEC_FACTOR_NO_SPEC_MAP 0.6
#define ENV_ALPHA_FACTOR 0.3
#define GLOW_MAP_INTENSITY 1.5
@@ -94,21 +109,25 @@ varying vec3 lNormal;
#define VARIANCE_SHADOW_SCALE 1000000.0
#define VARIANCE_SHADOW_SCALE_INV 1.0/VARIANCE_SHADOW_SCALE
#define SRGB_GAMMA 2.2
fragIn vec4 fragPosition;
fragIn vec3 fragNormal;
fragIn vec4 fragTexCoord;
#ifdef FLAG_SHADOWS
vec2 sampleShadowMap(vec2 uv, vec2 offset_uv, int cascade, float shadowMapSizeInv)
{
return texture2DArray(shadow_map, vec3(uv + offset_uv * shadowMapSizeInv, float(cascade))).xy;
return tex2DArray(shadow_map, vec3(uv + offset_uv * shadowMapSizeInv, float(cascade))).xy;
}
float computeShadowFactor(vec2 moments, float bias)
{
float shadow = 1.0;
if((moments.x - bias) > pos_shadow.z)
if((moments.x - bias) > fragShadowPos.z)
{
// variance shadow mapping using Chebychev's Formula
float variance = moments.y * VARIANCE_SHADOW_SCALE - moments.x * moments.x;
float mD = moments.x - bias - pos_shadow.z;
float mD = moments.x - bias - fragShadowPos.z;
shadow = variance / (variance + mD * mD);
shadow = clamp(shadow, 0.0, 1.0);
}
@@ -117,7 +136,7 @@ float computeShadowFactor(vec2 moments, float bias)
float sampleNoPCF(int cascade)
{
return computeShadowFactor(sampleShadowMap(shadow_vec[cascade].xy, vec2(0.0, 0.0), cascade, 1.0/1024.0), 0.05);
return computeShadowFactor(sampleShadowMap(fragShadowUV[cascade].xy, vec2(0.0, 0.0), cascade, 1.0/1024.0), 0.05);
}
float samplePoissonPCF(int cascade)
@@ -145,28 +164,28 @@ float samplePoissonPCF(int cascade)
maxUVOffset[1] = 1.0/250.0;
maxUVOffset[2] = 1.0/200.0;
maxUVOffset[3] = 1.0/200.0;
vec2 sum = sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[0], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[1], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[2], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[3], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[4], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[5], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[6], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[7], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[8], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[9], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[10], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[11], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[12], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[13], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[14], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(shadow_vec[cascade].xy, poissonDisc[15], cascade, maxUVOffset[cascade])*(1.0/16.0);
vec2 sum = sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[0], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[1], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[2], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[3], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[4], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[5], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[6], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[7], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[8], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[9], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[10], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[11], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[12], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[13], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[14], cascade, maxUVOffset[cascade])*(1.0/16.0);
sum += sampleShadowMap(fragShadowUV[cascade].xy, poissonDisc[15], cascade, maxUVOffset[cascade])*(1.0/16.0);
return computeShadowFactor(sum, 0.1);
}
float getShadowValue()
{
// Valathil's Shadows
float depth = -position.z;
float depth = -fragPosition.z;
int cascade = 4;
cascade -= int(step(depth, fardist));
cascade -= int(step(depth, middist));
@@ -192,7 +211,7 @@ vec3 FresnelSchlick(vec3 specColor, vec3 light, vec3 halfVec)
}
vec3 FresnelLazarovEnv(vec3 specColor, vec3 view, vec3 normal, float gloss)
{
// Fresnel for environment lighting
// Fresnel for environment lighting
// Equation referenced from Dimitar Lazarov's presentation titled Physically Based Rendering in Call of Duty: Black Ops
return specColor + (vec3(1.0) - specColor) * pow(1.0 - clamp(dot(view, normal), 0.0, 1.0), 5.0) / (4.0 - 3.0 * gloss);
}
@@ -206,38 +225,38 @@ vec4 SpecularLegacy(vec4 specColor, vec3 normal, vec3 halfVec, float specPower)
}
void GetLightInfo(int i, out vec3 lightDir, out float attenuation, out float specIntensity)
{
lightDir = normalize(gl_LightSource[i].position.xyz);
lightDir = normalize(lightPosition[i].xyz);
attenuation = 1.0;
specIntensity = SPEC_INTENSITY_DIRECTIONAL;
#if __VERSION__ > 120
if (gl_LightSource[i].position.w == 1.0) {
if (lightType[i] != LT_DIRECTIONAL) {
#else
if (gl_LightSource[i].position.w == 1.0 && i != 0) {
if (lightType[i] != LT_DIRECTIONAL && i != 0) {
#endif
// Positional light source
float dist = distance(gl_LightSource[i].position.xyz, position.xyz);
lightDir = (gl_LightSource[i].position.xyz - position.xyz);
float dist = distance(lightPosition[i].xyz, fragPosition.xyz);
lightDir = (lightPosition[i].xyz - fragPosition.xyz);
#if __VERSION__ > 120
if (gl_LightSource[i].spotCutoff < 91.0) { // Tube light
float beamlength = length(gl_LightSource[i].spotDirection);
vec3 beamDir = normalize(gl_LightSource[i].spotDirection);
if (lightType[i] == LT_TUBE) { // Tube light
float beamlength = length(lightDirection[i]);
vec3 beamDir = normalize(lightDirection[i]);
// Get nearest point on line
float neardist = dot(position.xyz - gl_LightSource[i].position.xyz , beamDir);
float neardist = dot(fragPosition.xyz - lightPosition[i].xyz, beamDir);
// Move back from the endpoint of the beam along the beam by the distance we calculated
vec3 nearest = gl_LightSource[i].position.xyz - beamDir * abs(neardist);
lightDir = nearest - position.xyz;
vec3 nearest = lightPosition[i].xyz - beamDir * abs(neardist);
lightDir = nearest - fragPosition.xyz;
dist = length(lightDir);
}
#endif
lightDir = normalize(lightDir);
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + (gl_LightSource[i].linearAttenuation * dist) + (gl_LightSource[i].quadraticAttenuation * dist * dist));
attenuation = 1.0 / (lightAttenuation[i] * dist);
specIntensity = SPEC_INTENSITY_POINT;
}
}
vec3 CalculateLighting(vec3 normal, vec3 diffuseMaterial, vec3 specularMaterial, float gloss, float shadow, float ambientFactor)
vec3 CalculateLighting(vec3 normal, vec3 diffuseMaterial, vec3 specularMaterial, float gloss, float shadow, float aoFactor)
{
vec3 eyeDir = vec3(normalize(-position).xyz);
vec3 lightAmbient = vec3(gl_FrontMaterial.emission + (gl_LightModel.ambient * gl_FrontMaterial.ambient)) * ambientFactor;
vec3 eyeDir = vec3(normalize(-fragPosition).xyz);
vec3 lightAmbient = (emissionFactor + ambientFactor) * aoFactor;
vec3 lightAmbientDiffuse = vec3(0.0, 0.0, 0.0);
vec3 lightDiffuse = vec3(0.0, 0.0, 0.0);
vec3 lightSpecular = vec3(0.0, 0.0, 0.0);
@@ -257,9 +276,8 @@ vec3 CalculateLighting(vec3 normal, vec3 diffuseMaterial, vec3 specularMaterial,
vec3 halfVec = normalize(lightDir + eyeDir);
float NdotL = max(dot(normal, lightDir), 0.0);
// Ambient, Diffuse, and Specular
lightAmbient += (gl_FrontLightProduct[i].ambient.rgb * attenuation);
lightDiffuse += (gl_FrontLightProduct[i].diffuse.rgb * light_factor * NdotL * attenuation) * shadow;
lightSpecular += gl_FrontLightProduct[i].specular.rgb * SpecularBlinnPhong(specularMaterial, lightDir, normal, halfVec, exp2(10.0 * gloss + 1.0), NdotL) * attenuation * shadow;
lightDiffuse += (lightDiffuseColor[i].rgb * diffuseFactor * NdotL * attenuation) * shadow;
lightSpecular += lightSpecColor[i] * SpecularBlinnPhong(specularMaterial, lightDir, normal, halfVec, exp2(10.0 * gloss + 1.0), NdotL) * attenuation * shadow;
}
lightAmbientDiffuse = lightAmbient + lightDiffuse;
vec3 finalColor = diffuseMaterial;
@@ -271,27 +289,27 @@ vec3 CalculateLighting(vec3 normal, vec3 diffuseMaterial, vec3 specularMaterial,
void main()
{
#ifdef FLAG_TRANSFORM
if(not_visible >= 0.9) { discard; }
if(fragNotVisible >= 0.9) { discard; }
#endif
#ifdef FLAG_SHADOW_MAP
#ifdef FLAG_CLIP
if(use_clip_plane == 1) { if(clip_distance <= 0.0) { discard; } }
if(use_clip_plane == 1) { if(fragClipDistance <= 0.0) { discard; } }
#endif
// need depth and depth squared for variance shadow maps
gl_FragData[0] = vec4(position.z, position.z * position.z * VARIANCE_SHADOW_SCALE_INV, 0.0, 1.0);
fragOut0 = vec4(fragPosition.z, fragPosition.z * fragPosition.z * VARIANCE_SHADOW_SCALE_INV, 0.0, 1.0);
return;
#endif
vec3 eyeDir = vec3(normalize(-position).xyz);
vec3 eyeDir = vec3(normalize(-fragPosition).xyz);
vec3 lightAmbientDiffuse = vec3(0.0, 0.0, 0.0);
vec3 lightDiffuse = vec3(0.0, 0.0, 0.0);
vec3 lightAmbient = vec3(0.0, 0.0, 0.0);
vec4 lightSpecular = vec4(0.0, 0.0, 0.0, 1.0);
vec2 texCoord = gl_TexCoord[0].xy;
vec4 baseColor = gl_Color;
vec2 texCoord = fragTexCoord.xy;
vec4 baseColor = color;
#ifdef FLAG_HDR
baseColor.rgb = pow(baseColor.rgb, vec3(SRGB_GAMMA));
#endif
vec4 posData = vec4(position.xyz,1.0);
vec4 posData = vec4(fragPosition.xyz,1.0);
vec4 normData = vec4(0.0, 0.0, 0.0, 1.0);
vec4 specData = vec4(0.0, 0.0, 0.0, 1.0);
float glossData = 0.6;
@@ -304,14 +322,14 @@ void main()
// green is cavity occlusion factor which only affects diffuse and specular lighting.
aoFactors = texture2D(sAmbientmap, texCoord).xy;
#endif
vec3 unitNormal = normalize(lNormal);
vec3 unitNormal = normalize(fragNormal);
vec3 normal = unitNormal;
#ifdef FLAG_NORMAL_MAP
// Normal map - convert from DXT5nm
vec2 normalSample;
normal.rg = normalSample = (texture2D(sNormalmap, texCoord).ag * 2.0) - 1.0;
normal.rg = normalSample = (tex2D(sNormalmap, texCoord).ag * 2.0) - 1.0;
normal.b = sqrt(1.0 - dot(normal.rg, normal.rg));
normal = tbnMatrix * normal;
normal = fragTangentMatrix * normal;
float norm = length(normal);
// prevent breaking of normal maps
if (norm > 0.0)
@@ -322,7 +340,7 @@ void main()
normData = vec4(normal, 1.0);
#ifdef FLAG_ANIMATED
vec2 distort = vec2(cos(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005),sin(position.x*position.w*0.005+anim_timer*20.0)*cos(position.y*position.w*0.005))*0.03;
vec2 distort = vec2(cos(fragPosition.x*fragPosition.w*0.005+anim_timer*20.0)*sin(fragPosition.y*fragPosition.w*0.005),sin(fragPosition.x*fragPosition.w*0.005+anim_timer*20.0)*cos(fragPosition.y*fragPosition.w*0.005))*0.03;
#endif
#ifdef FLAG_DIFFUSE_MAP
@@ -332,7 +350,7 @@ void main()
diffuseTexCoord = texCoord + distort*(1.0-anim_timer);
}
#endif
baseColor = texture2D(sBasemap, diffuseTexCoord);
baseColor = tex2D(sBasemap, diffuseTexCoord);
if ( blend_alpha == 0 && baseColor.a < 0.95 ) discard; // if alpha blending is not on, discard transparent pixels
// premultiply alpha if blend_alpha is 1. assume that our blend function is srcColor + (1-Alpha)*destColor.
// if blend_alpha is 2, assume blend func is additive and don't modify color
@@ -360,7 +378,7 @@ void main()
#ifdef FLAG_MISC_MAP
#ifdef FLAG_TEAMCOLOR
vec4 teamMask = vec4(0.0, 0.0, 0.0, 0.0);
teamMask = texture2D(sMiscmap, texCoord);
teamMask = tex2D(sMiscmap, texCoord);
vec3 base = base_color - vec3(0.5);
vec3 stripe = stripe_color - vec3(0.5);
baseColor.rgb += (base * teamMask.x) + (stripe * teamMask.y);
@@ -375,13 +393,10 @@ void main()
#ifdef FLAG_LIGHT
baseColor.rgb = CalculateLighting(normal, baseColor.rgb, specData.rgb, glossData, shadow, aoFactors.x);
#else
baseColor.rgb *= max(gl_Color.rgb * AMBIENT_LIGHT_BOOST, gl_LightModel.ambient.rgb - 0.425);
baseColor.rgb += gl_SecondaryColor.rgb * specData.rgb;
#endif
#ifdef FLAG_ENV_MAP
vec3 envReflectNM = normalize(envReflect);
vec3 envReflectNM = fragEnvReflect;
#ifdef FLAG_NORMAL_MAP
envReflectNM += vec3(normalSample, 0.0);
envReflectNM = normalize(envReflectNM);
@@ -411,15 +426,15 @@ void main()
#endif
#ifdef FLAG_FOG
vec3 fogColor = gl_Fog.color.rgb;
vec3 finalFogColor = fogColor.rgb;
#ifdef FLAG_HDR
fogColor = pow(fogColor, vec3(SRGB_GAMMA));
finalFogColor = pow(finalFogColor, vec3(SRGB_GAMMA));
#endif
#ifdef FLAG_DIFFUSE_MAP
if(blend_alpha == 1) fogColor *= baseColor.a;
if(blend_alpha == 1) finalFogColor *= baseColor.a;
#endif
baseColor.rgb = mix(baseColor.rgb, fogColor, fogDist);
specData.rgb *= fogDist;
baseColor.rgb = mix(baseColor.rgb, finalFogColor, fragFogDist);
specData.rgb *= fragFogDist;
#endif
#ifdef FLAG_DIFFUSE_MAP
@@ -434,34 +449,38 @@ void main()
baseColor.a = baseColor.a * clamp(shinefactor * (fract(abs(texCoord.x))-anim_timer) * -10000.0,0.0,1.0);
}
if (effect_num == 1) {
float shinefactor = 1.0/(1.0 + pow(abs(position.y-anim_timer), 2.0));
float shinefactor = 1.0/(1.0 + pow(abs(fragPosition.y-anim_timer), 2.0));
baseColor.rgb = baseColor.rgb + vec3(shinefactor);
#ifdef FLAG_LIGHT
baseColor.a = baseColor.a;
#else
// ATI Wireframe fix *grumble*
baseColor.a = clamp((position.y-anim_timer) * 10000.0,0.0,1.0);
baseColor.a = clamp((fragPosition.y-anim_timer) * 10000.0,0.0,1.0);
#endif
}
if (effect_num == 2) {
vec2 screenPos = gl_FragCoord.xy * vec2(vpwidth,vpheight);
baseColor.a = baseColor.a;
float cloak_interp = (sin(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005)*0.5)-0.5;
float cloak_interp = (sin(fragPosition.x*fragPosition.w*0.005+anim_timer*20.0)*sin(fragPosition.y*fragPosition.w*0.005)*0.5)-0.5;
#ifdef FLAG_LIGHT
baseColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*normal.xy).rgb,baseColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
baseColor.rgb = mix(tex2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*normal.xy).rgb,baseColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#else
baseColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*lNormal.xy).rgb,baseColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
baseColor.rgb = mix(tex2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*fragNormal.xy).rgb,baseColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#endif
}
#endif
#ifdef FLAG_NORMAL_ALPHA
float normViewOffset = dot(vec3(0.0, 0.0, 1.0), normal);
baseColor.a = smoothstep(min(normalAlphaMinMax.x, normalAlphaMinMax.y), max(normalAlphaMinMax.x, normalAlphaMinMax.y), clamp(normalAlphaMinMax.x > normalAlphaMinMax.y ? normViewOffset : 1.0 - normViewOffset, 0.0, 1.0));
#endif
#ifdef FLAG_CLIP
// for some odd reason if we try to discard the pixel early for plane clipping, it screws up glow maps so let's just do it down here.
if(use_clip_plane == 1) { if(clip_distance <= 0.0) { discard; } }
if(use_clip_plane == 1) { if(fragClipDistance <= 0.0) { discard; } }
#endif
gl_FragData[0] = baseColor;
fragOut0 = baseColor;
#ifdef FLAG_DEFERRED
gl_FragData[1] = posData;
gl_FragData[2] = normData;
gl_FragData[3] = specData;
fragOut1 = posData;
fragOut2 = normData;
fragOut3 = specData;
#endif
}
};
+22 -15
View File
@@ -1,33 +1,40 @@
#extension GL_EXT_geometry_shader4 : enable
#extension GL_ARB_geometry_shader4 : enable
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
uniform mat4 shadow_proj_matrix[4];
varying in float Instance[3];
varying out vec4 position;
in float geoInstance[];
in vec3 geoNormal[];
in vec4 geoTexCoord[];
out vec4 fragPosition;
out vec3 fragNormal;
out vec4 fragTexCoord;
#ifdef FLAG_TRANSFORM
varying in float not_visible_g[];
varying out float not_visible;
in float geoNotVisible[];
out float fragNotVisible;
#endif
#ifdef FLAG_CLIP
varying in float clip_distance_g[];
varying out float clip_distance;
in float geoClipDistance[];
out float fragClipDistance;
#endif
void main(void)
{
int instanceID = int(Instance[0]);
for(int vert = 0; vert < gl_VerticesIn; vert++)
int instanceID = int(geoInstance[0]);
for(int vert = 0; vert < gl_in.length(); vert++)
{
gl_Position = shadow_proj_matrix[instanceID] * gl_PositionIn[vert];
gl_Position = shadow_proj_matrix[instanceID] * gl_in[vert].gl_Position;
if(gl_Position.z < -1.0)
gl_Position.z = -1.0;
position = gl_PositionIn[vert];
gl_ClipVertex = gl_ClipVertexIn[vert];
fragPosition = gl_in[vert].gl_Position;
fragNormal = geoNormal[vert];
fragTexCoord = geoTexCoord[vert];
gl_Layer = instanceID;
#ifdef FLAG_TRANSFORM
not_visible = not_visible_g[0];
fragNotVisible = geoNotVisible[0];
#endif
#ifdef FLAG_CLIP
clip_distance = clip_distance_g[0];
fragClipDistance = geoClipDistance[0];
#endif
EmitVertex();
}
EndPrimitive();
}
};
+73 -46
View File
@@ -7,37 +7,57 @@
#extension GL_ARB_draw_instanced : enable
#endif
#endif
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertIn vec3 vertNormal;
vertIn vec4 vertTangent;
vertIn float vertModelID;
uniform mat4 modelViewMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 textureMatrix;
uniform vec4 color;
#ifdef FLAG_NORMAL_EXTRUDE
uniform float extrudeWidth;
#endif
#ifdef FLAG_ENV_MAP
uniform mat4 envMatrix;
varying vec3 envReflect;
vertOut vec3 fragEnvReflect;
#endif
#ifdef FLAG_NORMAL_MAP
varying mat3 tbnMatrix;
vertOut mat3 fragTangentMatrix;
#endif
#ifdef FLAG_FOG
varying float fogDist;
uniform float fogStart;
uniform float fogScale;
vertOut float fragFogDist;
#endif
#ifdef FLAG_TRANSFORM
#extension GL_ARB_texture_buffer_object : enable
attribute float model_id;
uniform samplerBuffer transform_tex;
uniform int buffer_matrix_offset;
#ifdef FLAG_SHADOW_MAP
varying float not_visible_g;
vertOut float geoNotVisible;
#else
varying float not_visible;
vertOut float fragNotVisible;
#endif
#endif
#ifdef FLAG_SHADOW_MAP
varying float Instance;
vertOut float geoInstance;
uniform mat4 shadow_proj_matrix[4];
vertOut vec3 geoNormal;
vertOut vec4 geoTexCoord;
#else
vertOut vec4 fragPosition;
vertOut vec3 fragNormal;
vertOut vec4 fragTexCoord;
#endif
#ifdef FLAG_SHADOWS
uniform mat4 shadow_mv_matrix;
uniform mat4 shadow_proj_matrix[4];
uniform mat4 model_matrix;
varying vec4 shadow_vec[4];
varying vec4 pos_shadow;
vertOut vec4 fragShadowUV[4];
vertOut vec4 fragShadowPos;
#endif
#ifdef FLAG_THRUSTER
uniform float thruster_scale;
@@ -46,16 +66,12 @@ uniform float thruster_scale;
uniform int use_clip_plane;
uniform vec3 clip_normal;
uniform vec3 clip_position;
//uniform vec4 clip_plane;
uniform mat4 world_matrix;
#ifdef FLAG_SHADOW_MAP
varying float clip_distance_g;
vertOut float geoClipDistance;
#else
varying float clip_distance;
vertOut float fragClipDistance;
#endif
#endif
varying vec4 position;
varying vec3 lNormal;
#ifdef FLAG_TRANSFORM
#define TEXELS_PER_MATRIX 4
void getModelTransform(inout mat4 transform, inout float invisible, int id, int matrix_offset)
@@ -82,68 +98,79 @@ vec4 transformToShadowMap(int i, vec4 pos)
#endif
void main()
{
vec4 position;
vec3 normal;
vec4 texCoord;
mat4 orient = mat4(1.0);
mat4 scale = mat4(1.0);
#ifdef FLAG_TRANSFORM
float invisible; getModelTransform(orient, invisible, int(model_id), buffer_matrix_offset);
float invisible;
getModelTransform(orient, invisible, int(vertModelID), buffer_matrix_offset);
#ifdef FLAG_SHADOW_MAP
not_visible_g = invisible;
geoNotVisible = invisible;
#else
not_visible = invisible;
fragNotVisible = invisible;
#endif
#endif
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vec4 vertex = gl_Vertex;
texCoord = textureMatrix * vertTexCoord;
vec4 vertex = vertPosition;
#ifdef FLAG_THRUSTER
if(vertex.z < -1.5) {
vertex.z *= thruster_scale;
}
#endif
position = gl_ModelViewMatrix * orient * vertex;
// Transform the normal into eye space and normalize the result.
normal = normalize(mat3(modelViewMatrix) * mat3(orient) * vertNormal);
position = modelViewMatrix * orient * vertex;
#ifdef FLAG_SHADOW_MAP
gl_Position = position;
#ifdef APPLE
Instance = float(gl_InstanceIDARB);
geoInstance = float(gl_InstanceIDARB);
#else
Instance = float(gl_InstanceID);
geoInstance = float(gl_InstanceID);
#endif
#else
gl_Position = gl_ProjectionMatrix * position;
gl_Position = projMatrix * position;
#endif
#ifdef FLAG_NORMAL_EXTRUDE
gl_Position.xy += (mat3(projMatrix) * normal.xyz).xy * gl_Position.z * extrudeWidth;
#endif
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
// Transform the normal into eye space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * mat3(orient) * gl_Normal);
lNormal = normal;
#ifdef FLAG_SHADOWS
pos_shadow = shadow_mv_matrix * model_matrix * orient * gl_Vertex;
shadow_vec[0] = transformToShadowMap(0, pos_shadow);
shadow_vec[1] = transformToShadowMap(1, pos_shadow);
shadow_vec[2] = transformToShadowMap(2, pos_shadow);
shadow_vec[3] = transformToShadowMap(3, pos_shadow);
fragShadowPos = shadow_mv_matrix * modelMatrix * orient * vertPosition;
fragShadowUV[0] = transformToShadowMap(0, fragShadowPos);
fragShadowUV[1] = transformToShadowMap(1, fragShadowPos);
fragShadowUV[2] = transformToShadowMap(2, fragShadowPos);
fragShadowUV[3] = transformToShadowMap(3, fragShadowPos);
#endif
#ifdef FLAG_NORMAL_MAP
// Setup stuff for normal maps
vec3 t = normalize(gl_NormalMatrix * mat3(orient) * gl_MultiTexCoord1.xyz);
vec3 b = cross(normal, t) * gl_MultiTexCoord1.w;
tbnMatrix = mat3(t, b, normal);
vec3 t = normalize(mat3(modelViewMatrix) * mat3(orient) * vertTangent.xyz);
vec3 b = cross(normal, t) * vertTangent.w;
fragTangentMatrix = mat3(t, b, normal);
#endif
#ifdef FLAG_ENV_MAP
// Environment mapping reflection vector.
envReflect = reflect(normalize(position.xyz), normal);
envReflect = vec3(envMatrix * vec4(envReflect, 0.0));
fragEnvReflect = reflect(normalize(position.xyz), normal);
fragEnvReflect = vec3(envMatrix * vec4(fragEnvReflect, 0.0));
#endif
#ifdef FLAG_FOG
fogDist = clamp((gl_Position.z - gl_Fog.start) * 0.75 * gl_Fog.scale, 0.0, 1.0);
fragFogDist = clamp((gl_Position.z - fogStart) * 0.75 * fogScale, 0.0, 1.0);
#endif
#ifdef FLAG_CLIP
float clip_dist = 0.0;
if(use_clip_plane == 1) clip_dist = dot(normalize((world_matrix*orient*vertex).xyz - clip_position), clip_normal);
if(use_clip_plane == 1) clip_dist = dot(normalize((modelMatrix * orient * vertex).xyz - clip_position), clip_normal);
#ifdef FLAG_SHADOW_MAP
clip_distance_g = clip_dist;
geoClipDistance = clip_dist;
#else
clip_distance = clip_dist;
fragClipDistance = clip_dist;
#endif
#endif
gl_ClipVertex = (gl_ModelViewMatrix * orient * vertex);
}
#ifndef FLAG_SHADOW_MAP
fragPosition = position;
fragNormal = normal;
fragTexCoord = texCoord;
#else
geoNormal = normal;
geoTexCoord = texCoord;
#endif
};
+8 -5
View File
@@ -1,14 +1,17 @@
fragIn vec4 fragTexCoord;
fragIn vec4 fragColor;
uniform sampler2D baseMap;
uniform int alphaTexture;
uniform int noTexturing;
uniform int srgb;
uniform float intensity;
uniform float alphaThreshold;
#define SRGB_GAMMA 2.2
void main()
{
vec4 baseColor = texture2D(baseMap, gl_TexCoord[0].xy);
vec4 baseColor = texture2D(baseMap, fragTexCoord.xy);
if(alphaThreshold > baseColor.a) discard;
baseColor.rgb = (srgb == 1) ? pow(baseColor.rgb, vec3(SRGB_GAMMA)) : baseColor.rgb;
vec4 blendColor = (srgb == 1) ? vec4(pow(gl_Color.rgb, vec3(SRGB_GAMMA)), gl_Color.a) : gl_Color ;
baseColor *= blendColor;
gl_FragColor = mix(mix(baseColor, vec4(blendColor.rgb, baseColor.a), float(alphaTexture)), blendColor, float(noTexturing)) * intensity;
}
vec4 blendColor = (srgb == 1) ? vec4(pow(fragColor.rgb, vec3(SRGB_GAMMA)), fragColor.a) : fragColor;
fragOut0 = mix(mix(baseColor * blendColor, vec4(blendColor.rgb, baseColor.r * blendColor.a), float(alphaTexture)), blendColor, float(noTexturing)) * intensity;
};
+12 -5
View File
@@ -1,7 +1,14 @@
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertIn vec4 vertColor;
vertOut vec4 fragTexCoord;
vertOut vec4 fragColor;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform vec4 color;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
}
fragTexCoord = vertTexCoord;
fragColor = vertColor * color;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
};
+9 -8
View File
@@ -1,3 +1,4 @@
fragIn vec4 fragTexCoord;
uniform sampler2D tex;
uniform float timer;
uniform sampler2D bloomed;
@@ -33,7 +34,7 @@ void main()
{
#ifdef FLAG_DISTORT_NOISE
// Distort noise
float distort_factor = timer * sin(gl_TexCoord[0].x * gl_TexCoord[0].y * 100.0 + timer);
float distort_factor = timer * sin(fragTexCoord.x * fragTexCoord.y * 100.0 + timer);
distort_factor = mod(distort_factor, 8.0) * mod(distort_factor, 4.0);
vec2 distort;
distort = vec2(mod(distort_factor, noise_amount), mod(distort_factor, noise_amount + 0.002));
@@ -41,7 +42,7 @@ void main()
vec2 distort = vec2(0, 0);
#endif
// Global constant
vec4 color_in = texture2D(tex, gl_TexCoord[0].xy + distort);
vec4 color_in = tex2D(tex, fragTexCoord.xy + distort);
vec4 color_out;
// Bloom
if (bloom_intensity > 0.0) {
@@ -50,7 +51,7 @@ void main()
for (int mipmap = 0; mipmap < levels; ++mipmap) {
float scale = 1.0/exp2(float(mipmap));
factor += scale;
bloom += texture2DLod(bloomed, gl_TexCoord[0].xy + distort, float(mipmap)).rgb * scale;
bloom += tex2DLod(bloomed, fragTexCoord.xy + distort, float(mipmap)).rgb * scale;
}
bloom /= factor;
color_in.rgb += bloom;
@@ -75,7 +76,7 @@ void main()
#endif
#ifdef FLAG_GRAIN
// Film Grain
float x = gl_TexCoord[0].x * gl_TexCoord[0].y * timer * 1000.0;
float x = fragTexCoord.x * fragTexCoord.y * timer * 1000.0;
x = mod(x, 13.0) * mod(x, 123.0);
float dx = mod(x, 0.01);
vec3 result = color_out.rgb + color_out.rgb * clamp(0.1 + dx * 100.0, 0.0, 1.0);
@@ -84,8 +85,8 @@ void main()
#ifdef FLAG_STRIPES
// TV-Stripes (Old School)
vec2 sc;
sc.x = sin(gl_TexCoord[0].y * 2048.0);
sc.y = cos(gl_TexCoord[0].y * 2048.0);
sc.x = sin(fragTexCoord.y * 2048.0);
sc.y = cos(fragTexCoord.y * 2048.0);
vec3 stripes = color_out.rgb + color_out.rgb * vec3(sc.x, sc.y, sc.x) * 0.8;
color_out.rgb = mix(color_out.rgb, stripes, tv_stripes);
#endif
@@ -113,5 +114,5 @@ void main()
color_out.rgb = floor(color_out.rgb * downsampling_factor + bias) / downsampling_factor;
#endif
color_out.a = 1.0;
gl_FragColor = color_out;
}
fragOut0 = color_out;
};
+8 -9
View File
@@ -1,11 +1,10 @@
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertOut vec4 fragTexCoord;
vertOut float blurSize;
uniform float bsize;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
// Check necessary for ATI specific behavior
#ifdef __GLSL_CG_DATA_TYPES
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);
#endif
}
fragTexCoord = vertTexCoord;
gl_Position = vertPosition;
};
+5 -4
View File
@@ -1,10 +1,11 @@
#extension GL_EXT_texture_array : enable
fragIn vec4 fragTexCoord;
uniform sampler2DArray shadow_map;
//uniform sampler2D shadow_map;
uniform int index;
void main()
{
vec3 texcoord = vec3(gl_TexCoord[0].xy, float(index));
gl_FragColor = vec4(texture2DArray(shadow_map, texcoord).rgb,1.0);
//gl_FragColor = vec4(texture2D(shadow_map, gl_TexCoord[0].xy).rgb,1.0);
}
vec3 texcoord = vec3(fragTexCoord.xy, float(index));
fragOut0 = vec4(tex2DArray(shadow_map, texcoord).rgb,1.0);
//fragOut0 = vec4(tex2D(shadow_map, fragTexCoord.xy).rgb,1.0);
};
+6 -8
View File
@@ -1,10 +1,8 @@
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertOut vec4 fragTexCoord;
void main()
{
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = vec4(1.0);
gl_Position = gl_Vertex;
#ifdef __GLSL_CG_DATA_TYPES
// Check necessary for ATI specific behavior
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);
#endif
}
fragTexCoord = vertTexCoord;
gl_Position = vertPosition;
};
+4 -3
View File
@@ -1,3 +1,4 @@
fragIn vec4 fragTexCoord;
uniform sampler2D tex;
uniform float exposure;
vec3 Uncharted2Tonemapping(vec3 hdr_color)
@@ -13,10 +14,10 @@ vec3 Uncharted2Tonemapping(vec3 hdr_color)
#define SRGB_GAMMA 2.2
void main()
{
vec4 color = texture2D(tex, gl_TexCoord[0].xy);
vec4 color = tex2D(tex, fragTexCoord.xy);
// Tone mapping using John Hable's Uncharted 2 tonemapping algorithm.
float whitepoint = 11.2f; // hardcoded whitepoint value from Hable's algo
color.rgb = Uncharted2Tonemapping(color.rgb * exposure) / Uncharted2Tonemapping(vec3(whitepoint));
color.rgb = pow(color.rgb, vec3(1.0/SRGB_GAMMA)); // return from linear color space to SRGB color space
gl_FragColor = vec4(color.rgb, 1.0);
}
fragOut0 = vec4(color.rgb, 1.0);
};
+7 -6
View File
@@ -1,11 +1,12 @@
fragIn vec4 fragTexCoord;
uniform sampler2D ytex;
uniform sampler2D utex;
uniform sampler2D vtex;
void main()
{
vec3 val = vec3(texture2D(ytex, gl_TexCoord[0].st).r - 0.0625, texture2D(utex, gl_TexCoord[0].st).r - 0.5, texture2D(vtex, gl_TexCoord[0].st).r - 0.5);
gl_FragColor.r = dot(val, vec3(1.1640625, 0.0, 1.59765625));
gl_FragColor.g = dot(val, vec3(1.1640625, -0.390625, -0.8125));
gl_FragColor.b = dot(val, vec3(1.1640625, 2.015625, 0.0));
gl_FragColor.a = 1.0;
}
vec3 val = vec3(tex2D(ytex, fragTexCoord.st).r - 0.0625, tex2D(utex, fragTexCoord.st).r - 0.5, tex2D(vtex, fragTexCoord.st).r - 0.5);
fragOut0.r = dot(val, vec3(1.1640625, 0.0, 1.59765625));
fragOut0.g = dot(val, vec3(1.1640625, -0.390625, -0.8125));
fragOut0.b = dot(val, vec3(1.1640625, 2.015625, 0.0));
fragOut0.a = 1.0;
};
+8 -5
View File
@@ -1,7 +1,10 @@
vertIn vec4 vertPosition;
vertIn vec4 vertTexCoord;
vertOut vec4 fragTexCoord;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
gl_FrontColor = vec4(1.0);
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
}
fragTexCoord = vertTexCoord;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
};
+3 -14
View File
@@ -19,6 +19,7 @@
#include "object/object.h"
#include "parse/parselo.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include <stdlib.h>
@@ -982,25 +983,13 @@ void fireball_render(object* obj, draw_list *scene)
switch ( fb->fireball_render_type ) {
case FIREBALL_MEDIUM_EXPLOSION: {
batch_add_bitmap (
Fireballs[num].current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_EMISSIVE,
&p,
fb->orient,
obj->radius
);
batching_add_volume_bitmap(Fireballs[num].current_bitmap, &p, fb->orient, obj->radius);
}
break;
case FIREBALL_LARGE_EXPLOSION: {
// Make the big explosions rotate with the viewer.
batch_add_bitmap_rotated (
Fireballs[num].current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_EMISSIVE,
&p,
(i2fl(fb->orient)*PI)/180.0f,
obj->radius
);
batching_add_volume_bitmap_rotated(Fireballs[num].current_bitmap, &p, (i2fl(fb->orient)*PI) / 180.0f, obj->radius);
}
break;
+12 -4
View File
@@ -18,6 +18,7 @@
#include "model/model.h"
#include "nebula/neb.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
extern int Warp_model;
@@ -61,7 +62,8 @@ void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
vertlist[2] = *v3;
}
batch_add_tri(texture, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE, vertlist, 1.0f);
// batch_add_tri(texture, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE, vertlist, 1.0f);
batching_add_tri(texture, vertlist); // TODO render as emissive
}
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
@@ -214,6 +216,12 @@ void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *p
vm_vec_scale_add( &center, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
verts[0].r = 255;
verts[0].g = 255;
verts[0].b = 255;
verts[0].a = 255;
verts[1] = verts[2] = verts[3] = verts[4] = verts[0];
if (Warp_glow_bitmap >= 0) {
float r = radius;
@@ -254,7 +262,8 @@ void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *p
float alpha = (The_mission.flags[Mission::Mission_Flags::Fullneb]) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE , &verts[4], 0, r, alpha);
//batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
batching_add_bitmap(Warp_glow_bitmap, &verts[4], 0, r, alpha);
}
}
@@ -311,7 +320,7 @@ void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *p
verts[3].texture_position.v = 0.99f;
verts[4].texture_position.u = 0.5f;
verts[4].texture_position.v = 0.5f;
verts[4].texture_position.v = 0.5f;
g3_transfer_vertex( &verts[0], &vecs[0] );
g3_transfer_vertex( &verts[1], &vecs[1] );
@@ -326,7 +335,6 @@ void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *p
}
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
//flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
flash_ball warp_ball(20, .1f,.25f, &orient->vec.fvec, pos, 4.0f, 0.5f);
float adg = (2.0f * life_percent) - 1.0f;
-1
View File
@@ -74,7 +74,6 @@ bool Normalmap_override = false;
bool Heightmap_override = false;
bool Glowpoint_override = false;
bool Glowpoint_use_depth_buffer = true;
bool GLSL_override = false;
bool PostProcessing_override = false;
bool Teamcolor_override = false;
bool Shadow_override = false;
+187 -131
View File
@@ -75,9 +75,6 @@ int gr_global_zbuffering = 0;
// stencil buffer stuff
int gr_stencil_mode = 0;
// alpha mask stuff
int gr_alpha_test = 0;
// Default clipping distances
const float Default_min_draw_distance = 1.0f;
const float Default_max_draw_distance = 1e10;
@@ -1279,12 +1276,20 @@ void gr_bitmap(int _x, int _y, int resize_mode)
verts[3].texture_position.v = 1.0f;
// turn off zbuffering
int saved_zbuffer_mode = gr_zbuffer_get();
gr_zbuffer_set(GR_ZBUFF_NONE);
//int saved_zbuffer_mode = gr_zbuffer_get();
//gr_zbuffer_set(GR_ZBUFF_NONE);
gr_render(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_INTERFACE);
material mat_params;
material_set_interface(
&mat_params,
gr_screen.current_bitmap,
gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ? true : false,
gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ? gr_screen.current_alpha : 1.0f
);
gr_zbuffer_set(saved_zbuffer_mode);
g3_render_primitives_textured(&mat_params, verts, 4, PRIM_TYPE_TRIFAN, true);
//gr_zbuffer_set(saved_zbuffer_mode);
}
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode)
@@ -1292,10 +1297,6 @@ void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u
float x, y, w, h;
vertex verts[4];
if (gr_screen.mode == GR_STUB) {
return;
}
x = i2fl(_x);
y = i2fl(_y);
w = i2fl(_w);
@@ -1328,36 +1329,35 @@ void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u
verts[3].texture_position.u = _u0;
verts[3].texture_position.v = _v1;
// turn off zbuffering
int saved_zbuffer_mode = gr_zbuffer_get();
gr_zbuffer_set(GR_ZBUFF_NONE);
material material_params;
gr_render(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_INTERFACE);
gr_zbuffer_set(saved_zbuffer_mode);
material_set_interface(&material_params, gr_screen.current_bitmap, false, 1.0f);
g3_render_primitives_textured(&material_params, verts, 4, PRIM_TYPE_TRIFAN, true);
}
// NEW new bitmap functions -Bobboau
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode)
{
for (int i = 0; i < n_bm; i++) {
bitmap_2d_list *l = &list[i];
bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
}
}
g3_draw_2d_poly_bitmap_list(list, n_bm, TMAP_FLAG_INTERFACE);
}
// void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode)
// {
// for (int i = 0; i < n_bm; i++) {
// bitmap_2d_list *l = &list[i];
//
// bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
//
// if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
// gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
// }
// }
//
// g3_draw_2d_poly_bitmap_list(list, n_bm, TMAP_FLAG_INTERFACE);
// }
// _->NEW<-_ NEW new bitmap functions -Bobboau
//takes a list of rectangles that have assosiated rectangles in a texture
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode)
{
for(int i = 0; i < n_bm; i++) {
// adapted from g3_draw_2d_poly_bitmap_list
for ( int i = 0; i < n_bm; i++ ) {
bitmap_2d_list *l = &list[i].screen_rect;
// if no valid hight or width values were given get some from the bitmap
@@ -1370,19 +1370,91 @@ void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode)
}
}
g3_draw_2d_poly_bitmap_rect_list(list, n_bm, TMAP_FLAG_INTERFACE);
vertex* vert_list = new vertex[6 * n_bm];
float sw = 0.1f;
for ( int i = 0; i < n_bm; i++ ) {
// stuff coords
bitmap_2d_list* b = &list[i].screen_rect;
texture_rect_list* t = &list[i].texture_rect;
//tri one
vertex *V = &vert_list[i * 6];
V->screen.xyw.x = (float)b->x;
V->screen.xyw.y = (float)b->y;
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u0;
V->texture_position.v = (float)t->v0;
V->flags = PF_PROJECTED;
V->codes = 0;
V++;
V->screen.xyw.x = (float)(b->x + b->w);
V->screen.xyw.y = (float)b->y;
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u1;
V->texture_position.v = (float)t->v0;
V->flags = PF_PROJECTED;
V->codes = 0;
V++;
V->screen.xyw.x = (float)(b->x + b->w);
V->screen.xyw.y = (float)(b->y + b->h);
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u1;
V->texture_position.v = (float)t->v1;
V->flags = PF_PROJECTED;
V->codes = 0;
//tri two
V++;
V->screen.xyw.x = (float)b->x;
V->screen.xyw.y = (float)b->y;
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u0;
V->texture_position.v = (float)t->v0;
V->flags = PF_PROJECTED;
V->codes = 0;
V++;
V->screen.xyw.x = (float)(b->x + b->w);
V->screen.xyw.y = (float)(b->y + b->h);
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u1;
V->texture_position.v = (float)t->v1;
V->flags = PF_PROJECTED;
V->codes = 0;
V++;
V->screen.xyw.x = (float)b->x;
V->screen.xyw.y = (float)(b->y + b->h);
V->screen.xyw.w = sw;
V->texture_position.u = (float)t->u0;
V->texture_position.v = (float)t->v1;
V->flags = PF_PROJECTED;
V->codes = 0;
}
material material_params;
material_set_unlit(&material_params, gr_screen.current_bitmap, 1.0f, true, false);
g3_render_primitives_textured(&material_params, vert_list, 6 * n_bm, PRIM_TYPE_TRIS, true);
delete[] vert_list;
}
/**
* Given endpoints, and thickness, calculate coords of the endpoint
*/
* Given endpoints, and thickness, calculate coords of the endpoint
* Adapted from gr_pline_helper()
*/
void gr_pline_helper(vec3d *out, vec3d *in1, vec3d *in2, int thickness)
{
vec3d slope;
// slope of the line
if(vm_vec_same(in1, in2)) {
if ( vm_vec_same(in1, in2) ) {
slope = vmd_zero_vector;
} else {
vm_vec_sub(&slope, in2, in1);
@@ -1395,14 +1467,16 @@ void gr_pline_helper(vec3d *out, vec3d *in1, vec3d *in2, int thickness)
vm_vec_scale_add(out, in1, &slope, (float)thickness);
}
/**
* Special function for drawing polylines.
*
* This function is specifically intended for polylines where each section
* is no more than 90 degrees away from a previous section.
* Moreover, it is _really_ intended for use with 45 degree angles.
*/
void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
* Special function for drawing polylines.
*
* This function is specifically intended for polylines where each section
* is no more than 90 degrees away from a previous section.
* Moreover, it is _really_ intended for use with 45 degree angles.
* Adapted from gr_pline_special()
*/
void gr_pline_special(SCP_vector<vec3d> *pts, int thickness, int resize_mode)
{
vec3d s1, s2, e1, e2, dir;
vec3d last_e1, last_e2;
@@ -1414,22 +1488,25 @@ void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
size_t num_pts = pts->size();
// if we have less than 2 pts, bail
if(num_pts < 2) {
if ( num_pts < 2 ) {
return;
}
extern int G3_count;
if(G3_count == 0) {
if ( G3_count == 0 ) {
g3_start_frame(1);
started_frame = 1;
}
// turn off zbuffering
saved_zbuffer_mode = gr_zbuffer_get();
gr_zbuffer_set(GR_ZBUFF_NONE);
float sw = 0.1f;
// turn off culling
int cull = gr_set_cull(0);
color clr = gr_screen.current_color;
material material_def;
material_def.set_depth_mode(ZBUFFER_TYPE_NONE);
material_def.set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
material_def.set_cull_mode(false);
// draw each section
last_e1 = vmd_zero_vector;
@@ -1438,111 +1515,118 @@ void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
for(size_t idx=0; idx<num_pts-1; idx++) {
// get the start and endpoints
s1 = pts->at(idx); // start 1 (on the line)
e1 = pts->at(idx+1); // end 1 (on the line)
e1 = pts->at(idx + 1); // end 1 (on the line)
gr_pline_helper(&s2, &s1, &e1, thickness); // start 2
vm_vec_sub(&dir, &e1, &s1);
vm_vec_add(&e2, &s2, &dir); // end 2
// stuff coords
// stuff coords
v[0].screen.xyw.x = (float)ceil(s1.xyz.x);
v[0].screen.xyw.y = (float)ceil(s1.xyz.y);
v[0].screen.xyw.w = 0.0f;
v[0].screen.xyw.w = sw;
v[0].texture_position.u = 0.5f;
v[0].texture_position.v = 0.5f;
v[0].flags = PF_PROJECTED;
v[0].codes = 0;
v[0].r = gr_screen.current_color.red;
v[0].g = gr_screen.current_color.green;
v[0].b = gr_screen.current_color.blue;
v[0].r = clr.red;
v[0].g = clr.green;
v[0].b = clr.blue;
v[0].a = clr.alpha;
v[1].screen.xyw.x = (float)ceil(s2.xyz.x);
v[1].screen.xyw.y = (float)ceil(s2.xyz.y);
v[1].screen.xyw.w = 0.0f;
v[1].screen.xyw.w = sw;
v[1].texture_position.u = 0.5f;
v[1].texture_position.v = 0.5f;
v[1].flags = PF_PROJECTED;
v[1].codes = 0;
v[1].r = gr_screen.current_color.red;
v[1].g = gr_screen.current_color.green;
v[1].b = gr_screen.current_color.blue;
v[1].r = clr.red;
v[1].g = clr.green;
v[1].b = clr.blue;
v[1].a = clr.alpha;
v[2].screen.xyw.x = (float)ceil(e2.xyz.x);
v[2].screen.xyw.y = (float)ceil(e2.xyz.y);
v[2].screen.xyw.w = 0.0f;
v[2].screen.xyw.w = sw;
v[2].texture_position.u = 0.5f;
v[2].texture_position.v = 0.5f;
v[2].flags = PF_PROJECTED;
v[2].codes = 0;
v[2].r = gr_screen.current_color.red;
v[2].g = gr_screen.current_color.green;
v[2].b = gr_screen.current_color.blue;
v[2].r = clr.red;
v[2].g = clr.green;
v[2].b = clr.blue;
v[2].a = clr.alpha;
v[3].screen.xyw.x = (float)ceil(e1.xyz.x);
v[3].screen.xyw.y = (float)ceil(e1.xyz.y);
v[3].screen.xyw.w = 0.0f;
v[3].screen.xyw.w = sw;
v[3].texture_position.u = 0.5f;
v[3].texture_position.v = 0.5f;
v[3].flags = PF_PROJECTED;
v[3].codes = 0;
v[3].r = gr_screen.current_color.red;
v[3].g = gr_screen.current_color.green;
v[3].b = gr_screen.current_color.blue;
v[3].r = clr.red;
v[3].g = clr.green;
v[3].b = clr.blue;
v[3].a = clr.alpha;
//We could really do this better...but oh well. _WMC
if(resize_mode != GR_RESIZE_NONE) {
for(j=0;j<4;j++) {
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
if ( resize_mode != GR_RESIZE_NONE ) {
for ( j = 0; j<4; j++ ) {
gr_resize_screen_posf(&v[j].screen.xyw.x, &v[j].screen.xyw.y, NULL, NULL, resize_mode);
}
}
// draw the polys
g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
//g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
g3_render_primitives_colored(&material_def, v, 4, PRIM_TYPE_TRIFAN, true);
// if we're past the first section, draw a "patch" triangle to fill any gaps
if(idx > 0) {
if ( idx > 0 ) {
// stuff coords
v[0].screen.xyw.x = (float)ceil(s1.xyz.x);
v[0].screen.xyw.y = (float)ceil(s1.xyz.y);
v[0].screen.xyw.w = 0.0f;
v[0].screen.xyw.w = sw;
v[0].texture_position.u = 0.5f;
v[0].texture_position.v = 0.5f;
v[0].flags = PF_PROJECTED;
v[0].codes = 0;
v[0].r = gr_screen.current_color.red;
v[0].g = gr_screen.current_color.green;
v[0].b = gr_screen.current_color.blue;
v[0].r = clr.red;
v[0].g = clr.green;
v[0].b = clr.blue;
v[0].a = clr.alpha;
v[1].screen.xyw.x = (float)ceil(s2.xyz.x);
v[1].screen.xyw.y = (float)ceil(s2.xyz.y);
v[1].screen.xyw.w = 0.0f;
v[1].screen.xyw.w = sw;
v[1].texture_position.u = 0.5f;
v[1].texture_position.v = 0.5f;
v[1].flags = PF_PROJECTED;
v[1].codes = 0;
v[1].r = gr_screen.current_color.red;
v[1].g = gr_screen.current_color.green;
v[1].b = gr_screen.current_color.blue;
v[1].r = clr.red;
v[1].g = clr.green;
v[1].b = clr.blue;
v[1].a = clr.alpha;
v[2].screen.xyw.x = (float)ceil(last_e2.xyz.x);
v[2].screen.xyw.y = (float)ceil(last_e2.xyz.y);
v[2].screen.xyw.w = 0.0f;
v[2].screen.xyw.w = sw;
v[2].texture_position.u = 0.5f;
v[2].texture_position.v = 0.5f;
v[2].flags = PF_PROJECTED;
v[2].codes = 0;
v[2].r = gr_screen.current_color.red;
v[2].g = gr_screen.current_color.green;
v[2].b = gr_screen.current_color.blue;
v[2].r = clr.red;
v[2].g = clr.green;
v[2].b = clr.blue;
v[2].a = clr.alpha;
//Inefficiency or flexibility? you be the judge -WMC
if(resize_mode != GR_RESIZE_NONE) {
for(j=0;j<3;j++) {
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
if ( resize_mode != GR_RESIZE_NONE ) {
for ( j = 0; j<3; j++ ) {
gr_resize_screen_posf(&v[j].screen.xyw.x, &v[j].screen.xyw.y, NULL, NULL, resize_mode);
}
}
g3_draw_poly_constant_sw(3, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB, 0.1f);
g3_render_primitives_colored(&material_def, v, 3, PRIM_TYPE_TRIFAN, true);
}
// store our endpoints
@@ -1550,15 +1634,9 @@ void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
last_e2 = e2;
}
if(started_frame) {
if ( started_frame ) {
g3_end_frame();
}
// restore zbuffer mode
gr_zbuffer_set(saved_zbuffer_mode);
// restore culling
gr_set_cull(cull);
}
int poly_list::find_first_vertex(int idx)
@@ -1673,7 +1751,7 @@ void poly_list::allocate(int _verts)
tsb = (tsb_t*)vm_malloc(sizeof(tsb_t) * _verts);
}
if ( GLSL_version >= 130 ) {
if ( GLSL_version >= 150 ) {
submodels = (int*)vm_malloc(sizeof(int) * _verts);
}
@@ -1855,7 +1933,7 @@ void poly_list::make_index_buffer(SCP_vector<int> &vertex_list)
buffer_list_internal.tsb[z] = tsb[j];
}
if ( GLSL_version >= 130 ) {
if ( GLSL_version >= 150 ) {
buffer_list_internal.submodels[z] = submodels[j];
}
@@ -1885,7 +1963,7 @@ poly_list& poly_list::operator = (poly_list &other_list)
memcpy(tsb, other_list.tsb, sizeof(tsb_t) * other_list.n_verts);
}
if ( GLSL_version >= 130 ) {
if ( GLSL_version >= 150 ) {
memcpy(submodels, other_list.submodels, sizeof(int) * other_list.n_verts);
}
@@ -1982,21 +2060,8 @@ void gr_shield_icon(coord2d coords[6], int resize_mode)
if (gr_screen.mode == GR_STUB) {
return;
}
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&coords[0].x, &coords[0].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[1].x, &coords[1].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[2].x, &coords[2].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[3].x, &coords[3].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[4].x, &coords[4].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[5].x, &coords[5].y, NULL, NULL, resize_mode);
}
g3_draw_2d_shield_icon(coords,
gr_screen.current_color.red,
gr_screen.current_color.green,
gr_screen.current_color.blue,
gr_screen.current_color.alpha);
g3_render_shield_icon(&gr_screen.current_color, coords, resize_mode);
}
void gr_rect(int x, int y, int w, int h, int resize_mode)
@@ -2005,15 +2070,7 @@ void gr_rect(int x, int y, int w, int h, int resize_mode)
return;
}
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
}
g3_draw_2d_rect(x, y, w, h,
gr_screen.current_color.red,
gr_screen.current_color.green,
gr_screen.current_color.blue,
gr_screen.current_color.alpha);
g3_render_colored_rect(&gr_screen.current_color, x, y, w, h, resize_mode);
}
void gr_shade(int x, int y, int w, int h, int resize_mode)
@@ -2023,17 +2080,16 @@ void gr_shade(int x, int y, int w, int h, int resize_mode)
if (gr_screen.mode == GR_STUB) {
return;
}
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
}
r = (int)gr_screen.current_shader.r;
g = (int)gr_screen.current_shader.g;
b = (int)gr_screen.current_shader.b;
a = (int)gr_screen.current_shader.c;
color clr;
gr_init_alphacolor(&clr, r, g, b, a);
g3_draw_2d_rect(x, y, w, h, r, g, b, a);
g3_render_colored_rect(&clr, x, y, w, h, resize_mode);
}
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
+306 -64
View File
@@ -12,11 +12,14 @@
#ifndef _GRAPHICS_H
#define _GRAPHICS_H
#include "graphics/grinternal.h"
#include <osapi/osapi.h>
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "globalincs/pstypes.h"
#include "graphics/tmapper.h"
#include "cfile/cfile.h"
#include "math/vecmat.h"
#include "io/cursor.h"
extern const float Default_min_draw_distance;
@@ -29,7 +32,123 @@ extern int Gr_inited;
extern int gr_zbuffering, gr_zbuffering_mode;
extern int gr_global_zbuffering;
class material;
class model_material;
class particle_material;
class distortion_material;
struct transform
{
matrix basis;
vec3d origin;
vec3d scale;
transform() : basis(vmd_identity_matrix), origin(vmd_zero_vector), scale(vmd_scale_identity_vector) {}
transform(matrix *m, vec3d *v) : basis(*m), origin(*v) {}
matrix4 get_matrix4()
{
matrix4 new_mat;
vm_matrix4_set_identity(&new_mat);
new_mat.a1d[0] = basis.vec.rvec.xyz.x; new_mat.a1d[4] = basis.vec.uvec.xyz.x; new_mat.a1d[8] = basis.vec.fvec.xyz.x;
new_mat.a1d[1] = basis.vec.rvec.xyz.y; new_mat.a1d[5] = basis.vec.uvec.xyz.y; new_mat.a1d[9] = basis.vec.fvec.xyz.y;
new_mat.a1d[2] = basis.vec.rvec.xyz.z; new_mat.a1d[6] = basis.vec.uvec.xyz.z; new_mat.a1d[10] = basis.vec.fvec.xyz.z;
new_mat.a1d[12] = origin.xyz.x;
new_mat.a1d[13] = origin.xyz.y;
new_mat.a1d[14] = origin.xyz.z;
return new_mat;
}
};
class transform_stack {
matrix4 Current_transform;
SCP_vector<matrix4> Stack;
public:
transform_stack()
{
vm_matrix4_set_identity(&Current_transform);
Stack.clear();
Stack.push_back(Current_transform);
}
matrix4 &get_transform()
{
return Current_transform;
}
void clear()
{
vm_matrix4_set_identity(&Current_transform);
Stack.clear();
Stack.push_back(Current_transform);
}
void push_and_replace(matrix4 new_transform)
{
Current_transform = new_transform;
Stack.push_back(Current_transform);
}
void push(const vec3d *pos, const matrix *orient, const vec3d *scale = NULL)
{
vec3d new_scale = SCALE_IDENTITY_VECTOR;
matrix new_orient = IDENTITY_MATRIX;
vec3d new_pos = ZERO_VECTOR;
matrix4 current_transform_copy = Current_transform;
matrix4 new_transform;
if ( pos != NULL ) {
new_pos = *pos;
}
if ( orient != NULL ) {
new_orient = *orient;
}
if ( scale != NULL ) {
new_scale = *scale;
}
vm_vec_scale(&new_orient.vec.rvec, new_scale.xyz.x);
vm_vec_scale(&new_orient.vec.uvec, new_scale.xyz.y);
vm_vec_scale(&new_orient.vec.fvec, new_scale.xyz.z);
vm_matrix4_set_transform(&new_transform, &new_orient, &new_pos);
vm_matrix4_x_matrix4(&Current_transform, &current_transform_copy, &new_transform);
Stack.push_back(Current_transform);
}
void pop()
{
if ( Stack.size() > 1 ) {
Stack.pop_back();
}
Current_transform = Stack.back();
}
};
enum primitive_type {
PRIM_TYPE_POINTS,
PRIM_TYPE_LINES,
PRIM_TYPE_LINESTRIP,
PRIM_TYPE_TRIS,
PRIM_TYPE_TRISTRIP,
PRIM_TYPE_TRIFAN,
PRIM_TYPE_QUADS,
PRIM_TYPE_QUADSTRIP
};
enum shader_type {
SDR_TYPE_NONE = -1,
SDR_TYPE_MODEL,
SDR_TYPE_EFFECT_PARTICLE,
SDR_TYPE_EFFECT_DISTORTION,
@@ -70,18 +189,108 @@ enum shader_type {
#define SDR_FLAG_MODEL_CLIP (1<<17)
#define SDR_FLAG_MODEL_HDR (1<<18)
#define SDR_FLAG_MODEL_AMBIENT_MAP (1<<19)
#define SDR_FLAG_MODEL_NORMAL_ALPHA (1<<20)
#define SDR_FLAG_MODEL_NORMAL_EXTRUDE (1<<21)
#define SDR_FLAG_PARTICLE_POINT_GEN (1<<0)
#define SDR_FLAG_BLUR_HORIZONTAL (1<<0)
#define SDR_FLAG_BLUR_VERTICAL (1<<1)
struct vertex_format_data
{
enum vertex_format {
POSITION4,
POSITION3,
POSITION2,
SCREEN_POS,
COLOR3,
COLOR4,
TEX_COORD,
NORMAL,
TANGENT,
MODEL_ID,
RADIUS,
UVEC
};
vertex_format format_type;
size_t stride;
void *data_src;
int offset;
vertex_format_data(vertex_format i_format_type, size_t i_stride, void *i_data_src) :
format_type(i_format_type), stride(i_stride), data_src(i_data_src), offset(-1) {}
vertex_format_data(vertex_format i_format_type, size_t i_stride, int i_offset) :
format_type(i_format_type), stride(i_stride), data_src(NULL), offset(i_offset) {}
static inline uint mask(vertex_format v_format) { return 1 << v_format; }
};
class vertex_layout
{
SCP_vector<vertex_format_data> Vertex_components;
uint Vertex_mask;
public:
vertex_layout(): Vertex_mask(0) {}
vertex_layout(void* init_ptr): Vertex_mask(0) {}
size_t get_num_vertex_components() { return Vertex_components.size(); }
vertex_format_data* get_vertex_component(size_t index) { return &Vertex_components[index]; }
bool resident_vertex_format(vertex_format_data::vertex_format format_type)
{
return ( Vertex_mask & vertex_format_data::mask(format_type) ) ? true : false;
}
void add_vertex_component(vertex_format_data::vertex_format format_type, void* src)
{
add_vertex_component(format_type, 0, src);
}
void add_vertex_component(vertex_format_data::vertex_format format_type, size_t stride, void* src)
{
if ( resident_vertex_format(format_type) ) {
// we already have a vertex component of this format type
return;
}
Vertex_mask |= (1 << format_type);
Vertex_components.push_back(vertex_format_data(format_type, stride, src));
}
void add_vertex_component(vertex_format_data::vertex_format format_type, size_t stride, int offset)
{
if ( resident_vertex_format(format_type) ) {
// we already have a vertex component of this format type
return;
}
Vertex_mask |= (1 << format_type);
Vertex_components.push_back(vertex_format_data(format_type, stride, offset));
}
};
typedef enum gr_capability {
CAPABILITY_ENVIRONMENT_MAP,
CAPABILITY_NORMAL_MAP,
CAPABILITY_HEIGHT_MAP,
CAPABILITY_SOFT_PARTICLES,
CAPABILITY_DISTORTION,
CAPABILITY_POST_PROCESSING,
CAPABILITY_DEFERRED_LIGHTING,
CAPABILITY_SHADOWS,
CAPABILITY_BATCHED_SUBMODELS,
CAPABILITY_POINT_PARTICLES
} gr_capability;
// stencil buffering stuff
extern int gr_stencil_mode;
// alpha test
extern int gr_alpha_test;
/**
* This is a structure used by the shader to keep track
* of the values you want to use in the shade primitive.
@@ -315,13 +524,16 @@ public:
size_t stride;
size_t vertex_offset;
size_t vertex_num_offset;
poly_list *model_list;
SCP_vector<buffer_data> tex_buf;
vertex_layout layout;
vertex_buffer() :
flags(0), stride(0), vertex_offset(0), model_list(NULL)
flags(0), stride(0), vertex_offset(0), vertex_num_offset(0), model_list(NULL)
{
}
@@ -349,8 +561,26 @@ public:
}
};
struct indexed_vertex_source {
float *Vertex_list; // interleaved array
ubyte *Index_list;
int Vbuffer_handle;
int Ibuffer_handle;
uint Vertex_list_size;
uint Index_list_size;
indexed_vertex_source() :
Vertex_list(NULL), Index_list(NULL),
Vbuffer_handle(-1), Ibuffer_handle(-1), Vertex_list_size(0), Index_list_size(0)
{
}
};
struct light;
#define FIND_SCALED_NUM(x, x0, x1, y0, y1) ( ((((x) - (x0)) * ((y1) - (y0))) / ((x1) - (x0))) + (y0) )
#define GR_ALPHABLEND_NONE 0 // no blending
#define GR_ALPHABLEND_FILTER 1 // 50/50 mix of foreground, background, using intensity as alpha
@@ -548,14 +778,17 @@ typedef struct screen {
void (*gf_set_texture_addressing)(int);
int (*gf_create_vertex_buffer)(bool static_buffer);
int (*gf_create_index_buffer)(bool static_buffer);
void (*gf_delete_buffer)(int handle);
int (*gf_create_buffer)();
bool (*gf_pack_buffer)(const int buffer_id, vertex_buffer *vb);
bool (*gf_config_buffer)(const int buffer_id, vertex_buffer *vb, bool update_ibuffer_only);
void (*gf_destroy_buffer)(int);
void (*gf_set_buffer)(int);
void (*gf_render_buffer)(int, const vertex_buffer*, size_t, int);
void (*gf_render_buffer)(int, vertex_buffer*, size_t, int);
void (*gf_update_buffer_object)(int handle, size_t size, void* data);
void (*gf_update_buffer_data)(int handle, size_t size, void* data);
void (*gf_update_transform_buffer)(void* data, size_t size);
void (*gf_set_transform_buffer_offset)(size_t offset);
@@ -618,6 +851,7 @@ typedef struct screen {
void (*gf_line_htl)(const vec3d *start, const vec3d *end);
void (*gf_sphere_htl)(float rad);
void (*gf_sphere)(material *material_def, float rad);
int (*gf_maybe_create_shader)(shader_type type, unsigned int flags);
@@ -630,8 +864,19 @@ typedef struct screen {
void (*gf_update_texture)(int bitmap_handle, int bpp, const ubyte* data, int width, int height);
void (*gf_get_bitmap_from_texture)(void* data_out, int bitmap_num);
void (*gf_shadow_map_start)(const matrix4 *shadow_view_matrix, const matrix *light_matrix);
void (*gf_shadow_map_start)(matrix4 *shadow_view_matrix, const matrix *light_matrix);
void (*gf_shadow_map_end)();
// new drawing functions
void (*gf_render_model)(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, int texi);
void (*gf_render_primitives)(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_primitives_immediate)(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size);
void (*gf_render_primitives_particle)(particle_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_primitives_distortion)(distortion_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_primitives_2d)(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void (*gf_render_primitives_2d_immediate)(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size);
bool (*gf_is_capable)(gr_capability capability);
} screen;
// handy macro
@@ -865,16 +1110,27 @@ __inline int gr_bm_set_render_target(int n, int face = -1)
#define gr_set_texture_addressing GR_CALL(*gr_screen.gf_set_texture_addressing)
__inline int gr_create_vertex_buffer(bool static_buffer = false)
{
return (*gr_screen.gf_create_vertex_buffer)(static_buffer);
}
__inline int gr_create_index_buffer(bool static_buffer = false)
{
return (*gr_screen.gf_create_index_buffer)(static_buffer);
}
#define gr_delete_buffer GR_CALL(*gr_screen.gf_delete_buffer)
#define gr_create_buffer GR_CALL(*gr_screen.gf_create_buffer)
#define gr_pack_buffer GR_CALL(*gr_screen.gf_pack_buffer)
#define gr_config_buffer GR_CALL(*gr_screen.gf_config_buffer)
#define gr_destroy_buffer GR_CALL(*gr_screen.gf_destroy_buffer)
__inline void gr_render_buffer(int start, const vertex_buffer *bufferp, size_t texi, int flags = TMAP_FLAG_TEXTURED)
__inline void gr_render_buffer(int start, vertex_buffer *bufferp, size_t texi, int flags = TMAP_FLAG_TEXTURED)
{
(*gr_screen.gf_render_buffer)(start, bufferp, texi, flags);
}
#define gr_update_buffer_object GR_CALL(*gr_screen.gf_update_buffer_object)
#define gr_update_buffer_data GR_CALL(*gr_screen.gf_update_buffer_data)
#define gr_update_transform_buffer GR_CALL(*gr_screen.gf_update_transform_buffer)
#define gr_set_transform_buffer_offset GR_CALL(*gr_screen.gf_set_transform_buffer_offset)
@@ -934,6 +1190,7 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, size_t t
#define gr_line_htl GR_CALL(*gr_screen.gf_line_htl)
#define gr_sphere_htl GR_CALL(*gr_screen.gf_sphere_htl)
#define gr_sphere GR_CALL(*gr_screen.gf_sphere)
#define gr_maybe_create_shader GR_CALL(*gr_screen.gf_maybe_create_shader)
#define gr_set_animated_effect GR_CALL(*gr_screen.gf_set_animated_effect)
@@ -948,6 +1205,46 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, size_t t
#define gr_shadow_map_start GR_CALL(*gr_screen.gf_shadow_map_start)
#define gr_shadow_map_end GR_CALL(*gr_screen.gf_shadow_map_end)
__inline void gr_render_primitives(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle = -1)
{
(*gr_screen.gf_render_primitives)(material_info, prim_type, layout, offset, n_verts, buffer_handle);
}
__inline void gr_render_primitives_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
(*gr_screen.gf_render_primitives_immediate)(material_info, prim_type, layout, n_verts, data, size);
}
__inline void gr_render_primitives_particle(particle_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle = -1)
{
(*gr_screen.gf_render_primitives_particle)(material_info, prim_type, layout, offset, n_verts, buffer_handle);
}
__inline void gr_render_primitives_distortion(distortion_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle = -1)
{
(*gr_screen.gf_render_primitives_distortion)(material_info, prim_type, layout, offset, n_verts, buffer_handle);
}
__inline void gr_render_primitives_2d(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle = -1)
{
(*gr_screen.gf_render_primitives_2d)(material_info, prim_type, layout, offset, n_verts, buffer_handle);
}
__inline void gr_render_primitives_2d_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
(*gr_screen.gf_render_primitives_2d_immediate)(material_info, prim_type, layout, n_verts, data, size);
}
__inline void gr_render_model(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, int texi)
{
(*gr_screen.gf_render_model)(material_info, vert_source, bufferp, texi);
}
__inline bool gr_is_capable(gr_capability capability)
{
return (*gr_screen.gf_is_capable)(capability);
}
// color functions
void gr_get_color( int *r, int *g, int b );
void gr_init_color(color *c, int r, int g, int b);
@@ -1006,61 +1303,6 @@ void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode=GR_R
#define VB_FLAG_MODEL_ID (1<<11)
#define VB_FLAG_TRANS (1<<12)
struct vertex_format_data
{
enum vertex_format {
POSITION4,
POSITION3,
POSITION2,
SCREEN_POS,
COLOR3,
COLOR4,
TEX_COORD,
NORMAL,
TANGENT,
MODEL_ID,
RADIUS,
FVEC,
UVEC,
INTENSITY
};
vertex_format format_type;
size_t stride;
void *data_src;
vertex_format_data(vertex_format i_format_type, size_t i_stride, void *i_data_src) :
format_type(i_format_type), stride(i_stride), data_src(i_data_src) {}
};
class vertex_layout
{
SCP_vector<vertex_format_data> Vertex_components;
uint Vertex_mask;
public:
vertex_layout(): Vertex_mask(0) {}
size_t get_num_vertex_components() { return Vertex_components.size(); }
vertex_format_data* get_vertex_component(size_t index) { return &Vertex_components[index]; }
bool resident_vertex_format(vertex_format_data::vertex_format format_type) { return Vertex_mask & (1 << format_type) ? true : false; }
void add_vertex_component(vertex_format_data::vertex_format format_type, size_t stride, void* src)
{
if ( resident_vertex_format(format_type) ) {
// we already have a vertex component of this format type
return;
}
Vertex_mask |= (1 << format_type);
Vertex_components.push_back(vertex_format_data(format_type, stride, src));
}
};
/**
* @brief Prints the current time
*
+8 -4
View File
@@ -213,6 +213,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float dep
P[5].texture_position.u = 1.0f;
P[4].texture_position.u = 0.0f;
P[3].texture_position.u = 0.0f;
// tri 2
P[2].texture_position.u = 1.0f;
P[1].texture_position.u = 0.0f;
@@ -222,6 +223,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float dep
P[5].texture_position.u = 0.0f;
P[4].texture_position.u = 1.0f;
P[3].texture_position.u = 1.0f;
// tri 2
P[2].texture_position.u = 0.0f;
P[1].texture_position.u = 1.0f;
@@ -233,6 +235,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float dep
P[5].texture_position.v = 1.0f;
P[4].texture_position.v = 1.0f;
P[3].texture_position.v = 0.0f;
// tri 2
P[2].texture_position.v = 1.0f;
P[1].texture_position.v = 0.0f;
@@ -242,6 +245,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float dep
P[5].texture_position.v = 0.0f;
P[4].texture_position.v = 0.0f;
P[3].texture_position.v = 1.0f;
// tri 2
P[2].texture_position.v = 0.0f;
P[1].texture_position.v = 1.0f;
@@ -335,8 +339,9 @@ void geometry_batcher::draw_tri(vertex* verts)
{
vertex *P = &vert[n_to_render *3 ];
for (int i = 0; i < 3; i++)
for ( int i = 0; i < 3; i++ ) {
P[i] = verts[i];
}
n_to_render += 1;
use_radius = false;
@@ -358,7 +363,6 @@ void geometry_batcher::draw_quad(vertex* verts)
use_radius = false;
}
void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity, float offset)
{
vec3d p[4];
@@ -1116,7 +1120,7 @@ void geometry_batch_render(int stream_buffer)
batch_load_buffer_geometry_shader_map_bitmaps((particle_pnt*)Batch_geometry_buffer, &n_verts);
gr_update_buffer_object(stream_buffer, Batch_geometry_buffer_size, Batch_geometry_buffer);
gr_update_buffer_data(stream_buffer, Batch_geometry_buffer_size, Batch_geometry_buffer);
batch_render_geometry_shader_map_bitmaps(stream_buffer);
}
@@ -1140,7 +1144,7 @@ void batch_render_all(int stream_buffer)
batch_load_buffer_lasers((effect_vertex*)Batch_buffer, &n_verts);
batch_load_buffer_geometry_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
batch_load_buffer_distortion_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
gr_update_buffer_object(stream_buffer, Batch_buffer_size, Batch_buffer);
gr_update_buffer_data(stream_buffer, Batch_buffer_size, Batch_buffer);
Assert(n_verts <= n_to_render);
-3
View File
@@ -9,7 +9,6 @@
#ifndef __GRBATCH_H__
#define __GRBATCH_H__
class geometry_batcher
{
private:
@@ -27,7 +26,6 @@ private:
void allocate_internal(int n_verts);
void clone(const geometry_batcher &geo);
public:
geometry_batcher(): n_to_render(0), n_allocated(0), vert(NULL), use_radius(true), radius_list(NULL), buffer_offset(-1) {}
~geometry_batcher();
@@ -93,7 +91,6 @@ public:
size_t need_to_render() { return vertices.size(); }
};
float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r = 255, int g = 255, int b = 255);
int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha = 1.0f, float depth = 0.0f);
int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
-1
View File
@@ -13,7 +13,6 @@
#include "globalincs/globals.h" // just in case pstypes.h messed up
#include "globalincs/pstypes.h" // IAM_64BIT
#include "graphics/2d.h"
#include "graphics/font.h"
extern ubyte Gr_original_palette[768]; // The palette
+144 -18
View File
@@ -70,6 +70,8 @@ static ubyte *GL_saved_screen = NULL;
static int GL_saved_screen_id = -1;
static GLuint GL_screen_pbo = 0;
float GL_alpha_threshold = 0.0f;
extern const char *Osreg_title;
extern GLfloat GL_anisotropy;
@@ -86,6 +88,8 @@ static int GL_minimized = 0;
static GLenum GL_read_format = GL_BGRA;
GLuint GL_vao = 0;
static std::unique_ptr<os::OpenGLContext> GL_context = nullptr;
void opengl_go_fullscreen()
@@ -218,6 +222,7 @@ void gr_opengl_flip()
GL_context->swapBuffers();
opengl_tcache_frame();
opengl_reset_immediate_buffer();
#ifndef NDEBUG
int ic = opengl_check_for_errors();
@@ -451,6 +456,11 @@ void gr_opengl_shutdown(os::GraphicsOperations* graphicsOps)
GL_initted = false;
if ( GL_version >= 30 ) {
glDeleteVertexArrays(1, &GL_vao);
GL_vao = 0;
}
if (GL_original_gamma_ramp != NULL) {
SDL_SetWindowGammaRamp( os_get_window(), GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) );
}
@@ -506,13 +516,12 @@ void gr_opengl_fog_set(int fog_mode, int r, int g, int b, float fog_near, float
return;
}
if (OGL_fogmode == 3) {
glFogf(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
} else {
glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
if ( is_minimum_GLSL_version() && Current_shader != NULL && Current_shader->shader == SDR_TYPE_MODEL ) {
return;
}
glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
GL_state.Fog(GL_TRUE);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, fog_near);
@@ -650,9 +659,15 @@ void gr_opengl_stencil_clear()
int gr_opengl_alpha_mask_set(int mode, float alpha)
{
int tmp = gr_alpha_test;
if ( mode ) {
GL_alpha_threshold = alpha;
} else {
GL_alpha_threshold = 0.0f;
}
gr_alpha_test = mode;
if ( is_minimum_GLSL_version() ) { // alpha masking is deprecated
return mode;
}
if ( mode ) {
GL_state.AlphaTest(GL_TRUE);
@@ -662,7 +677,7 @@ int gr_opengl_alpha_mask_set(int mode, float alpha)
GL_state.AlphaFunc(GL_ALWAYS, 1.0f);
}
return tmp;
return mode;
}
// I feel dirty...
@@ -991,8 +1006,8 @@ void gr_opengl_translate_texture_matrix(int unit, const vec3d *shift)
void gr_opengl_set_line_width(float width)
{
GL_state.SetLineWidth(width);
GL_line_width = width;
glLineWidth(width);
}
// Returns the human readable error string if there is an error or NULL if not
@@ -1044,7 +1059,7 @@ void opengl_set_vsync(int status)
GL_CHECK_FOR_ERRORS("end of set_vsync()");
}
void opengl_setup_viewport()
void opengl_setup_viewport_fixed_pipeline()
{
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
@@ -1052,7 +1067,7 @@ void opengl_setup_viewport()
glLoadIdentity();
// the top and bottom positions are reversed on purpose, but RTT needs them the other way
if (GL_rendering_to_texture) {
if ( GL_rendering_to_texture ) {
glOrtho(0, gr_screen.max_w, 0, gr_screen.max_h, -1.0, 1.0);
} else {
glOrtho(0, gr_screen.max_w, gr_screen.max_h, 0, -1.0, 1.0);
@@ -1062,6 +1077,25 @@ void opengl_setup_viewport()
glLoadIdentity();
}
void opengl_setup_viewport()
{
if ( !is_minimum_GLSL_version() ) {
opengl_setup_viewport_fixed_pipeline();
return;
}
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
GL_last_projection_matrix = GL_projection_matrix;
// the top and bottom positions are reversed on purpose, but RTT needs them the other way
if (GL_rendering_to_texture) {
opengl_create_orthographic_projection_matrix(&GL_projection_matrix, 0, gr_screen.max_w, 0, gr_screen.max_h, -1.0, 1.0);
} else {
opengl_create_orthographic_projection_matrix(&GL_projection_matrix, 0, gr_screen.max_w, gr_screen.max_h, 0, -1.0, 1.0);
}
}
int opengl_init_display_device(os::GraphicsOperations* graphicsOps)
{
int bpp = gr_screen.bits_per_pixel;
@@ -1291,13 +1325,16 @@ void opengl_setup_function_pointers()
gr_screen.gf_set_fill_mode = gr_opengl_set_fill_mode;
gr_screen.gf_set_texture_panning = gr_opengl_set_texture_panning;
gr_screen.gf_create_vertex_buffer = gr_opengl_create_vertex_buffer;
gr_screen.gf_create_index_buffer = gr_opengl_create_index_buffer;
gr_screen.gf_delete_buffer = gr_opengl_delete_buffer;
gr_screen.gf_create_buffer = gr_opengl_create_buffer;
gr_screen.gf_config_buffer = gr_opengl_config_buffer;
gr_screen.gf_pack_buffer = gr_opengl_pack_buffer;
gr_screen.gf_destroy_buffer = gr_opengl_destroy_buffer;
gr_screen.gf_render_buffer = gr_opengl_render_buffer;
gr_screen.gf_set_buffer = gr_opengl_set_buffer;
gr_screen.gf_update_buffer_object = gr_opengl_update_buffer_object;
gr_screen.gf_update_buffer_data = gr_opengl_update_buffer_data;
gr_screen.gf_update_transform_buffer = gr_opengl_update_transform_buffer;
gr_screen.gf_set_transform_buffer_offset = gr_opengl_set_transform_buffer_offset;
@@ -1353,7 +1390,7 @@ void opengl_setup_function_pointers()
gr_screen.gf_set_line_width = gr_opengl_set_line_width;
gr_screen.gf_line_htl = gr_opengl_line_htl;
gr_screen.gf_sphere_htl = gr_opengl_sphere_htl;
gr_screen.gf_sphere = gr_opengl_sphere;
gr_screen.gf_set_animated_effect = gr_opengl_shader_set_animated_effect;
@@ -1367,6 +1404,20 @@ void opengl_setup_function_pointers()
gr_screen.gf_clear_states = gr_opengl_clear_states;
gr_screen.gf_set_team_color = gr_opengl_set_team_color;
gr_screen.gf_render_model = gr_opengl_render_model;
gr_screen.gf_render_primitives= gr_opengl_render_primitives;
gr_screen.gf_render_primitives_immediate = gr_opengl_render_primitives_immediate;
gr_screen.gf_render_primitives_2d = gr_opengl_render_primitives_2d;
gr_screen.gf_render_primitives_2d_immediate = gr_opengl_render_primitives_2d_immediate;
gr_screen.gf_render_primitives_particle = gr_opengl_render_primitives_particle;
gr_screen.gf_render_primitives_distortion = gr_opengl_render_primitives_distortion;
gr_screen.gf_is_capable = gr_opengl_is_capable;
// NOTE: All function pointers here should have a Cmdline_nohtl check at the top
// if they shouldn't be run in non-HTL mode, Don't keep separate entries.
// *****************************************************************************
}
#ifndef NDEBUG
@@ -1646,9 +1697,16 @@ bool gr_opengl_init(os::GraphicsOperations* graphicsOps)
if (is_minimum_GLSL_version()) {
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units);
max_texture_coords = 1;
} else {
glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
}
glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
// create vertex array object to make OpenGL Core happy if we can
if ( GL_version >= 30 ) {
glGenVertexArrays(1, &GL_vao);
glBindVertexArray(GL_vao);
}
GL_state.Texture.init(max_texture_units);
GL_state.Array.init(max_texture_coords);
@@ -1674,14 +1732,17 @@ bool gr_opengl_init(os::GraphicsOperations* graphicsOps)
opengl_set_vsync( !Cmdline_no_vsync );
opengl_setup_viewport();
vm_matrix4_set_identity(&GL_view_matrix);
vm_matrix4_set_identity(&GL_model_view_matrix);
glClear(GL_DEPTH_BUFFER_BIT);
glClear(GL_STENCIL_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_FOG_HINT, GL_NICEST);
if ( !is_minimum_GLSL_version() ) {
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_FOG_HINT, GL_NICEST);
}
if ( GLAD_GL_ARB_seamless_cube_map ) {
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
@@ -1741,6 +1802,71 @@ bool gr_opengl_init(os::GraphicsOperations* graphicsOps)
return true;
}
bool gr_opengl_is_capable(gr_capability capability)
{
if ( !is_minimum_GLSL_version() ) {
return false;
}
if ( GL_version < 20 ) {
return false;
}
switch ( capability ) {
case CAPABILITY_ENVIRONMENT_MAP:
return GLAD_GL_ARB_texture_cube_map ? true : false;
case CAPABILITY_NORMAL_MAP:
return Cmdline_normal ? true : false;
case CAPABILITY_HEIGHT_MAP:
return Cmdline_height ? true : false;
case CAPABILITY_SOFT_PARTICLES:
case CAPABILITY_DISTORTION:
return Cmdline_softparticles && (GLSL_version >= 120) && !Cmdline_no_fbo;
case CAPABILITY_POST_PROCESSING:
return Cmdline_postprocess && (GLSL_version >= 120) && !Cmdline_no_fbo;
case CAPABILITY_DEFERRED_LIGHTING:
return !Cmdline_no_fbo && !Cmdline_no_deferred_lighting && (GLSL_version >= 120);
case CAPABILITY_SHADOWS:
return GLAD_GL_ARB_draw_elements_base_vertex && GL_version >= 32;
case CAPABILITY_BATCHED_SUBMODELS:
return (GLSL_version >= 150) && GLAD_GL_ARB_texture_buffer_object && GLAD_GL_ARB_texture_float;
case CAPABILITY_POINT_PARTICLES:
return GL_version >= 32 && !Cmdline_no_geo_sdr_effects;
}
return false;
}
uint opengl_data_type_size(GLenum data_type)
{
switch ( data_type ) {
case GL_BYTE:
return sizeof(GLbyte);
case GL_UNSIGNED_BYTE:
return sizeof(GLubyte);
case GL_SHORT:
return sizeof(GLshort);
case GL_UNSIGNED_SHORT:
return sizeof(GLushort);
case GL_INT:
return sizeof(GLint);
case GL_UNSIGNED_INT:
return sizeof(GLuint);
case GL_FLOAT:
return sizeof(GLfloat);
case GL_2_BYTES:
return sizeof(GLbyte) * 2;
case GL_3_BYTES:
return sizeof(GLbyte) * 3;
case GL_4_BYTES:
return sizeof(GLbyte) * 4;
case GL_DOUBLE:
return sizeof(GLdouble);
}
return 0;
}
DCF(ogl_minimize, "Minimizes opengl")
{
bool minimize_ogl = false;
+6
View File
@@ -12,6 +12,7 @@
#ifndef _GROPENGL_H
#define _GROPENGL_H
#include <glad/glad.h>
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
@@ -20,6 +21,8 @@ const ubyte GL_zero_3ub[3] = { 0, 0, 0 };
bool gr_opengl_init(os::GraphicsOperations* graphicsOps);
void gr_opengl_cleanup(os::GraphicsOperations* graphicsOps, bool closing, int minimize=1);
int opengl_check_for_errors(char *err_at = NULL);
bool gr_opengl_is_capable(gr_capability capability);
uint opengl_data_type_size(GLenum data_type);
bool is_minimum_GLSL_version();
#ifndef NDEBUG
@@ -34,6 +37,9 @@ extern int GLSL_version;
extern int Use_VBOs;
extern int Use_PBOs;
extern GLuint GL_vao;
extern float GL_alpha_threshold;
extern float GL_line_width;
#endif
+1 -1
View File
@@ -132,7 +132,7 @@ int gr_opengl_bm_make_render_target(int n, int *width, int *height, int *bpp, in
if ( (flags & BMP_FLAG_CUBEMAP) && (*width != *height) ) {
MIN(*width, *height) = MAX(*width, *height);
}
if ( opengl_make_render_target(bm_bitmaps[n].handle, n, width, height, bpp, mm_lvl, flags) ) {
return 1;
}
+299 -287
View File
@@ -89,28 +89,6 @@ namespace
}
}
#ifdef _WIN32
#include "graphics/gl/glu.h"
#elif defined(SCP_UNIX)
#ifdef __APPLE__
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif // __APPLE__
#endif
#ifdef _WIN32
#include "graphics/gl/glu.h"
#elif defined(SCP_UNIX)
#ifdef __APPLE__
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif // __APPLE__
#endif
GLuint Scene_framebuffer;
GLuint Scene_ldr_texture;
GLuint Scene_color_texture;
@@ -149,107 +127,131 @@ GLuint deferred_light_cylinder_ibo = 0;
GLushort deferred_light_cylinder_vcount = 0;
GLuint deferred_light_cylinder_icount = 0;
struct opengl_vertex_bind {
vertex_format_data::vertex_format format;
enum type {
POSITION,
COLOR,
TEXCOORD0,
TEXCOORD1,
NORMAL,
ATTRIB
};
opengl_vertex_bind::type binding_type;
GLint size;
GLenum data_type;
// used only by vertex attributes
SCP_string attrib_name;
GLboolean normalized;
};
static opengl_vertex_bind GL_array_binding_data[] =
{
{ vertex_format_data::POSITION4, opengl_vertex_bind::POSITION, 4, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::POSITION3, opengl_vertex_bind::POSITION, 3, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::POSITION2, opengl_vertex_bind::POSITION, 2, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::SCREEN_POS, opengl_vertex_bind::POSITION, 2, GL_INT, "", GL_FALSE },
{ vertex_format_data::COLOR3, opengl_vertex_bind::COLOR, 3, GL_UNSIGNED_BYTE, "", GL_FALSE },
{ vertex_format_data::COLOR4, opengl_vertex_bind::COLOR, 4, GL_UNSIGNED_BYTE, "", GL_FALSE },
{ vertex_format_data::TEX_COORD, opengl_vertex_bind::TEXCOORD0, 2, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::NORMAL, opengl_vertex_bind::NORMAL, 3, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::TANGENT, opengl_vertex_bind::TEXCOORD1, 4, GL_FLOAT, "", GL_FALSE },
{ vertex_format_data::MODEL_ID, opengl_vertex_bind::ATTRIB, 1, GL_FLOAT, "model_id", GL_FALSE },
{ vertex_format_data::RADIUS, opengl_vertex_bind::ATTRIB, 1, GL_FLOAT, "radius", GL_FALSE },
{ vertex_format_data::FVEC, opengl_vertex_bind::ATTRIB, 3, GL_FLOAT, "fvec", GL_FALSE },
{ vertex_format_data::UVEC, opengl_vertex_bind::ATTRIB, 3, GL_FLOAT, "uvec", GL_FALSE },
{ vertex_format_data::INTENSITY, opengl_vertex_bind::ATTRIB, 1, GL_FLOAT, "intensity", GL_FALSE }
{ vertex_format_data::POSITION4, 4, GL_FLOAT, GL_FALSE, opengl_vert_attrib::POSITION },
{ vertex_format_data::POSITION3, 3, GL_FLOAT, GL_FALSE, opengl_vert_attrib::POSITION },
{ vertex_format_data::POSITION2, 2, GL_FLOAT, GL_FALSE, opengl_vert_attrib::POSITION },
{ vertex_format_data::SCREEN_POS, 2, GL_INT, GL_FALSE, opengl_vert_attrib::POSITION },
{ vertex_format_data::COLOR3, 3, GL_UNSIGNED_BYTE, GL_TRUE,opengl_vert_attrib::COLOR },
{ vertex_format_data::COLOR4, 4, GL_UNSIGNED_BYTE, GL_TRUE, opengl_vert_attrib::COLOR },
{ vertex_format_data::TEX_COORD, 2, GL_FLOAT, GL_FALSE, opengl_vert_attrib::TEXCOORD },
{ vertex_format_data::NORMAL, 3, GL_FLOAT, GL_FALSE, opengl_vert_attrib::NORMAL },
{ vertex_format_data::TANGENT, 4, GL_FLOAT, GL_FALSE, opengl_vert_attrib::TANGENT },
{ vertex_format_data::MODEL_ID, 1, GL_FLOAT, GL_FALSE, opengl_vert_attrib::MODEL_ID },
{ vertex_format_data::RADIUS, 1, GL_FLOAT, GL_FALSE, opengl_vert_attrib::RADIUS },
{ vertex_format_data::UVEC, 3, GL_FLOAT, GL_FALSE, opengl_vert_attrib::UVEC }
};
void opengl_bind_vertex_component(vertex_format_data &vert_component)
inline GLenum opengl_primitive_type(primitive_type prim_type)
{
switch ( prim_type ) {
case PRIM_TYPE_POINTS:
return GL_POINTS;
case PRIM_TYPE_TRIS:
return GL_TRIANGLES;
case PRIM_TYPE_TRISTRIP:
return GL_TRIANGLE_STRIP;
case PRIM_TYPE_TRIFAN:
return GL_TRIANGLE_FAN;
case PRIM_TYPE_QUADS:
return GL_QUADS;
case PRIM_TYPE_QUADSTRIP:
return GL_QUAD_STRIP;
case PRIM_TYPE_LINES:
return GL_LINES;
case PRIM_TYPE_LINESTRIP:
return GL_LINE_STRIP;
default:
return GL_TRIANGLE_FAN;
}
}
void opengl_bind_vertex_component(vertex_format_data &vert_component, uint base_vertex, ubyte* base_ptr)
{
opengl_vertex_bind &bind_info = GL_array_binding_data[vert_component.format_type];
opengl_vert_attrib &attrib_info = GL_vertex_attrib_info[bind_info.attribute_id];
switch ( bind_info.binding_type ) {
case opengl_vertex_bind::POSITION:
Assert(bind_info.attribute_id == attrib_info.attribute_id);
uint byte_offset = 0;
// determine if we need to offset into this vertex buffer by # of base_vertex vertices
if ( base_vertex > 0 ) {
if ( vert_component.stride > 0 ) {
// we have a stride so it's just number of bytes per stride times number of verts
byte_offset = vert_component.stride * base_vertex;
} else {
// no stride so that means verts are tightly packed so offset based off of the data type and width.
byte_offset = bind_info.size * opengl_data_type_size(bind_info.data_type) * base_vertex;
}
}
GLubyte *data_src;
if ( vert_component.offset >= 0 ) {
data_src = (GLubyte*)base_ptr + vert_component.offset + byte_offset;
} else {
data_src = (GLubyte*)vert_component.data_src + byte_offset;
}
if ( is_minimum_GLSL_version() && Current_shader != NULL ) {
// grabbing a vertex attribute is dependent on what current shader has been set. i hope no one calls opengl_bind_vertex_layout before opengl_set_current_shader
GLint index = opengl_shader_get_attribute(attrib_info.name.c_str());
if ( index >= 0 ) {
GL_state.Array.EnableVertexAttrib(index);
GL_state.Array.VertexAttribPointer(index, bind_info.size, bind_info.data_type, bind_info.normalized, (GLsizei)vert_component.stride, data_src);
}
return;
}
switch ( attrib_info.attribute_id ) {
case opengl_vert_attrib::POSITION:
{
GL_state.Array.EnableClientVertex();
GL_state.Array.VertexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, vert_component.data_src);
GL_state.Array.VertexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, data_src);
break;
}
case opengl_vertex_bind::TEXCOORD0:
case opengl_vert_attrib::TEXCOORD:
{
GL_state.Array.SetActiveClientUnit(0);
GL_state.Array.EnableClientTexture();
GL_state.Array.TexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, vert_component.data_src);
GL_state.Array.TexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, data_src);
break;
}
case opengl_vertex_bind::TEXCOORD1:
case opengl_vert_attrib::TANGENT:
{
GL_state.Array.SetActiveClientUnit(1);
GL_state.Array.EnableClientTexture();
GL_state.Array.TexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, vert_component.data_src);
GL_state.Array.TexPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, data_src);
break;
}
case opengl_vertex_bind::COLOR:
case opengl_vert_attrib::COLOR:
{
GL_state.Array.EnableClientColor();
GL_state.Array.ColorPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, vert_component.data_src);
GL_state.Array.ColorPointer(bind_info.size, bind_info.data_type, (GLsizei)vert_component.stride, data_src);
GL_state.InvalidateColor();
break;
}
case opengl_vertex_bind::NORMAL:
case opengl_vert_attrib::NORMAL:
{
GL_state.Array.EnableClientNormal();
GL_state.Array.NormalPointer(bind_info.data_type, (GLsizei)vert_component.stride, vert_component.data_src);
break;
}
case opengl_vertex_bind::ATTRIB:
{
// grabbing a vertex attribute is dependent on what current shader has been set. i hope no one calls opengl_bind_vertex_layout before opengl_set_current_shader
GLint index = opengl_shader_get_attribute(bind_info.attrib_name.c_str());
if ( index >= 0 ) {
GL_state.Array.EnableVertexAttrib(index);
GL_state.Array.VertexAttribPointer(index, bind_info.size, bind_info.data_type, bind_info.normalized, (GLsizei)vert_component.stride, vert_component.data_src);
}
GL_state.Array.NormalPointer(bind_info.data_type, (GLsizei)vert_component.stride, data_src);
break;
}
}
}
void opengl_bind_vertex_layout(vertex_layout &layout)
void opengl_bind_vertex_layout(vertex_layout &layout, uint base_vertex, ubyte* base_ptr)
{
GL_state.Array.BindPointersBegin();
size_t num_vertex_bindings = layout.get_num_vertex_components();
for (size_t i = 0; i < num_vertex_bindings; ++i ) {
opengl_bind_vertex_component(*layout.get_vertex_component(i));
for ( size_t i = 0; i < num_vertex_bindings; ++i ) {
opengl_bind_vertex_component(*layout.get_vertex_component(i), base_vertex, base_ptr);
}
GL_state.Array.BindPointersEnd();
@@ -321,11 +323,12 @@ void opengl_aabitmap_ex_internal(int x, int y, int w, int h, int sx, int sy, int
GLboolean cull_face = GL_state.CullFace(GL_FALSE);
opengl_shader_set_passthrough(true, true);
opengl_shader_set_passthrough(true, true, &gr_screen.current_color);
opengl_draw_textured_quad(x1,y1,u0,v0, x2,y2,u1,v1);
GL_state.CullFace(cull_face);
gr_clear_states();
GL_CHECK_FOR_ERRORS("end of aabitmap_ex_internal()");
}
@@ -509,7 +512,7 @@ void gr_opengl_aabitmap(int x, int y, int resize_mode, bool mirror)
opengl_aabitmap_ex_internal(dx1, dy1, (dx2 - dx1 + 1), (dy2 - dy1 + 1), sx, sy, resize_mode, mirror);
}
#define MAX_VERTS_PER_DRAW 120
#define MAX_VERTS_PER_DRAW 300
struct v4 { GLfloat x,y,u,v; };
static v4 GL_string_render_buff[MAX_VERTS_PER_DRAW];
@@ -526,20 +529,20 @@ void gr_opengl_string_old(float sx, float sy, const char* s, const char* end, fo
float bw, bh;
float u0, u1, v0, v1;
float x1, x2, y1, y2;
float u_scale, v_scale;
float u_scale = 1.0f, v_scale = 1.0f;
GL_CHECK_FOR_ERRORS("start of string()");
gr_set_bitmap(fontData->bitmap_id);
GL_state.SetTextureSource(TEXTURE_SOURCE_NO_FILTERING);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
if (!gr_opengl_tcache_set(gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale)) {
return;
}
gr_set_bitmap(fontData->bitmap_id);
GL_state.SetTextureSource(TEXTURE_SOURCE_NO_FILTERING);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
if (!gr_opengl_tcache_set(gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale)) {
return;
}
int buffer_offset = 0;
int ibw, ibh;
@@ -575,16 +578,12 @@ void gr_opengl_string_old(float sx, float sy, const char* s, const char* end, fo
spacing = 0;
GL_state.Array.BindArrayBuffer(0);
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(v4), &GL_string_render_buff[0].x);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(v4), &GL_string_render_buff[0].u);
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(v4), (int)offsetof(v4, x));
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(v4), (int)offsetof(v4, u));
opengl_bind_vertex_layout(vert_def);
//opengl_shader_set_current();
opengl_shader_set_passthrough(true, true);
opengl_shader_set_passthrough(true, true, &gr_screen.current_color);
// pick out letter coords, draw it, goto next letter and do the same
while (s < end) {
@@ -676,7 +675,7 @@ void gr_opengl_string_old(float sx, float sy, const char* s, const char* end, fo
v1 = v_scale * (i2fl((v+yd)+hc) / bh);
if ( buffer_offset == MAX_VERTS_PER_DRAW ) {
glDrawArrays(GL_TRIANGLES, 0, buffer_offset);
opengl_render_primitives_immediate(PRIM_TYPE_TRIS, &vert_def, buffer_offset, GL_string_render_buff, sizeof(v4) * buffer_offset);
buffer_offset = 0;
}
@@ -718,10 +717,11 @@ void gr_opengl_string_old(float sx, float sy, const char* s, const char* end, fo
}
if (buffer_offset) {
glDrawArrays(GL_TRIANGLES, 0, buffer_offset);
opengl_render_primitives_immediate(PRIM_TYPE_TRIS, &vert_def, buffer_offset, GL_string_render_buff, sizeof(v4) * buffer_offset);
}
GL_CHECK_FOR_ERRORS("end of string()");
gr_clear_states();
}
void gr_opengl_string(float sx, float sy, const char *s, int resize_mode, int in_length) {
@@ -1208,7 +1208,7 @@ void opengl_draw_primitive(int nv, vertex **verts, uint flags, float u_scale, fl
color_scale = 2.0f;
}
opengl_shader_set_passthrough(textured, false, color_scale);
opengl_shader_set_passthrough(textured, false, NULL, color_scale);
opengl_bind_vertex_layout(vert_def);
glDrawArrays(gl_mode, 0, nv);
@@ -1379,7 +1379,7 @@ void opengl_tmapper_internal3d(int nv, vertex **verts, uint flags)
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, 0, &uvcoords.front());
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough(textured, false, color_scale);
opengl_shader_set_passthrough(textured, false, NULL, color_scale);
glDrawArrays(gl_mode, 0, nv);
@@ -1490,6 +1490,7 @@ void opengl_render_internal(int nverts, vertex *verts, uint flags)
void opengl_render_internal3d(int nverts, vertex *verts, uint flags)
{
return;
int alpha, tmap_type, r, g, b;
float u_scale = 1.0f, v_scale = 1.0f;
GLenum gl_mode = GL_TRIANGLE_FAN;
@@ -1543,7 +1544,7 @@ void opengl_render_internal3d(int nverts, vertex *verts, uint flags)
vert_def.add_vertex_component(vertex_format_data::POSITION3, sizeof(vertex), &verts[0].world.xyz.x);
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough(textured, false, color_scale);
opengl_shader_set_passthrough(textured, false, NULL, color_scale);
glDrawArrays(gl_mode, 0, nverts);
@@ -1574,20 +1575,6 @@ void gr_opengl_render_effect(int nverts, vertex *verts, float *radius_list, uint
if ( flags & TMAP_FLAG_TEXTURED ) {
if ( flags & TMAP_FLAG_SOFT_QUAD ) {
if( (flags & TMAP_FLAG_DISTORTION) || (flags & TMAP_FLAG_DISTORTION_THRUSTER) )
{
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
opengl_tnl_set_material_distortion(flags);
zbuff = gr_zbuffer_set(GR_ZBUFF_READ);
}
else
{
opengl_tnl_set_material_soft_particle(flags);
zbuff = gr_zbuffer_set(GR_ZBUFF_NONE);
}
vert_def.add_vertex_component(vertex_format_data::RADIUS, 0, radius_list);
} else {
opengl_shader_set_passthrough(true);
@@ -1649,9 +1636,6 @@ void gr_opengl_render(int nverts, vertex *verts, uint flags)
}
}
#define FIND_SCALED_NUM(x, x0, x1, y0, y1) ( ((((x) - (x0)) * ((y1) - (y0))) / ((x1) - (x0))) + (y0) )
void gr_opengl_scaler(vertex *va, vertex *vb, bool bw_bitmap = false)
{
float x0, y0, x1, y1;
@@ -1826,6 +1810,10 @@ void gr_opengl_shade(int x, int y, int w, int h, int resize_mode)
GL_state.Color( (GLubyte)gr_screen.current_shader.r, (GLubyte)gr_screen.current_shader.g,
(GLubyte)gr_screen.current_shader.b, (GLubyte)gr_screen.current_shader.c );
color clr;
gr_init_alphacolor(&clr, gr_screen.current_shader.r, gr_screen.current_shader.g, gr_screen.current_shader.b, gr_screen.current_shader.c);
opengl_shader_set_passthrough(false, false, &clr);
opengl_draw_coloured_quad((GLint)x1, (GLint)y1, (GLint)x2, (GLint)y2);
gr_opengl_end_2d_matrix();
@@ -1852,6 +1840,10 @@ void gr_opengl_flash(int r, int g, int b)
GL_state.Color( (GLubyte)r, (GLubyte)g, (GLubyte)b, 255 );
color clr;
gr_init_alphacolor(&clr, (GLubyte)r, (GLubyte)g, (GLubyte)b, 255);
opengl_shader_set_passthrough(false, false, &clr);
opengl_draw_coloured_quad((GLint)x1, (GLint)y1, (GLint)x2, (GLint)y2);
}
@@ -1877,6 +1869,10 @@ void gr_opengl_flash_alpha(int r, int g, int b, int a)
GL_state.Color( (GLubyte)r, (GLubyte)g, (GLubyte)b, (GLubyte)a );
color clr;
gr_init_alphacolor(&clr, (GLubyte)r, (GLubyte)g, (GLubyte)b, (GLubyte)a);
opengl_shader_set_passthrough(false, false, &clr);
opengl_draw_coloured_quad((GLint)x1, (GLint)y1, (GLint)x2, (GLint)y2);
}
@@ -1924,9 +1920,14 @@ void opengl_bitmap_ex_internal(int x, int y, int w, int h, int sx, int sy, int r
}
GL_state.Color(255, 255, 255, (GLubyte)(gr_screen.current_alpha * 255));
opengl_shader_set_passthrough();
color clr;
gr_init_alphacolor(&clr, 255, 255, 255, gr_screen.current_alpha * 255);
opengl_shader_set_passthrough(true, false, &clr);
opengl_draw_textured_quad(x1, y1, u0, v0, x2, y2, u1, v1);
gr_clear_states();
}
@@ -2085,41 +2086,11 @@ void gr_opengl_bitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_
gr_opengl_bitmap_ex(dx1, dy1, dx2-dx1+1, dy2-dy1+1, sx, sy, resize_mode);
}*/
void gr_opengl_sphere_htl(float rad)
void gr_opengl_sphere(material* material_def, float rad)
{
GLUquadricObj *quad = NULL;
opengl_tnl_set_material(material_def, true);
// FIXME: before this is used in anything other than FRED2 we need to make this creation/deletion
// stuff global so that it's not so slow (it can be reused for multiple quadratic objects)
quad = gluNewQuadric();
if (quad == NULL) {
Int3();
return;
}
GL_state.SetTextureSource(TEXTURE_SOURCE_NONE);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
GL_state.SetZbufferType(ZBUFFER_TYPE_FULL);
opengl_shader_set_current();
GL_state.Color(gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue);
// FIXME: opengl_check_for_errors() needs to be modified to work with this at
// some point but for now I just don't care so it does nothing
gluQuadricCallback(quad, GLU_ERROR, NULL);
// FIXME: maybe support fill/wireframe with a future flag?
gluQuadricDrawStyle(quad, GLU_FILL);
// assuming unlit spheres, otherwise use GLU_SMOOTH so that it looks better
gluQuadricNormals(quad, GLU_NONE);
// we could set the slices/stacks at some point in the future but just use 16 now since it looks ok
gluSphere(quad, (GLdouble)rad, 16, 16);
// FIXME: I just heard this scream "Globalize Me!!". It was really scary. I even cried.
gluDeleteQuadric(quad);
opengl_draw_sphere();
}
void gr_opengl_deferred_light_sphere_init(int rings, int segments) // Generate a VBO of a sphere of radius 1.0f, based on code at http://www.ogre3d.org/tikiwiki/ManualSphereMeshes
@@ -2209,12 +2180,8 @@ void gr_opengl_deferred_light_sphere_init(int rings, int segments) // Generate a
}
void gr_opengl_draw_deferred_light_sphere(vec3d *position, float rad, bool clearStencil = true)
void opengl_draw_sphere()
{
g3_start_instance_matrix(position, &vmd_identity_matrix, true);
GL_state.Uniform.setUniform3f("scale", rad, rad, rad);
GL_state.Array.BindArrayBuffer(deferred_light_sphere_vbo);
GL_state.Array.BindElementBuffer(deferred_light_sphere_ibo);
@@ -2225,6 +2192,17 @@ void gr_opengl_draw_deferred_light_sphere(vec3d *position, float rad, bool clear
opengl_bind_vertex_layout(vertex_declare);
glDrawRangeElements(GL_TRIANGLES, 0, deferred_light_sphere_vcount, deferred_light_sphere_icount, GL_UNSIGNED_SHORT, 0);
}
void gr_opengl_draw_deferred_light_sphere(vec3d *position, float rad, bool clearStencil = true)
{
g3_start_instance_matrix(position, &vmd_identity_matrix, true);
GL_state.Uniform.setUniform3f("scale", rad, rad, rad);
GL_state.Uniform.setUniformMatrix4f("modelViewMatrix", GL_model_view_matrix);
GL_state.Uniform.setUniformMatrix4f("projMatrix", GL_projection_matrix);
opengl_draw_sphere();
g3_done_instance(true);
}
@@ -2342,6 +2320,8 @@ void gr_opengl_draw_deferred_light_cylinder(vec3d *position,matrix *orient, floa
g3_start_instance_matrix(position, orient, true);
GL_state.Uniform.setUniform3f("scale", rad, rad, length);
GL_state.Uniform.setUniformMatrix4f("modelViewMatrix", GL_model_view_matrix);
GL_state.Uniform.setUniformMatrix4f("projMatrix", GL_projection_matrix);
GL_state.Array.BindArrayBuffer(deferred_light_cylinder_vbo);
GL_state.Array.BindElementBuffer(deferred_light_cylinder_ibo);
@@ -2544,7 +2524,6 @@ void opengl_setup_scene_textures()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, Scene_texture_width, Scene_texture_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Scene_depth_texture, 0);
@@ -2789,61 +2768,22 @@ void gr_opengl_scene_texture_end()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_state.Color(255, 255, 255, 255);
if ( !is_minimum_GLSL_version() ) {
GL_state.Color(255, 255, 255, 255);
}
opengl_shader_set_passthrough(true, false);
GL_state.Array.BindArrayBuffer(0);
if (GL_rendering_to_texture)
{
GLfloat vertices[8] = {
0.0f, (float)gr_screen.max_h,
(float)gr_screen.max_w, (float)gr_screen.max_h,
(float)gr_screen.max_w, 0.0f,
0.0f, 0.0f
};
GLfloat uvcoords[8] = {
Scene_texture_u_scale, 0.0f,
0.0f, 0.0f,
0.0f, Scene_texture_v_scale,
Scene_texture_u_scale, Scene_texture_v_scale
};
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, vertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, 0, uvcoords);
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough();
glDrawArrays(GL_QUADS, 0, 4);
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, 0.0f, (float)gr_screen.max_w, (float)gr_screen.max_h, Scene_texture_u_scale, Scene_texture_v_scale);
}
else
{
GLfloat vertices[8] = {
0.0f, (float)gr_screen.max_h,
(float)gr_screen.max_w, (float)gr_screen.max_h,
(float)gr_screen.max_w, 0.0f,
0.0f, 0.0f
};
GLfloat uvcoords[8] = {
0.0f, 0.0f,
Scene_texture_u_scale, 0.0f,
Scene_texture_u_scale, Scene_texture_v_scale,
0.0f, Scene_texture_v_scale
};
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, vertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, 0, uvcoords);
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough();
glDrawArrays(GL_QUADS, 0, 4);
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w, (float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
}
GL_state.Texture.SetActiveUnit(0);
@@ -2873,7 +2813,7 @@ void gr_opengl_copy_effect_texture()
}
glDrawBuffer(GL_COLOR_ATTACHMENT4_EXT);
glBlitFramebufferEXT(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, gr_screen.max_w, gr_screen.max_h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, gr_screen.max_w, gr_screen.max_h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
@@ -2926,7 +2866,6 @@ void gr_opengl_deferred_lighting_end()
extern light Lights[MAX_LIGHTS];
extern int Num_lights;
extern float GL_light_color[];
extern float static_point_factor;
extern float static_light_factor;
extern float static_tube_factor;
@@ -2991,7 +2930,7 @@ void gr_opengl_deferred_lighting_finish()
GL_state.Uniform.setUniformi( "dualCone", l->dual_cone );
GL_state.Uniform.setUniformf( "coneAngle", l->cone_angle );
GL_state.Uniform.setUniformf( "coneInnerAngle", l->cone_inner_angle );
GL_state.Uniform.setUniform3f( "coneDir", l->vec2.xyz.x, l->vec2.xyz.y, l->vec2.xyz.z);
GL_state.Uniform.setUniform3f( "coneDir", l->vec2.xyz.x, l->vec2.xyz.y, l->vec2.xyz.z);
case LT_POINT:
GL_state.Uniform.setUniform3f( "diffuseLightColor", l->r * l->intensity * static_point_factor, l->g * l->intensity * static_point_factor, l->b * l->intensity * static_point_factor );
GL_state.Uniform.setUniform3f( "specLightColor", l->spec_r * l->intensity * static_point_factor, l->spec_g * l->intensity * static_point_factor, l->spec_b * l->intensity * static_point_factor );
@@ -3010,7 +2949,7 @@ void gr_opengl_deferred_lighting_finish()
GL_state.Uniform.setUniform3f( "specLightColor", l->spec_r * l->intensity * static_tube_factor, l->spec_g * l->intensity * static_tube_factor, l->spec_b * l->intensity * static_tube_factor );
GL_state.Uniform.setUniformf( "lightRadius", l->radb * 1.5f );
GL_state.Uniform.setUniformi( "lightType", 1 );
vec3d a, b;
matrix orient;
float length, dist;
@@ -3056,48 +2995,22 @@ void gr_opengl_deferred_lighting_finish()
GLboolean lighting = GL_state.Lighting(GL_FALSE);
GLboolean blend = GL_state.Blend(GL_FALSE);
GLboolean cull = GL_state.CullFace(GL_FALSE);
GLfloat vertices[8] = {
0.0f, (float)gr_screen.max_h,
(float)gr_screen.max_w, (float)gr_screen.max_h,
(float)gr_screen.max_w, 0.0f,
0.0f, 0.0f
};
GLfloat uvcoords[8] = {
0.0f, 0.0f,
Scene_texture_u_scale, 0.0f,
Scene_texture_u_scale, Scene_texture_v_scale,
0.0f, Scene_texture_v_scale
};
if ( High_dynamic_range ) {
High_dynamic_range = false;
opengl_shader_set_passthrough();
opengl_shader_set_passthrough(true, false);
High_dynamic_range = true;
} else {
opengl_shader_set_passthrough();
opengl_shader_set_passthrough(true, false);
}
GL_state.Array.BindArrayBuffer(0);
GL_state.Array.BindElementBuffer(0);
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, vertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, 0, uvcoords);
opengl_bind_vertex_layout(vert_def);
GL_state.Texture.DisableAll();
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Scene_luminance_texture);
GL_state.SetAlphaBlendMode( ALPHA_BLEND_ADDITIVE );
glDrawArrays(GL_QUADS, 0, 4);
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w, (float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
gr_set_view_matrix(&Eye_position, &Eye_matrix);
@@ -3125,7 +3038,7 @@ void gr_opengl_update_distortion()
GLboolean blend = GL_state.Blend(GL_FALSE);
GLboolean cull = GL_state.CullFace(GL_FALSE);
opengl_shader_set_current();
opengl_shader_set_passthrough(true, false);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Distortion_framebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Distortion_texture[!Distortion_switch], 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
@@ -3136,60 +3049,63 @@ void gr_opengl_update_distortion()
GL_state.Texture.Enable(Distortion_texture[Distortion_switch]);
glClearColor(0.5f, 0.5f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_state.Color(255, 255, 255, 255);
GLfloat texcoord[8] = {
0.0f, 0.0f,
0.96875f, 0.0f,
0.96875f, 1.0f,
0.0f, 1.0f
};
vertex vertices[4];
GLfloat vertices[8] = {
0.03f*(float)gr_screen.max_w,(float)gr_screen.max_h,
(float)gr_screen.max_w, (float)gr_screen.max_h,
(float)gr_screen.max_w, 0.0f,
0.03f*(float)gr_screen.max_w, 0.0f
};
vertices[0].texture_position.u = 0.0f;
vertices[0].texture_position.v = 0.0f;
GL_state.Array.BindArrayBuffer(0);
vertices[1].texture_position.u = 0.96875f;
vertices[1].texture_position.v = 0.0f;
vertices[2].texture_position.u = 0.0f;
vertices[2].texture_position.v = 1.0f;
vertices[3].texture_position.u = 0.96875f;
vertices[3].texture_position.v = 1.0f;
vertices[0].screen.xyw.x = 0.03f*(float)gr_screen.max_w;
vertices[0].screen.xyw.y = (float)gr_screen.max_h;
vertices[1].screen.xyw.x = (float)gr_screen.max_w;
vertices[1].screen.xyw.y = (float)gr_screen.max_h;
vertices[2].screen.xyw.x = 0.03f*(float)gr_screen.max_w;
vertices[2].screen.xyw.y = 0.0f;
vertices[3].screen.xyw.x = (float)gr_screen.max_w;
vertices[3].screen.xyw.y = 0.0f;
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, vertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, 0, texcoord);
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(vertex), offsetof(vertex, screen));
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(vertex), offsetof(vertex, texture_position));
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough();
glDrawArrays(GL_QUADS, 0, 4);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, vertices, sizeof(vertex) * 4);
GL_state.Texture.Disable();
SCP_vector<ubyte> colours;
SCP_vector<GLfloat> distortion_vertex;
colours.reserve(33 * 4);
distortion_vertex.reserve(33 * 2);
opengl_shader_set_passthrough(false, false);
vertex distortion_verts[33];
for(int i = 0; i < 33; i++)
{
colours.push_back((ubyte) rand()%256);
colours.push_back((ubyte) rand()%256);
colours.push_back(255);
colours.push_back(255);
distortion_verts[i].r = (ubyte)rand() % 256;
distortion_verts[i].g = (ubyte)rand() % 256;
distortion_verts[i].b = 255;
distortion_verts[i].a = 255;
distortion_vertex.push_back(0.04f);
distortion_vertex.push_back((float)gr_screen.max_h*0.03125f*i);
distortion_verts[i].screen.xyw.x = 0.04f;
distortion_verts[i].screen.xyw.y = (float)gr_screen.max_h*0.03125f*i;
}
vert_def = vertex_layout();
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, &distortion_vertex.front());
vert_def.add_vertex_component(vertex_format_data::COLOR4, 0, &colours.front());
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(vertex), offsetof(vertex, screen));
vert_def.add_vertex_component(vertex_format_data::COLOR4, sizeof(vertex), offsetof(vertex, r));
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough(false);
glDrawArrays(GL_POINTS, 0, 33);
opengl_render_primitives_immediate(PRIM_TYPE_POINTS, &vert_def, 33, distortion_verts, 33 * sizeof(vertex));
Distortion_switch = !Distortion_switch;
@@ -3205,7 +3121,103 @@ void gr_opengl_update_distortion()
GL_state.CullFace(cull);
}
void opengl_draw(vertex_layout vertex_binding, GLenum prim_type, int count, int vbuffer_handle)
void opengl_render_primitives(primitive_type prim_type, vertex_layout* layout, int n_verts, int buffer_handle, uint vert_offset, uint byte_offset)
{
if ( buffer_handle >= 0 ) {
opengl_bind_buffer_object(buffer_handle);
} else {
GL_state.Array.BindArrayBuffer(0);
}
opengl_bind_vertex_layout(*layout, 0, (ubyte*)byte_offset);
glDrawArrays(opengl_primitive_type(prim_type), vert_offset, n_verts);
}
void opengl_render_primitives_immediate(primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
uint offset = opengl_add_to_immediate_buffer(size, data);
opengl_render_primitives(prim_type, layout, n_verts, GL_immediate_buffer_handle, 0, offset);
}
void gr_opengl_render_primitives(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives()");
opengl_tnl_set_material(material_info, true);
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, offset, 0);
GL_CHECK_FOR_ERRORS("end of gr_opengl_render_primitives()");
}
void gr_opengl_render_primitives_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
opengl_tnl_set_material(material_info, true);
opengl_render_primitives_immediate(prim_type, layout, n_verts, data, size);
}
void gr_opengl_render_primitives_2d(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives_2d()");
//glPushMatrix();
//glTranslatef((float)gr_screen.offset_x, (float)gr_screen.offset_y, -0.99f);
gr_opengl_set_2d_matrix();
gr_opengl_render_primitives(material_info, prim_type, layout, offset, n_verts, buffer_handle);
gr_opengl_end_2d_matrix();
//glPopMatrix();
GL_CHECK_FOR_ERRORS("end of gr_opengl_render_primitives_2d()");
}
void gr_opengl_render_primitives_2d_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives_2d_immediate()");
//glPushMatrix();
//glTranslatef((float)gr_screen.offset_x, (float)gr_screen.offset_y, -0.99f);
gr_opengl_set_2d_matrix();
gr_opengl_render_primitives_immediate(material_info, prim_type, layout, n_verts, data, size);
gr_opengl_end_2d_matrix();
//glPopMatrix();
GL_CHECK_FOR_ERRORS("end of gr_opengl_render_primitives_2d_immediate()");
}
void gr_opengl_render_primitives_particle(particle_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives_particle()");
opengl_tnl_set_material_particle(material_info);
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, offset, 0);
GL_CHECK_FOR_ERRORS("end of gr_opengl_render_primitives_particle()");
}
void gr_opengl_render_primitives_distortion(distortion_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives_distortion()");
opengl_tnl_set_material_distortion(material_info);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, offset, 0);
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2, buffers);
GL_CHECK_FOR_ERRORS("start of gr_opengl_render_primitives_distortion()");
}
+33 -19
View File
@@ -15,9 +15,16 @@
#include "graphics/gropenglstate.h"
#include "graphics/gropenglshader.h"
#include "graphics/shadows.h"
#include <glad/glad.h>
struct opengl_vertex_bind {
vertex_format_data::vertex_format format;
GLint size;
GLenum data_type;
GLboolean normalized;
opengl_vert_attrib::attrib_id attribute_id;
};
void gr_opengl_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode, bool mirror);
void gr_opengl_aabitmap(int x, int y, int resize_mode, bool mirror);
void gr_opengl_string(float sx, float sy, const char *s, int resize_mode, int length);
@@ -43,8 +50,9 @@ void gr_opengl_update_distortion();
void opengl_set_spec_mapping(int tmap_type, float *u_scale, float *v_scale, int stage = 0);
void opengl_reset_spec_mapping();
void opengl_draw_sphere();
void gr_opengl_line_htl(const vec3d *start, const vec3d *end);
void gr_opengl_sphere_htl(float rad);
void gr_opengl_sphere(material *material_def, float rad);
void gr_opengl_deferred_light_sphere_init(int rings, int segments);
void gr_opengl_draw_deferred_light_sphere(const vec3d *position, float rad, bool clearStencil);
void gr_opengl_deferred_light_cylinder_init(int segments);
@@ -52,7 +60,7 @@ void gr_opengl_draw_deferred_light_cylinder(const vec3d *position, const matrix
void gr_opengl_draw_line_list(const colored_vector *lines, int num);
void gr_opengl_shadow_map_start(const matrix4 *shadow_view_matrix, const matrix *light_orient);
void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, const matrix *light_orient);
void gr_opengl_shadow_map_end();
void opengl_setup_scene_textures();
@@ -66,7 +74,17 @@ void gr_opengl_deferred_lighting_begin();
void gr_opengl_deferred_lighting_end();
void gr_opengl_deferred_lighting_finish();
void opengl_bind_vertex_layout(vertex_layout &layout);
void opengl_render_primitives(primitive_type prim_type, vertex_layout* layout, int n_verts, int buffer_handle, uint vert_offset, uint byte_offset);
void opengl_render_primitives_immediate(primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size);
void gr_opengl_render_primitives(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void gr_opengl_render_primitives_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size);
void gr_opengl_render_primitives_2d(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void gr_opengl_render_primitives_2d_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size);
void gr_opengl_render_primitives_particle(particle_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void gr_opengl_render_primitives_distortion(distortion_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle);
void opengl_bind_vertex_layout(vertex_layout &layout, uint base_vertex = 0, ubyte* base_ptr = NULL);
inline void opengl_draw_textured_quad_instanced(
GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
@@ -104,21 +122,17 @@ inline void opengl_draw_textured_quad(
{ x2, y2, u2, v2 }
};
GL_state.Array.BindArrayBuffer(0);
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
opengl_bind_vertex_layout(vert_def);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLfloat) * 4 * 4);
}
inline void opengl_draw_coloured_quad(
GLint x1, GLint y1,
GLint x2, GLint y2 )
GLint x1, GLint y1,
GLint x2, GLint y2)
{
GLint glVertices[8] = {
x1, y1,
@@ -129,12 +143,11 @@ inline void opengl_draw_coloured_quad(
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::SCREEN_POS, 0, glVertices);
vert_def.add_vertex_component(vertex_format_data::SCREEN_POS, 0, 0);
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough(false);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLint) * 8);
}
inline void opengl_draw_coloured_quad(
@@ -150,14 +163,15 @@ inline void opengl_draw_coloured_quad(
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, glVertices);
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, 0);
opengl_bind_vertex_layout(vert_def);
opengl_shader_set_passthrough(false);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLfloat) * 8);
}
inline GLenum opengl_primitive_type(primitive_type prim_type);
extern int Scene_texture_initialized;
extern GLuint Scene_color_texture;
+226 -43
View File
@@ -22,6 +22,7 @@
#include "graphics/2d.h"
#include "graphics/gropengllight.h"
#include "graphics/gropenglstate.h"
#include "graphics/gropengltnl.h"
#include "lighting/lighting.h"
#include "render/3d.h"
@@ -29,6 +30,8 @@
// Variables
opengl_light *opengl_lights = NULL;
opengl_light_uniform_data opengl_light_uniforms;
bool lighting_is_enabled = true;
int Num_active_gl_lights = 0;
int GL_center_alpha = 0;
@@ -44,12 +47,12 @@ extern float Cmdline_ogl_spec;
GLint GL_max_lights = 0;
// OGL defaults
static const float GL_light_color[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
static const float GL_light_spec[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
static const float GL_light_zero[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
static const float GL_light_emission[4] = { 0.09f, 0.09f, 0.09f, 1.0f };
static const float GL_light_true_zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
static float GL_light_ambient[4] = { 0.47f, 0.47f, 0.47f, 1.0f };
const float GL_light_color[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
const float GL_light_spec[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
const float GL_light_zero[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const float GL_light_emission[4] = { 0.09f, 0.09f, 0.09f, 1.0f };
const float GL_light_true_zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float GL_light_ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
void FSLight2GLLight(light *FSLight, opengl_light *GLLight)
{
@@ -156,30 +159,101 @@ void FSLight2GLLight(light *FSLight, opengl_light *GLLight)
}
}
void opengl_set_light(int light_num, opengl_light *ltp)
void opengl_set_light_fixed_pipeline(int light_num, opengl_light *ltp)
{
Assert(light_num < GL_max_lights);
GLfloat diffuse[4];
memcpy(diffuse, ltp->Diffuse, sizeof(GLfloat) * 4);
if ( !is_minimum_GLSL_version() && (ltp->type == LT_DIRECTIONAL) && (GL_light_factor < 1.0f) ) {
// if we're not using shaders, manually adjust the diffuse light factor.
if ( (ltp->type == LT_DIRECTIONAL) && (GL_light_factor < 1.0f) ) {
diffuse[0] *= GL_light_factor;
diffuse[1] *= GL_light_factor;
diffuse[2] *= GL_light_factor;
}
glLightfv(GL_LIGHT0+light_num, GL_POSITION, ltp->Position);
glLightfv(GL_LIGHT0+light_num, GL_AMBIENT, ltp->Ambient);
glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, ltp->Specular);
glLightfv(GL_LIGHT0+light_num, GL_SPOT_DIRECTION, ltp->SpotDir);
// transform lights into eyespace
vec3d light_pos_world;
vec3d light_pos_eye;
vec4 light_pos_eye_4d;
light_pos_world.xyz.x = ltp->Position[0];
light_pos_world.xyz.y = ltp->Position[1];
light_pos_world.xyz.z = ltp->Position[2];
if ( ltp->type == LT_POINT ) {
vm_vec_sub2(&light_pos_world, &Object_position);
}
vm_vec_rotate(&light_pos_eye, &light_pos_world, &Object_matrix);
light_pos_eye_4d.a1d[0] = light_pos_eye.a1d[0];
light_pos_eye_4d.a1d[1] = light_pos_eye.a1d[1];
light_pos_eye_4d.a1d[2] = light_pos_eye.a1d[2];
light_pos_eye_4d.a1d[3] = 1.0f;
vec3d light_dir_world;
vec3d light_dir_eye;
light_dir_world.xyz.x = ltp->SpotDir[0];
light_dir_world.xyz.y = ltp->SpotDir[1];
light_dir_world.xyz.z = ltp->SpotDir[2];
vm_vec_rotate(&light_dir_eye, &light_dir_world, &Object_matrix);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glLightfv(GL_LIGHT0 + light_num, GL_POSITION, light_pos_eye_4d.a1d);
glLightfv(GL_LIGHT0 + light_num, GL_AMBIENT, ltp->Ambient);
glLightfv(GL_LIGHT0 + light_num, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0 + light_num, GL_SPECULAR, ltp->Specular);
glLightfv(GL_LIGHT0 + light_num, GL_SPOT_DIRECTION, light_dir_eye.a1d);
//glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, ltp->ConstantAtten); Default is 1.0 and we only use 1.0 - Valathil
glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, ltp->LinearAtten);
glLightf(GL_LIGHT0 + light_num, GL_LINEAR_ATTENUATION, ltp->LinearAtten);
//glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, ltp->QuadraticAtten); Default is 0.0 and we only use 0.0 - Valathil
glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, ltp->SpotExp);
glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, ltp->SpotCutOff);
glLightf(GL_LIGHT0 + light_num, GL_SPOT_EXPONENT, ltp->SpotExp);
glLightf(GL_LIGHT0 + light_num, GL_SPOT_CUTOFF, ltp->SpotCutOff);
glPopMatrix();
}
void opengl_set_light(int light_num, opengl_light *ltp)
{
if ( !is_minimum_GLSL_version() ) {
opengl_set_light_fixed_pipeline(light_num, ltp);
return;
}
Assert(light_num < GL_max_lights);
vec4 light_pos_world;
light_pos_world.xyzw.x = ltp->Position[0];
light_pos_world.xyzw.y = ltp->Position[1];
light_pos_world.xyzw.z = ltp->Position[2];
light_pos_world.xyzw.w = ltp->Position[3];
vec3d light_dir_world;
light_dir_world.xyz.x = ltp->SpotDir[0];
light_dir_world.xyz.y = ltp->SpotDir[1];
light_dir_world.xyz.z = ltp->SpotDir[2];
vm_vec_transform(&opengl_light_uniforms.Position[light_num], &light_pos_world, &GL_view_matrix);
vm_vec_transform(&opengl_light_uniforms.Direction[light_num], &light_dir_world, &GL_view_matrix, false);
opengl_light_uniforms.Diffuse_color[light_num].xyz.x = ltp->Diffuse[0];
opengl_light_uniforms.Diffuse_color[light_num].xyz.y = ltp->Diffuse[1];
opengl_light_uniforms.Diffuse_color[light_num].xyz.z = ltp->Diffuse[2];
opengl_light_uniforms.Spec_color[light_num].xyz.x = ltp->Specular[0];
opengl_light_uniforms.Spec_color[light_num].xyz.y = ltp->Specular[1];
opengl_light_uniforms.Spec_color[light_num].xyz.z = ltp->Specular[2];
opengl_light_uniforms.Light_type[light_num] = ltp->type;
opengl_light_uniforms.Attenuation[light_num] = ltp->LinearAtten;
}
bool opengl_sort_active_lights(const opengl_light &la, const opengl_light &lb)
@@ -459,7 +533,10 @@ void gr_opengl_reset_lighting()
// memset( opengl_lights, 0, sizeof(opengl_light) * MAX_LIGHTS );
for (i = 0; i < GL_max_lights; i++) {
GL_state.Light(i, GL_FALSE);
if ( is_minimum_GLSL_version() ) {
GL_state.Light(i, GL_FALSE);
}
opengl_lights[i].occupied = false;
}
@@ -469,18 +546,12 @@ void gr_opengl_reset_lighting()
void opengl_calculate_ambient_factor()
{
float amb_user = 0.0f;
// assuming that the default is "128", just skip this if not a user setting
if (Cmdline_ambient_factor == 128)
return;
amb_user = (float)((Cmdline_ambient_factor * 2) - 255) / 255.0f;
float amb_user = i2fl(Cmdline_ambient_factor) / 128.0f;
// set the ambient light
GL_light_ambient[0] += amb_user;
GL_light_ambient[1] += amb_user;
GL_light_ambient[2] += amb_user;
GL_light_ambient[0] *= amb_user;
GL_light_ambient[1] *= amb_user;
GL_light_ambient[2] *= amb_user;
CLAMP( GL_light_ambient[0], 0.02f, 1.0f );
CLAMP( GL_light_ambient[1], 0.02f, 1.0f );
@@ -495,24 +566,58 @@ void opengl_light_shutdown()
vm_free(opengl_lights);
opengl_lights = NULL;
}
if ( opengl_light_uniforms.Position != NULL ) {
vm_free(opengl_light_uniforms.Position);
opengl_light_uniforms.Position = NULL;
}
if ( opengl_light_uniforms.Diffuse_color != NULL ) {
vm_free(opengl_light_uniforms.Diffuse_color);
opengl_light_uniforms.Diffuse_color = NULL;
}
if ( opengl_light_uniforms.Spec_color != NULL ) {
vm_free(opengl_light_uniforms.Spec_color);
opengl_light_uniforms.Spec_color = NULL;
}
if ( opengl_light_uniforms.Direction != NULL ) {
vm_free(opengl_light_uniforms.Direction);
opengl_light_uniforms.Direction = NULL;
}
if ( opengl_light_uniforms.Light_type != NULL ) {
vm_free(opengl_light_uniforms.Light_type);
opengl_light_uniforms.Light_type = NULL;
}
if ( opengl_light_uniforms.Attenuation != NULL ) {
vm_free(opengl_light_uniforms.Attenuation);
opengl_light_uniforms.Attenuation = NULL;
}
}
void opengl_light_init()
{
opengl_calculate_ambient_factor();
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
if ( !is_minimum_GLSL_version() ) {
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
glMaterialf(GL_FRONT, GL_SHININESS, Cmdline_ogl_spec /*80.0f*/ );
glMaterialf(GL_FRONT, GL_SHININESS, Cmdline_ogl_spec /*80.0f*/);
// more realistic lighting model
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
// more realistic lighting model
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glGetIntegerv(GL_MAX_LIGHTS, &GL_max_lights); // Get the max number of lights supported
glGetIntegerv(GL_MAX_LIGHTS, &GL_max_lights); // Get the max number of lights supported
Verify(GL_max_lights > 0);
} else {
GL_max_lights = 8;
}
// allocate memory for enabled lights
Verify(GL_max_lights > 0);
if ( opengl_lights == NULL )
opengl_lights = (opengl_light *) vm_malloc(MAX_LIGHTS * sizeof(opengl_light), memory::quiet_alloc);
@@ -520,9 +625,15 @@ void opengl_light_init()
Error( LOCATION, "Unable to allocate memory for lights!\n");
memset( opengl_lights, 0, MAX_LIGHTS * sizeof(opengl_light) );
opengl_light_uniforms.Position = (vec4 *)vm_malloc(GL_max_lights * sizeof(vec4));
opengl_light_uniforms.Diffuse_color = (vec3d *)vm_malloc(GL_max_lights * sizeof(vec3d));
opengl_light_uniforms.Spec_color = (vec3d *)vm_malloc(GL_max_lights * sizeof(vec3d));
opengl_light_uniforms.Direction = (vec3d *)vm_malloc(GL_max_lights * sizeof(vec3d));
opengl_light_uniforms.Light_type = (int *)vm_malloc(GL_max_lights * sizeof(int));
opengl_light_uniforms.Attenuation = (float *)vm_malloc(GL_max_lights * sizeof(float));
}
extern int Cmdline_no_emissive;
bool ambient_state = false;
bool emission_state = false;
bool specular_state = false;
@@ -533,8 +644,7 @@ void opengl_default_light_settings(int ambient, int emission, int specular)
if (ambient) {
if (!ambient_state) {
glMaterialfv( GL_FRONT, GL_DIFFUSE, GL_light_color );
glMaterialfv( GL_FRONT, GL_AMBIENT, GL_light_ambient );
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, GL_light_color);
ambient_state = true;
}
} else {
@@ -574,7 +684,7 @@ void opengl_default_light_settings(int ambient, int emission, int specular)
}
}
void gr_opengl_set_lighting(bool set, bool state)
void opengl_set_lighting_fixed_pipeline(bool set, bool state)
{
lighting_is_enabled = set;
@@ -582,16 +692,89 @@ void gr_opengl_set_lighting(bool set, bool state)
if ( (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) && !set ) {
float amb[4] = { gr_screen.current_alpha, gr_screen.current_alpha, gr_screen.current_alpha, gr_screen.current_alpha };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, amb );
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
} else {
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, GL_light_ambient );
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, GL_light_ambient);
}
for (int i = 0; i < GL_max_lights; i++) {
GL_state.Lighting((state) ? GL_TRUE : GL_FALSE);
if ( !state ) {
for ( int i = 0; i < GL_max_lights; i++ ) {
GL_state.Light(i, GL_FALSE);
}
return;
}
//Valathil: Sort lights by priority
extern bool Deferred_lighting;
if ( !Deferred_lighting )
opengl_pre_render_init_lights();
int i = 0;
for ( i = 0; i < GL_max_lights; i++ ) {
if ( i >= Num_active_gl_lights ) {
break;
}
if ( opengl_lights[i].occupied ) {
opengl_set_light(i, &opengl_lights[i]);
GL_state.Light(i, GL_TRUE);
}
}
opengl_light zero;
memset(&zero, 0, sizeof(opengl_light));
zero.Position[0] = 1.0f;
// make sure that we turn off any lights that we aren't using right now
for ( ; i < GL_max_lights; i++ ) {
GL_state.Light(i, GL_FALSE);
opengl_set_light(i, &zero);
}
}
void gr_opengl_set_lighting(bool set, bool state)
{
if ( !is_minimum_GLSL_version() ) {
opengl_set_lighting_fixed_pipeline(set, state);
return;
}
GL_state.Lighting( (state) ? GL_TRUE : GL_FALSE );
lighting_is_enabled = set;
if ( !state ) {
return;
}
//Valathil: Sort lights by priority
extern bool Deferred_lighting;
if ( !Deferred_lighting )
opengl_pre_render_init_lights();
int i = 0;
for ( i = 0; i < GL_max_lights; i++ ) {
if ( i >= Num_active_gl_lights ) {
break;
}
if ( opengl_lights[i].occupied ) {
opengl_set_light(i, &opengl_lights[i]);
}
}
opengl_light zero;
memset(&zero, 0, sizeof(opengl_light));
zero.Position[0] = 1.0f;
// make sure that we turn off any lights that we aren't using right now
for ( ; i < GL_max_lights; i++ ) {
opengl_set_light(i, &zero);
}
}
void gr_opengl_set_ambient_light(int red, int green, int blue)
+18 -6
View File
@@ -14,13 +14,9 @@
#define _GROPENGLLIGHT_H
#include "graphics/gropengl.h"
#include "lighting/lighting.h"
#include <glad/glad.h>
struct ogl_light_color {
float r,g,b,a;
};
// Structures
struct opengl_light
{
@@ -39,7 +35,16 @@ struct opengl_light
int type;
};
struct light_data;
struct opengl_light_uniform_data {
vec4 *Position;
vec3d *Diffuse_color;
vec3d *Spec_color;
vec3d *Direction;
int *Light_type;
float *Attenuation;
};
extern opengl_light_uniform_data opengl_light_uniforms;
//Variables
extern bool lighting_is_enabled;
@@ -48,6 +53,13 @@ extern int Num_active_gl_lights;
extern int GL_center_alpha;
extern float GL_light_factor;
extern const float GL_light_color[4];
extern const float GL_light_spec[4];
extern const float GL_light_zero[4];
extern const float GL_light_emission[4];
extern const float GL_light_true_zero[4];
extern float GL_light_ambient[4];
//Functions
int gr_opengl_make_light(light *fs_light, int idx, int priority); //unused -- stub function
void gr_opengl_modify_light(light *fs_light, int idx, int priority); //unused -- stub function
+1 -4
View File
@@ -337,7 +337,6 @@ void opengl_post_lightshafts()
GL_state.Texture.SetActiveUnit(1);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Cockpit_depth_texture);
GL_state.Color(255, 255, 255, 255);
GL_state.Blend(GL_TRUE);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE);
@@ -389,8 +388,6 @@ void gr_opengl_post_process_end()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_state.Color(255, 255, 255, 255);
// set and configure post shader ...
int flags = 0;
for ( int i = 0; i < (int)Post_effects.size(); i++) {
@@ -1030,7 +1027,7 @@ void opengl_post_process_init()
Cmdline_postprocess = 0;
return;
}
if ( !opengl_post_init_shaders() ) {
mprintf((" Unable to initialize post-processing shaders! Disabling post-processing...\n\n"));
Cmdline_postprocess = 0;
+189 -74
View File
@@ -35,56 +35,83 @@ static float GL_anim_timer = 0.0f;
geometry_sdr_params *Current_geo_sdr_params = NULL;
opengl_vert_attrib GL_vertex_attrib_info[] =
{
{ opengl_vert_attrib::POSITION, "vertPosition", { 0.0f, 0.0f, 0.0f, 1.0f } },
{ opengl_vert_attrib::COLOR, "vertColor", { 1.0f, 1.0f, 1.0f, 1.0f } },
{ opengl_vert_attrib::TEXCOORD, "vertTexCoord", { 1.0f, 1.0f, 1.0f, 1.0f } },
{ opengl_vert_attrib::NORMAL, "vertNormal", { 0.0f, 0.0f, 1.0f, 0.0f } },
{ opengl_vert_attrib::TANGENT, "vertTangent", { 1.0f, 0.0f, 0.0f, 0.0f } },
{ opengl_vert_attrib::MODEL_ID, "vertModelID", { 0.0f, 0.0f, 0.0f, 0.0f } },
{ opengl_vert_attrib::RADIUS, "vertRadius", { 1.0f, 0.0f, 0.0f, 0.0f } },
{ opengl_vert_attrib::UVEC, "vertUvec", { 0.0f, 1.0f, 0.0f, 0.0f } }
};
/**
* Static lookup reference for shader uniforms
* When adding a new shader, list all associated uniforms and attributes here
*/
static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_MODEL, "main-v.sdr", "main-f.sdr", "main-g.sdr", {GL_TRIANGLES, GL_TRIANGLE_STRIP, 3},
0, {}, 0, {}, "Model Rendering" },
6, { "modelViewMatrix", "modelMatrix", "viewMatrix", "projMatrix", "textureMatrix", "color" },
5, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::NORMAL, opengl_vert_attrib::TANGENT, opengl_vert_attrib::MODEL_ID }, "Model Rendering" },
{ SDR_TYPE_EFFECT_PARTICLE, "effect-v.sdr", "effect-particle-f.sdr", "effect-screen-g.sdr", {GL_POINTS, GL_TRIANGLE_STRIP, 4},
9, { "baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ", "linear_depth", "srgb", "blend_alpha" }, 1, {"radius"}, "Particle Effects" },
11, { "modelViewMatrix", "projMatrix", "baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ", "linear_depth", "srgb", "blend_alpha" },
4, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::RADIUS, opengl_vert_attrib::COLOR }, "Particle Effects" },
{ SDR_TYPE_EFFECT_DISTORTION, "effect-distort-v.sdr", "effect-distort-f.sdr", 0, { 0, 0, 0 },
6, { "baseMap", "window_width", "window_height", "distMap", "frameBuffer", "use_offset" }, 1, { "radius" }, "Distortion Effects" },
8, { "modelViewMatrix", "projMatrix", "baseMap", "window_width", "window_height", "distMap", "frameBuffer", "use_offset" },
3, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::RADIUS, opengl_vert_attrib::COLOR }, "Distortion Effects" },
{ SDR_TYPE_POST_PROCESS_MAIN, "post-v.sdr", "post-f.sdr", 0, {0, 0, 0},
6, { "tex", "depth_tex", "timer", "bloomed", "bloom_intensity", "levels" }, 0, { NULL }, "Post Processing" },
6, { "tex", "depth_tex", "timer", "bloomed", "bloom_intensity", "levels" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Post Processing" },
{ SDR_TYPE_POST_PROCESS_BLUR, "post-v.sdr", "blur-f.sdr", 0, {0, 0, 0},
4, { "tex", "texSize", "level", "tapSize", "debug" }, 0, { NULL }, "Gaussian Blur" },
5, { "tex", "texSize", "level", "tapSize", "debug" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Gaussian Blur" },
{ SDR_TYPE_POST_PROCESS_BLOOM_COMP, "post-v.sdr", "bloom-comp-f.sdr", 0, {0, 0, 0},
3, { "bloomed", "bloom_intensity", "levels" }, 0, { NULL }, "Bloom Compositing" },
3, { "bloomed", "bloom_intensity", "levels" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Bloom Compositing" },
{ SDR_TYPE_POST_PROCESS_BRIGHTPASS, "post-v.sdr", "brightpass-f.sdr", 0, { 0, 0, 0 },
1, { "tex" }, 0, { NULL }, "Bloom Brightpass" },
1, { "tex" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Bloom Brightpass" },
{ SDR_TYPE_POST_PROCESS_FXAA, "fxaa-v.sdr", "fxaa-f.sdr", 0, {0, 0, 0},
3, { "tex0", "rt_w", "rt_h" }, 0, { NULL }, "FXAA" },
3, { "tex0", "rt_w", "rt_h" },
1, { opengl_vert_attrib::POSITION }, "FXAA" },
{ SDR_TYPE_POST_PROCESS_FXAA_PREPASS, "post-v.sdr", "fxaapre-f.sdr", 0, {0, 0, 0},
1, { "tex" }, 0, { NULL }, "FXAA Prepass" },
1, { "tex" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "FXAA Prepass" },
{ SDR_TYPE_POST_PROCESS_LIGHTSHAFTS, "post-v.sdr", "ls-f.sdr", 0, {0, 0, 0},
8, { "scene", "cockpit", "sun_pos", "weight", "intensity", "falloff", "density", "cp_intensity" }, 0, { NULL }, "Lightshafts" },
8, { "scene", "cockpit", "sun_pos", "weight", "intensity", "falloff", "density", "cp_intensity" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Lightshafts" },
{ SDR_TYPE_POST_PROCESS_TONEMAPPING, "post-v.sdr", "tonemapping-f.sdr", 0, {0, 0, 0},
2, { "tex", "exposure" }, 0, { NULL }, "Tonemapping" },
2, { "tex", "exposure" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Tonemapping" },
{ SDR_TYPE_DEFERRED_LIGHTING, "deferred-v.sdr", "deferred-f.sdr", 0, { 0, 0, 0 },
16, { "scale", "ColorBuffer", "NormalBuffer", "PositionBuffer", "SpecBuffer", "invScreenWidth", "invScreenHeight", "lightType", "lightRadius", "diffuseLightColor",
"specLightColor", "dualCone", "coneDir", "coneAngle", "coneInnerAngle", "specFactor" }, 0, { NULL }, "Deferred Lighting" },
18, { "modelViewMatrix", "projMatrix", "scale", "ColorBuffer", "NormalBuffer", "PositionBuffer", "SpecBuffer", "invScreenWidth", "invScreenHeight", "lightType", "lightRadius",
"diffuseLightColor", "specLightColor", "dualCone", "coneDir", "coneAngle", "coneInnerAngle", "specFactor" },
1, { opengl_vert_attrib::POSITION }, "Deferred Lighting" },
{ SDR_TYPE_DEFERRED_CLEAR, "deferred-clear-v.sdr", "deferred-clear-f.sdr", 0, {0, 0, 0},
0, { NULL }, 0, { NULL }, "Clear Deferred Lighting Buffer" },
0, { NULL },
1, { opengl_vert_attrib::POSITION }, "Clear Deferred Lighting Buffer" },
{ SDR_TYPE_VIDEO_PROCESS, "video-v.sdr", "video-f.sdr", 0, {0, 0, 0},
3, { "ytex", "utex", "vtex" }, 0, { NULL }, "Video Playback" },
5, { "modelViewMatrix", "projMatrix", "ytex", "utex", "vtex" },
2, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Video Playback" },
{ SDR_TYPE_PASSTHROUGH_RENDER, "passthrough-v.sdr", "passthrough-f.sdr", 0, { 0, 0, 0 },
5, { "baseMap", "noTexturing", "alphaTexture", "srgb", "intensity" }, 0, { NULL }, "Passthrough" }
{ SDR_TYPE_PASSTHROUGH_RENDER, "passthrough-v.sdr", "passthrough-f.sdr", 0,{ 0, 0, 0 },
9, { "modelViewMatrix", "projMatrix", "baseMap", "noTexturing", "alphaTexture", "srgb", "intensity", "color", "alphaThreshold" },
3, { opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::COLOR }, "Passthrough" }
};
/**
@@ -93,89 +120,99 @@ static opengl_shader_type_t GL_shader_types[] = {
*/
static opengl_shader_variant_t GL_shader_variants[] = {
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_LIGHT, "FLAG_LIGHT",
3, { "n_lights", "light_factor", "defaultGloss" }, 0, { NULL },
11, { "n_lights", "lightPosition", "lightDirection", "lightDiffuseColor", "lightSpecColor", "lightType", "lightAttenuation", "ambientFactor", "diffuseFactor", "emissionFactor", "defaultGloss" }, 0, { },
"Lighting" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_FOG, "FLAG_FOG",
0, { NULL }, 0, { NULL },
3, { "fogStart", "fogScale", "fogColor" }, 0, { },
"Fog Effect" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DIFFUSE_MAP, "FLAG_DIFFUSE_MAP",
6, { "sBasemap", "desaturate", "desaturate_clr", "blend_alpha", "overrideDiffuse", "diffuseClr" }, 0, { NULL },
6, { "sBasemap", "desaturate", "desaturate_clr", "blend_alpha", "overrideDiffuse", "diffuseClr" }, 0, { },
"Diffuse Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_GLOW_MAP, "FLAG_GLOW_MAP",
3, { "sGlowmap", "overrideGlow", "glowClr" }, 0, { NULL },
3, { "sGlowmap", "overrideGlow", "glowClr" }, 0, { },
"Glow Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SPEC_MAP, "FLAG_SPEC_MAP",
5, { "sSpecmap", "overrideSpec", "specClr", "gammaSpec", "alphaGloss" }, 0, { NULL },
5, { "sSpecmap", "overrideSpec", "specClr", "gammaSpec", "alphaGloss" }, 0, { },
"Specular Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_MAP, "FLAG_NORMAL_MAP",
1, { "sNormalmap" }, 0, { NULL },
1, { "sNormalmap" }, 0, { },
"Normal Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HEIGHT_MAP, "FLAG_HEIGHT_MAP",
1, { "sHeightmap" }, 0, { NULL },
1, { "sHeightmap" }, 0, { },
"Parallax Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ENV_MAP, "FLAG_ENV_MAP",
3, { "sEnvmap", "envGloss", "envMatrix" }, 0, { NULL },
3, { "sEnvmap", "envGloss", "envMatrix" }, 0, { },
"Environment Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ANIMATED, "FLAG_ANIMATED",
5, { "sFramebuffer", "effect_num", "anim_timer", "vpwidth", "vpheight" }, 0, { NULL },
5, { "sFramebuffer", "effect_num", "anim_timer", "vpwidth", "vpheight" }, 0, { },
"Animated Effects" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_MISC_MAP, "FLAG_MISC_MAP",
1, { "sMiscmap" }, 0, { NULL },
1, { "sMiscmap" }, 0, { },
"Utility mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TEAMCOLOR, "FLAG_TEAMCOLOR",
3, { "stripe_color", "base_color", "team_glow_enabled" }, 0, { NULL },
3, { "stripe_color", "base_color", "team_glow_enabled" }, 0, { },
"Team Colors" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DEFERRED, "FLAG_DEFERRED",
0, { NULL }, 0, { NULL },
0, { NULL }, 0, { },
"Deferred lighting" },
{ SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_SHADOW_MAP, "FLAG_SHADOW_MAP",
1, { "shadow_proj_matrix" }, 0, { NULL },
1, { "shadow_proj_matrix" }, 0, { },
"Shadow Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SHADOWS, "FLAG_SHADOWS",
8, { "shadow_map", "shadow_mv_matrix", "shadow_proj_matrix", "model_matrix", "veryneardist", "neardist", "middist", "fardist" }, 0, { NULL },
7, { "shadow_map", "shadow_mv_matrix", "shadow_proj_matrix", "veryneardist", "neardist", "middist", "fardist" }, 0, { },
"Shadows" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_THRUSTER, "FLAG_THRUSTER",
1, { "thruster_scale" }, 0, { NULL },
1, { "thruster_scale" }, 0, { },
"Thruster scaling" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TRANSFORM, "FLAG_TRANSFORM",
2, { "transform_tex", "buffer_matrix_offset" }, 1, { "model_id" },
2, { "transform_tex", "buffer_matrix_offset" }, 0, { },
"Submodel Transforms" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_CLIP, "FLAG_CLIP",
4, { "use_clip_plane", "world_matrix", "clip_normal", "clip_position" }, 0, { NULL },
3, { "use_clip_plane", "clip_normal", "clip_position" }, 0, { },
"Clip Plane" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HDR, "FLAG_HDR",
0, { NULL }, 0, { NULL}, "High Dynamic Range" },
0, { NULL }, 0, { },
"High Dynamic Range" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_AMBIENT_MAP, "FLAG_AMBIENT_MAP",
1, { "sAmbientmap" }, 0, { NULL }, "Ambient Occlusion Map" },
1, { "sAmbientmap" }, 0, { },
"Ambient Occlusion Map" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_ALPHA, "FLAG_NORMAL_ALPHA",
1, { "normalAlphaMinMax" }, 0, { },
"Normal Alpha" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_EXTRUDE, "FLAG_NORMAL_EXTRUDE",
1, { "extrudeWidth" }, 0, { },
"Normal Extrusion" },
{ SDR_TYPE_EFFECT_PARTICLE, true, SDR_FLAG_PARTICLE_POINT_GEN, "FLAG_EFFECT_GEOMETRY",
0, { NULL }, 1, { "uvec" },
0, { NULL }, 1, { opengl_vert_attrib::UVEC },
"Geometry shader point-based particles" },
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_HORIZONTAL, "PASS_0",
0, { NULL }, 0, { NULL },
0, { NULL }, 0, { },
"Horizontal blur pass" },
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_VERTICAL, "PASS_1",
0, { NULL }, 0, { NULL },
0, { NULL }, 0, { },
"Vertical blur pass" }
};
@@ -195,6 +232,8 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
{
if (shader_obj != NULL) {
if(!Current_shader || (Current_shader->program_id != shader_obj->program_id)) {
GL_state.Array.ResetVertexAttribs();
GL_state.Uniform.reset();
Current_shader = shader_obj;
glUseProgram(Current_shader->program_id);
GL_state.Uniform.reset();
@@ -206,7 +245,7 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
glGetProgramiv(Current_shader->program_id, GL_VALIDATE_STATUS, &obj_status);
if ( !obj_status ) {
opengl_shader_check_info_log(Current_shader->program_id);
opengl_program_check_info_log(Current_shader->program_id);
mprintf(("VALIDATE INFO-LOG:\n"));
@@ -220,6 +259,8 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
#endif
}
} else {
GL_state.Array.ResetVertexAttribs();
GL_state.Uniform.reset();
Current_shader = NULL;
glUseProgram(0);
}
@@ -307,7 +348,7 @@ void opengl_shader_shutdown()
}
}
static SCP_string get_shader_header(shader_type type_id, int flags) {
static SCP_string opengl_shader_get_header(shader_type type_id, int flags, shader_stage stage) {
SCP_stringstream sflags;
#ifdef __APPLE__
@@ -316,6 +357,50 @@ static SCP_string get_shader_header(shader_type type_id, int flags) {
sflags << "#define APPLE\n";
#endif
// apply different macros for differing GLSL versions
if ( GL_version >= 32 && GLSL_version >= 150 ) {
sflags << "#version " << GLSL_version << "\n";
if ( stage == SDR_STAGE_VERTEX ) {
sflags << "#define vertIn in\n";
sflags << "#define vertOut out\n";
sflags << "#define tex2D texture\n";
sflags << "#define tex2DLod textureLod\n";
sflags << "#define texCube texture\n";
sflags << "#define tex2DArray texture\n";
} else if ( stage == SDR_STAGE_FRAGMENT ) {
sflags << "#define fragIn in\n";
sflags << "#define tex2D texture\n";
sflags << "#define tex2DLod textureLod\n";
sflags << "#define texCube texture\n";
sflags << "#define tex2DArray texture\n";
sflags << "out vec4 fragOut0;\n";
sflags << "out vec4 fragOut1;\n";
sflags << "out vec4 fragOut2;\n";
sflags << "out vec4 fragOut3;\n";
sflags << "out vec4 fragOut4;\n";
}
} else {
if ( stage == SDR_STAGE_VERTEX ) {
sflags << "#define vertIn attribute\n";
sflags << "#define vertOut varying\n";
sflags << "#define tex2D texture2D\n";
sflags << "#define tex2DLod texture2DLod\n";
sflags << "#define texCube textureCube\n";
sflags << "#define tex2DArray texture2DArray\n";
} else {
sflags << "#define fragIn varying\n";
sflags << "#define tex2D texture2D\n";
sflags << "#define tex2DLod texture2DLod\n";
sflags << "#define texCube textureCube\n";
sflags << "#define tex2DArray texture2DArray\n";
sflags << "#define fragOut0 gl_FragData[0]\n";
sflags << "#define fragOut1 gl_FragData[1]\n";
sflags << "#define fragOut2 gl_FragData[2]\n";
sflags << "#define fragOut3 gl_FragData[3]\n";
sflags << "#define fragOut4 gl_FragData[4]\n";
}
}
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS || type_id == SDR_TYPE_POST_PROCESS_FXAA) {
// ignore looking for variants. main post process, lightshafts, and FXAA shaders need special headers to be hacked in
opengl_post_shader_header(sflags, type_id, flags);
@@ -368,9 +453,9 @@ static SCP_string opengl_load_shader(const char *filename)
return content;
}
static SCP_vector<SCP_string> opengl_get_shader_content(shader_type type_id, const char* filename, int flags) {
static SCP_vector<SCP_string> opengl_get_shader_content(shader_type type_id, const char* filename, int flags, shader_stage stage) {
SCP_vector<SCP_string> parts;
parts.push_back(get_shader_header(type_id, flags));
parts.push_back(opengl_shader_get_header(type_id, flags, stage));
parts.push_back(opengl_load_shader(filename));
@@ -394,6 +479,7 @@ int opengl_compile_shader(shader_type sdr, uint flags)
opengl_shader_type_t *sdr_info = &GL_shader_types[sdr];
Assert(sdr_info->type_id == sdr);
mprintf(("Compiling new shader:\n"));
mprintf((" %s\n", sdr_info->description));
@@ -412,8 +498,8 @@ int opengl_compile_shader(shader_type sdr, uint flags)
}
}
auto vertex_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->vert, flags);
auto fragment_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->frag, flags);
auto vertex_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->vert, flags, SDR_STAGE_VERTEX);
auto fragment_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->frag, flags, SDR_STAGE_FRAGMENT);
SCP_vector<SCP_string> geom_content;
if ( use_geo_sdr ) {
@@ -422,7 +508,7 @@ int opengl_compile_shader(shader_type sdr, uint flags)
}
// read geometry shader
geom_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->geo, flags);
geom_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->geo, flags, SDR_STAGE_GEOMETRY);
Current_geo_sdr_params = &sdr_info->geo_sdr_info;
}
@@ -438,13 +524,22 @@ int opengl_compile_shader(shader_type sdr, uint flags)
opengl_shader_set_current(&new_shader);
// bind fragment data locations
if ( GL_version >= 32 && GLSL_version >= 150 ) {
glBindFragDataLocation(new_shader.program_id, 0, "fragOut0");
glBindFragDataLocation(new_shader.program_id, 1, "fragOut1");
glBindFragDataLocation(new_shader.program_id, 2, "fragOut2");
glBindFragDataLocation(new_shader.program_id, 3, "fragOut3");
glBindFragDataLocation(new_shader.program_id, 4, "fragOut4");
}
// initialize uniforms and attributes
for ( int i = 0; i < sdr_info->num_uniforms; ++i ) {
opengl_shader_init_uniform( sdr_info->uniforms[i] );
}
for (int i = 0; i < sdr_info->num_attributes; ++i) {
opengl_shader_init_attribute(sdr_info->attributes[i]);
opengl_shader_init_attribute(&GL_vertex_attrib_info[sdr_info->attributes[i]]);
}
// if this shader is POST_PROCESS_MAIN, hack in the user-defined flags
@@ -464,7 +559,7 @@ int opengl_compile_shader(shader_type sdr, uint flags)
}
for (int j = 0; j < variant.num_attributes; ++j) {
opengl_shader_init_attribute(variant.attributes[j]);
opengl_shader_init_attribute(&GL_vertex_attrib_info[variant.attributes[j]]);
}
mprintf((" %s\n", variant.description));
@@ -535,6 +630,8 @@ void opengl_shader_init()
opengl_shader_compile_passthrough_shader();
mprintf(("\n"));
opengl_shader_compile_passthrough_shader();
}
/**
@@ -648,13 +745,13 @@ GLuint opengl_shader_link_object(GLuint vertex_object, GLuint fragment_object, G
if (geometry_object) {
glAttachShader(shader_object, geometry_object);
if ( Current_geo_sdr_params != NULL) {
glProgramParameteriARB((GLuint)shader_object, GL_GEOMETRY_INPUT_TYPE_ARB, Current_geo_sdr_params->input_type);
glProgramParameteriARB((GLuint)shader_object, GL_GEOMETRY_OUTPUT_TYPE_ARB, Current_geo_sdr_params->output_type);
glProgramParameteriARB((GLuint)shader_object, GL_GEOMETRY_VERTICES_OUT_ARB, Current_geo_sdr_params->vertices_out);
}
}
for ( int i = 0; i < opengl_vert_attrib::NUM_ATTRIBS; ++i ) {
// assign vert attribute binding locations before we link the shader
glBindAttribLocation(shader_object, i, GL_vertex_attrib_info[i].name.c_str());
}
glLinkProgram(shader_object);
// check if the link was successful
@@ -750,24 +847,33 @@ Done:
*
* @param attribute_text Name of the attribute to be initialized
*/
void opengl_shader_init_attribute(const char *attribute_text)
void opengl_shader_init_attribute(const opengl_vert_attrib *attrib_info)
{
opengl_shader_uniform_t new_attribute;
if ( ( Current_shader == NULL ) || ( attribute_text == NULL ) ) {
if ( (Current_shader == NULL) || attrib_info->name.empty() ) {
Int3();
return;
}
new_attribute.text_id = attribute_text;
new_attribute.location = glGetAttribLocation(Current_shader->program_id, attribute_text);
new_attribute.text_id = attrib_info->name;
new_attribute.location = glGetAttribLocation(Current_shader->program_id, attrib_info->name.c_str());
if ( new_attribute.location < 0 ) {
nprintf(("SHADER-DEBUG", "WARNING: Unable to get shader attribute location for \"%s\"!\n", attribute_text));
nprintf(("SHADER-DEBUG", "WARNING: Unable to get shader attribute location for \"%s\"!\n", attrib_info->name.c_str()));
return;
}
Current_shader->attributes.push_back( new_attribute );
// assign default value to vertex attribute
glVertexAttrib4f(
new_attribute.location,
attrib_info->default_value.xyzw.x,
attrib_info->default_value.xyzw.y,
attrib_info->default_value.xyzw.z,
attrib_info->default_value.xyzw.w
);
Current_shader->attributes.push_back(new_attribute);
}
/**
@@ -927,7 +1033,7 @@ float opengl_shader_get_animated_timer()
}
/**
* Compile the deferred light shader.
* Compile the deferred light shader and the clear shader.
*/
void opengl_shader_compile_deferred_light_shader()
{
@@ -962,9 +1068,6 @@ void opengl_shader_compile_deferred_light_shader()
}
}
/**
* Compile the deferred light clear shader.
*/
void opengl_shader_compile_passthrough_shader()
{
bool in_error = false;
@@ -973,7 +1076,7 @@ void opengl_shader_compile_passthrough_shader()
int sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0);
if (sdr_handle >= 0) {
if ( sdr_handle >= 0 ) {
opengl_shader_set_current(sdr_handle);
//Hardcoded Uniforms
@@ -983,42 +1086,54 @@ void opengl_shader_compile_passthrough_shader()
GL_state.Uniform.setUniformi("srgb", 0);
} else {
opengl_shader_set_current();
mprintf(("Failed to compile deferred lighting shader!\n"));
mprintf(("Failed to compile passthrough shader!\n"));
in_error = true;
}
if (in_error) {
if ( in_error ) {
mprintf((" Shader in_error! Passthrough shader unavailable!\n"));
}
opengl_shader_set_current();
}
void opengl_shader_set_passthrough(bool textured, bool alpha, float color_scale)
void opengl_shader_set_passthrough(bool textured, bool alpha, color *clr, float color_scale)
{
if ( !is_minimum_GLSL_version() ) {
opengl_shader_set_current();
return;
}
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
if (textured) {
if ( textured ) {
GL_state.Uniform.setUniformi("noTexturing", 0);
} else {
GL_state.Uniform.setUniformi("noTexturing", 1);
}
if (alpha) {
if ( alpha ) {
GL_state.Uniform.setUniformi("alphaTexture", 1);
} else {
GL_state.Uniform.setUniformi("alphaTexture", 0);
}
if (High_dynamic_range) {
GL_state.Uniform.setUniformi("srgb", 1);
if ( High_dynamic_range ) {
GL_state.Uniform.setUniformi("srgb", 1);
GL_state.Uniform.setUniformf("intensity", color_scale);
} else {
GL_state.Uniform.setUniformi("srgb", 0);
GL_state.Uniform.setUniformf("intensity", 1.0f);
}
GL_state.Uniform.setUniformf("alphaThreshold", GL_alpha_threshold);
if ( clr != NULL ) {
GL_state.Uniform.setUniform4f("color", i2fl(clr->red) / 255.0f, i2fl(clr->green) / 255.0f, i2fl(clr->blue) / 255.0f, i2fl(clr->alpha) / 255.0f);
} else {
GL_state.Uniform.setUniformi("srgb", 0);
GL_state.Uniform.setUniform4f("color", 1.0f, 1.0f, 1.0f, 1.0f);
}
GL_state.Uniform.setUniformf("intensity", color_scale);
GL_state.Uniform.setUniformMatrix4f("modelViewMatrix", GL_model_view_matrix);
GL_state.Uniform.setUniformMatrix4f("projMatrix", GL_projection_matrix);
}
+36 -5
View File
@@ -12,6 +12,7 @@
#define _GROPENGLSHADER_H
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "graphics/gropengl.h"
#include <string>
@@ -22,10 +23,36 @@
#define SDR_ATTRIB_RADIUS 0
#define SDR_ATTRIB_SUBMODEL 1
#define MAX_SDR_ATTRIBUTES 5
#define MAX_SDR_ATTRIBUTES 8
#define MAX_SDR_UNIFORM_BLOCKS 5
enum shader_stage {
SDR_STAGE_VERTEX,
SDR_STAGE_FRAGMENT,
SDR_STAGE_GEOMETRY
};
struct opengl_vert_attrib {
enum attrib_id {
POSITION,
COLOR,
TEXCOORD,
NORMAL,
TANGENT,
MODEL_ID,
RADIUS,
UVEC,
NUM_ATTRIBS
};
attrib_id attribute_id;
SCP_string name;
vec4 default_value;
};
extern opengl_vert_attrib GL_vertex_attrib_info[];
struct geometry_sdr_params
{
int input_type;
@@ -46,7 +73,8 @@ struct opengl_shader_type_t {
char* uniforms[MAX_SHADER_UNIFORMS];
int num_attributes;
char* attributes[MAX_SDR_ATTRIBUTES];
//char* attributes[MAX_SDR_ATTRIBUTES];
opengl_vert_attrib::attrib_id attributes[MAX_SDR_ATTRIBUTES];
const char* description;
};
@@ -63,7 +91,8 @@ struct opengl_shader_variant_t {
char* uniforms[MAX_SHADER_UNIFORMS];
int num_attributes;
char* attributes[MAX_SDR_ATTRIBUTES];
//char* attributes[MAX_SDR_ATTRIBUTES];
opengl_vert_attrib::attrib_id attributes[MAX_SDR_ATTRIBUTES];
const char* description;
};
@@ -134,14 +163,13 @@ void opengl_delete_shader(int sdr_handle);
void opengl_shader_set_current(opengl_shader_t *shader_obj = NULL);
void opengl_shader_set_current(int handle);
void opengl_shader_set_passthrough(bool textured = true, bool alpha = false, float color_scale = 1.0f);
void opengl_shader_init();
void opengl_shader_shutdown();
int opengl_compile_shader(shader_type sdr, uint flags);
void opengl_shader_init_attribute(const char *attribute_text);
void opengl_shader_init_attribute(const opengl_vert_attrib *attrib_info);
GLint opengl_shader_get_attribute(const char *attribute_text);
void opengl_shader_init_uniform(const char *uniform_text);
@@ -150,6 +178,8 @@ GLint opengl_shader_get_uniform(const char *uniform_text);
void opengl_shader_init_uniform_block(const char *uniform_text);
GLint opengl_shader_get_uniform_block(const char *uniform_text);
void opengl_program_check_info_log(GLuint program_object);
void opengl_shader_check_info_log(GLuint shader_object);
void gr_opengl_shader_set_animated_effect(int effect, float timer);
int opengl_shader_get_animated_effect();
@@ -159,6 +189,7 @@ void opengl_shader_compile_deferred_light_shader();
void opengl_shader_compile_deferred_light_clear_shader();
void opengl_shader_compile_passthrough_shader();
void opengl_shader_set_passthrough(bool textured = true, bool alpha = false, color* clr = NULL, float color_scale = 1.0f);
#define ANIMATED_SHADER_LOADOUTSELECT_FS1 0
#define ANIMATED_SHADER_LOADOUTSELECT_FS2 1
+446 -12
View File
@@ -10,6 +10,7 @@
#include "graphics/gropengllight.h"
#include "graphics/gropenglshader.h"
#include "graphics/material.h"
#include "graphics/gropenglstate.h"
#include "math/vecmat.h"
@@ -40,7 +41,7 @@ void opengl_texture_state::init(GLuint n_units)
default_values(unit);
glActiveTexture(GL_TEXTURE0 + unit);
if (unit < (GLuint)GL_supported_texture_units) {
if (unit < (GLuint)GL_supported_texture_units && !is_minimum_GLSL_version()) {
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
@@ -52,7 +53,7 @@ void opengl_texture_state::init(GLuint n_units)
units[unit].texgen_R = GL_FALSE;
units[unit].texgen_Q = GL_FALSE;
if (unit < (GLuint)GL_supported_texture_units) {
if (unit < (GLuint)GL_supported_texture_units && !is_minimum_GLSL_version()) {
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
@@ -64,7 +65,7 @@ void opengl_texture_state::init(GLuint n_units)
units[unit].texgen_mode_R = GL_EYE_LINEAR;
units[unit].texgen_mode_Q = GL_EYE_LINEAR;
if (unit < (GLuint)GL_supported_texture_units) {
if (unit < (GLuint)GL_supported_texture_units && !is_minimum_GLSL_version()) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
@@ -74,7 +75,7 @@ void opengl_texture_state::init(GLuint n_units)
units[unit].env_combine_rgb = GL_MODULATE;
units[unit].env_combine_alpha = GL_MODULATE;
if (unit < (GLuint)GL_supported_texture_units) {
if (unit < (GLuint)GL_supported_texture_units && !is_minimum_GLSL_version()) {
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0f);
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);
}
@@ -91,7 +92,7 @@ void opengl_texture_state::default_values(GLint unit, GLenum target)
glActiveTexture(GL_TEXTURE0 + unit);
if (target == GL_INVALID_ENUM) {
if (unit < GL_supported_texture_units) {
if (unit < GL_supported_texture_units && !is_minimum_GLSL_version()) {
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
@@ -213,7 +214,7 @@ void opengl_texture_state::Enable(GLuint tex_id)
}
if ( !shader_mode && (active_texture_unit < (uint)GL_supported_texture_units) ) {
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT)
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT && !is_minimum_GLSL_version() )
glEnable( units[active_texture_unit].texture_target );
units[active_texture_unit].enabled = GL_TRUE;
}
@@ -233,7 +234,7 @@ void opengl_texture_state::Disable()
}
if ( units[active_texture_unit].enabled ) {
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT)
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT && !is_minimum_GLSL_version() )
glDisable( units[active_texture_unit].texture_target );
units[active_texture_unit].enabled = GL_FALSE;
}
@@ -340,13 +341,19 @@ void opengl_state::init()
{
int i;
glDisable(GL_FOG);
if ( !is_minimum_GLSL_version() ) {
glDisable(GL_FOG);
}
fog_Status = GL_FALSE;
glDisable(GL_BLEND);
blend_Status = GL_FALSE;
glDisable(GL_ALPHA_TEST);
if ( !is_minimum_GLSL_version() ) {
glDisable(GL_ALPHA_TEST);
}
alphatest_Status = GL_FALSE;
glDisable(GL_DEPTH_TEST);
@@ -364,7 +371,9 @@ void opengl_state::init()
polygon_offset_Factor = 0.0f;
polygon_offset_Unit = 0.0f;
glDisable(GL_NORMALIZE);
if ( !is_minimum_GLSL_version() ) {
glDisable(GL_NORMALIZE);
}
normalize_Status = GL_FALSE;
for (i = 0; i < (int)(sizeof(clipplane_Status) / sizeof(GLboolean)); i++) {
@@ -383,14 +392,18 @@ void opengl_state::init()
light_Status = (GLboolean*) vm_malloc(GL_max_lights * sizeof(GLboolean));
for (i = 0; i < GL_max_lights; i++) {
glDisable(GL_LIGHT0+i);
if ( !is_minimum_GLSL_version() ) {
glDisable(GL_LIGHT0 + i);
}
light_Status[i] = GL_FALSE;
}
glDepthMask(GL_FALSE);
depthmask_Status = GL_FALSE;
glDisable(GL_LIGHTING);
if ( !is_minimum_GLSL_version() ) {
glDisable(GL_LIGHTING);
}
lighting_Status = GL_FALSE;
glFrontFace(GL_CCW);
@@ -406,6 +419,8 @@ void opengl_state::init()
glDepthFunc(GL_LESS);
depthfunc_Value = GL_LESS;
glGetFloatv(GL_LINE_WIDTH, &line_width_Value);
Current_alpha_blend_mode = ALPHA_BLEND_NONE;
Current_zbuffer_type = ZBUFFER_TYPE_READ;
@@ -852,6 +867,16 @@ void opengl_state::SetStencilType(gr_stencil_type st)
Current_stencil_type = st;
}
void opengl_state::SetLineWidth(GLfloat width)
{
if ( width == line_width_Value ) {
return;
}
glLineWidth(width);
line_width_Value = width;
}
opengl_array_state::~opengl_array_state()
{
if ( client_texture_units != NULL ) {
@@ -911,6 +936,11 @@ void opengl_array_state::init(GLuint n_units)
void opengl_array_state::SetActiveClientUnit(GLuint id)
{
// this function is deprecated in OGL Core
if ( is_minimum_GLSL_version() ) {
return;
}
if ( id >= num_client_texture_units ) {
Int3();
id = 0;
@@ -1171,6 +1201,17 @@ void opengl_array_state::VertexAttribPointer(GLuint index, GLint size, GLenum ty
va_unit->ptr_init = true;
}
void opengl_array_state::ResetVertexAttribs()
{
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
DisableVertexAttrib(it->first);
}
vertex_attrib_units.clear();
}
void opengl_array_state::BindPointersBegin()
{
// set all available client states to not used
@@ -1347,6 +1388,59 @@ void opengl_uniform_state::setUniformi(const SCP_string &name, const int val)
glUniform1i(opengl_shader_get_uniform(name.c_str()), val);
}
void opengl_uniform_state::setUniform1iv(const SCP_string &name, const int count, const int *val)
{
int uniform_index = findUniform(name);
bool resident = false;
if ( uniform_index >= 0 ) {
Assert((size_t)uniform_index < uniforms.size());
uniform_bind *bind_info = &uniforms[uniform_index];
if ( bind_info->type == uniform_bind::INT && bind_info->count == count ) {
bool equal = true;
// if the values are close enough, pass.
for ( int i = 0; i < count; ++i ) {
if ( val[i] != uniform_data_ints[bind_info->index + i] ) {
equal = false;
break;
}
}
if ( equal ) {
return;
}
resident = true;
for ( int i = 0; i < count; ++i ) {
uniform_data_ints[bind_info->index + i] = val[i];
}
}
}
if ( !resident ) {
// uniform doesn't exist in our previous uniform block so queue this new value
for ( int i = 0; i < count; ++i ) {
uniform_data_ints.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = uniform_data_ints.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::INT;
new_bind.name = name;
uniforms.push_back(new_bind);
uniform_lookup[name] = uniforms.size() - 1;
}
glUniform1iv(opengl_shader_get_uniform(name.c_str()), count, (const GLint*)val);
}
void opengl_uniform_state::setUniformf(const SCP_string &name, const float val)
{
size_t uniform_index = findUniform(name);
@@ -1537,6 +1631,165 @@ void opengl_uniform_state::setUniform4f(const SCP_string &name, const vec4 &val)
glUniform4f(opengl_shader_get_uniform(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]);
}
void opengl_uniform_state::setUniform1fv(const SCP_string &name, const int count, const float *val)
{
int uniform_index = findUniform(name);
bool resident = false;
if ( uniform_index >= 0 ) {
Assert((size_t)uniform_index < uniforms.size());
uniform_bind *bind_info = &uniforms[uniform_index];
if ( bind_info->type == uniform_bind::FLOAT && bind_info->count == count ) {
bool equal = true;
// if the values are close enough, pass.
for ( int i = 0; i < count; ++i ) {
if ( !fl_equal(val[i], uniform_data_floats[bind_info->index + i]) ) {
equal = false;
break;
}
}
if ( equal ) {
return;
}
resident = true;
for ( int i = 0; i < count; ++i ) {
uniform_data_floats[bind_info->index + i] = val[i];
}
}
}
if ( !resident ) {
// uniform doesn't exist in our previous uniform block so queue this new value
for ( int i = 0; i < count; ++i ) {
uniform_data_floats.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = uniform_data_floats.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::FLOAT;
new_bind.name = name;
uniforms.push_back(new_bind);
uniform_lookup[name] = uniforms.size() - 1;
}
glUniform1fv(opengl_shader_get_uniform(name.c_str()), count, (const GLfloat*)val);
}
void opengl_uniform_state::setUniform3fv(const SCP_string &name, const int count, const vec3d *val)
{
int uniform_index = findUniform(name);
bool resident = false;
if ( uniform_index >= 0 ) {
Assert((size_t)uniform_index < uniforms.size());
uniform_bind *bind_info = &uniforms[uniform_index];
if ( bind_info->type == uniform_bind::VEC3 && bind_info->count == count ) {
bool equal = true;
// if the values are close enough, pass.
for ( int i = 0; i < count; ++i ) {
if ( !vm_vec_equal(val[i], uniform_data_vec3d[bind_info->index + i]) ) {
equal = false;
break;
}
}
if ( equal ) {
return;
}
resident = true;
for ( int i = 0; i < count; ++i ) {
uniform_data_vec3d[bind_info->index + i] = val[i];
}
}
}
if ( !resident ) {
// uniform doesn't exist in our previous uniform block so queue this new value
for ( int i = 0; i < count; ++i ) {
uniform_data_vec3d.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = uniform_data_vec3d.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::VEC3;
new_bind.name = name;
uniforms.push_back(new_bind);
uniform_lookup[name] = uniforms.size() - 1;
}
glUniform3fv(opengl_shader_get_uniform(name.c_str()), count, (const GLfloat*)val);
}
void opengl_uniform_state::setUniform4fv(const SCP_string &name, const int count, const vec4 *val)
{
int uniform_index = findUniform(name);
bool resident = false;
if ( uniform_index >= 0 ) {
Assert((size_t)uniform_index < uniforms.size());
uniform_bind *bind_info = &uniforms[uniform_index];
if ( bind_info->type == uniform_bind::VEC4 && bind_info->count == count ) {
bool equal = true;
// if the values are close enough, pass.
for ( int i = 0; i < count; ++i ) {
if ( !vm_vec_equal(val[i], uniform_data_vec4[bind_info->index + i]) ) {
equal = false;
break;
}
}
if ( equal ) {
return;
}
resident = true;
for ( int i = 0; i < count; ++i ) {
uniform_data_vec4[bind_info->index + i] = val[i];
}
}
}
if ( !resident ) {
// uniform doesn't exist in our previous uniform block so queue this new value
for ( int i = 0; i < count; ++i ) {
uniform_data_vec4.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = uniform_data_vec4.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::VEC4;
new_bind.name = name;
uniforms.push_back(new_bind);
uniform_lookup[name] = uniforms.size() - 1;
}
glUniform4fv(opengl_shader_get_uniform(name.c_str()), count, (const GLfloat*)val);
}
void opengl_uniform_state::setUniformMatrix4f(const SCP_string &name, const matrix4 &val)
{
size_t uniform_index = findUniform(name);
@@ -1646,8 +1899,189 @@ void opengl_uniform_state::reset()
uniform_lookup.clear();
}
opengl_light_state::opengl_light_state(int light_num): Light_num(light_num)
{
}
void opengl_light_state::Enable()
{
Assert ( Light_num >= 0 && Light_num < GL_max_lights );
if ( Enabled ) {
return;
}
glEnable(GL_LIGHT0 + Light_num);
Enabled = true;
}
void opengl_light_state::Disable()
{
Assert ( Light_num >= 0 && Light_num < GL_max_lights );
if ( !Enabled ) {
return;
}
glDisable(GL_LIGHT0 + Light_num);
Enabled = false;
}
void opengl_light_state::Invalidate()
{
InvalidPosition = true;
}
void opengl_light_state::SetPosition(GLfloat *val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( !InvalidPosition &&
fl_equal(Position[0], val[0]) &&
fl_equal(Position[1], val[1]) &&
fl_equal(Position[2], val[2]) &&
fl_equal(Position[3], val[3]) ) {
return;
}
Position[0] = val[0];
Position[1] = val[1];
Position[2] = val[2];
Position[3] = val[3];
glLightfv(GL_LIGHT0 + Light_num, GL_POSITION, val);
InvalidPosition = false;
}
void opengl_light_state::SetAmbient(GLfloat *val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(Ambient[0], val[0]) &&
fl_equal(Ambient[1], val[1]) &&
fl_equal(Ambient[2], val[2]) &&
fl_equal(Ambient[3], val[3]) ) {
return;
}
Ambient[0] = val[0];
Ambient[1] = val[1];
Ambient[2] = val[2];
Ambient[3] = val[3];
glLightfv(GL_LIGHT0 + Light_num, GL_AMBIENT, val);
}
void opengl_light_state::SetDiffuse(GLfloat *val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(Diffuse[0], val[0]) &&
fl_equal(Diffuse[1], val[1]) &&
fl_equal(Diffuse[2], val[2]) &&
fl_equal(Diffuse[3], val[3]) ) {
return;
}
Diffuse[0] = val[0];
Diffuse[1] = val[1];
Diffuse[2] = val[2];
Diffuse[3] = val[3];
glLightfv(GL_LIGHT0 + Light_num, GL_DIFFUSE, val);
}
void opengl_light_state::SetSpecular(GLfloat *val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(Specular[0], val[0]) &&
fl_equal(Specular[1], val[1]) &&
fl_equal(Specular[2], val[2]) &&
fl_equal(Specular[3], val[3]) ) {
return;
}
Specular[0] = val[0];
Specular[1] = val[1];
Specular[2] = val[2];
Specular[3] = val[3];
glLightfv(GL_LIGHT0 + Light_num, GL_SPECULAR, val);
}
void opengl_light_state::SetConstantAttenuation(GLfloat val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(ConstantAttenuation, val) ) {
return;
}
ConstantAttenuation = val;
glLightf(GL_LIGHT0 + Light_num, GL_CONSTANT_ATTENUATION, val);
}
void opengl_light_state::SetLinearAttenuation(GLfloat val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(LinearAttenuation, val) ) {
return;
}
LinearAttenuation = val;
glLightf(GL_LIGHT0 + Light_num, GL_LINEAR_ATTENUATION, val);
}
void opengl_light_state::SetQuadraticAttenuation(GLfloat val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(QuadraticAttenuation, val) ) {
return;
}
QuadraticAttenuation = val;
glLightf(GL_LIGHT0 + Light_num, GL_QUADRATIC_ATTENUATION, val);
}
void opengl_light_state::SetSpotExponent(GLfloat val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(SpotExponent, val) ) {
return;
}
SpotExponent = val;
glLightf(GL_LIGHT0 + Light_num, GL_SPOT_EXPONENT, val);
}
void opengl_light_state::SetSpotCutoff(GLfloat val)
{
Assert(Light_num >= 0 && Light_num < GL_max_lights);
if ( fl_equal(SpotCutoff, val) ) {
return;
}
SpotCutoff = val;
glLightf(GL_LIGHT0 + Light_num, GL_SPOT_CUTOFF, val);
}
void gr_opengl_clear_states()
{
if ( GL_version >= 30 ) {
glBindVertexArray(GL_vao);
}
GL_state.Texture.DisableAll();
gr_zbias(0);
+49
View File
@@ -14,10 +14,13 @@
#include "globalincs/pstypes.h"
#include "graphics/gropengl.h"
#include "graphics/gropengltexture.h"
#include "graphics/gropenglshader.h"
#include "graphics/material.h"
#include <glad/glad.h>
#define MAX_UNIFORM_BUFFERS 6
#define MAX_UNIFORM_LOCATIONS 256
struct opengl_texture_unit {
GLboolean active; // unit is active
@@ -245,6 +248,8 @@ class opengl_array_state
GLuint uniform_buffer;
GLuint uniform_buffer_index_bindings[MAX_UNIFORM_BUFFERS];
GLuint vertex_array_object;
public:
opengl_array_state(): active_client_texture_unit(0), client_texture_units(NULL) {
for ( int i = 0; i < MAX_UNIFORM_BUFFERS; ++i ) {
@@ -275,6 +280,7 @@ class opengl_array_state
void EnableVertexAttrib(GLuint index);
void DisableVertexAttrib(GLuint index);
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer);
void ResetVertexAttribs();
void BindPointersBegin();
void BindPointersEnd();
@@ -324,6 +330,7 @@ public:
opengl_uniform_state();
void setUniformi(const SCP_string &name, const int value);
void setUniform1iv(const SCP_string &name, const int count, const int *val);
void setUniformf(const SCP_string &name, const float value);
void setUniform2f(const SCP_string &name, const float x, const float y);
void setUniform2f(const SCP_string &name, const vec2d &val);
@@ -331,12 +338,51 @@ public:
void setUniform3f(const SCP_string &name, const vec3d &value);
void setUniform4f(const SCP_string &name, const float x, const float y, const float z, const float w);
void setUniform4f(const SCP_string &name, const vec4 &val);
void setUniform1fv(const SCP_string &name, const int count, const float *val);
void setUniform3fv(const SCP_string &name, const int count, const vec3d *val);
void setUniform4fv(const SCP_string &name, const int count, const vec4 *val);
void setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *value);
void setUniformMatrix4f(const SCP_string &name, const matrix4 &val);
void reset();
};
class opengl_light_state
{
int Light_num;
bool Enabled;
GLfloat Position[4];
bool InvalidPosition;
GLfloat Ambient[4];
GLfloat Diffuse[4];
GLfloat Specular[4];
GLfloat ConstantAttenuation;
GLfloat LinearAttenuation;
GLfloat QuadraticAttenuation;
GLfloat SpotExponent;
GLfloat SpotCutoff;
public:
opengl_light_state(int light_num);
void Enable();
void Disable();
void Invalidate();
void SetPosition(GLfloat *val);
void SetAmbient(GLfloat *val);
void SetDiffuse(GLfloat *val);
void SetSpecular(GLfloat *val);
void SetConstantAttenuation(GLfloat val);
void SetLinearAttenuation(GLfloat val);
void SetQuadraticAttenuation(GLfloat val);
void SetSpotExponent(GLfloat val);
void SetSpotCutoff(GLfloat val);
};
class opengl_state
{
friend class opengl_texture_state;
@@ -374,6 +420,8 @@ class opengl_state
GLfloat polygon_offset_Factor;
GLfloat polygon_offset_Unit;
GLfloat line_width_Value;
gr_alpha_blend Current_alpha_blend_mode;
gr_zbuffer_type Current_zbuffer_type;
gr_stencil_type Current_stencil_type;
@@ -393,6 +441,7 @@ class opengl_state
void SetStencilType(gr_stencil_type st);
void SetPolygonOffset(GLfloat factor, GLfloat units);
void SetPolygonMode(GLenum face, GLenum mode);
void SetLineWidth(GLfloat width);
// the GLboolean functions will return the current state if no argument
// and the previous state if an argument is passed
+28 -4
View File
@@ -25,6 +25,8 @@
static tcache_slot_opengl *Textures = NULL;
static int *Tex_used_this_frame = NULL;
matrix4 GL_texture_matrix;
int GL_texture_ram = 0;
int GL_min_texture_width = 0;
GLint GL_max_texture_width = 0;
@@ -186,13 +188,18 @@ void opengl_tcache_init()
GL_xlat[15] = GL_xlat[1];
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &GL_supported_texture_units);
if ( !is_minimum_GLSL_version() ) {
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &GL_supported_texture_units);
}
Assert( GL_supported_texture_units >= 2 );
GL_last_detail = Detail.hardware_textures;
GL_textures_in = 0;
GL_textures_in_frame = 0;
vm_matrix4_set_identity(&GL_texture_matrix);
}
void opengl_free_texture_with_handle(int handle)
@@ -555,10 +562,12 @@ int opengl_create_texture_sub(int bitmap_handle, int bitmap_type, int bmap_w, in
}
}
GLenum aa_format = is_minimum_GLSL_version() ? GL_RED : GL_ALPHA;
if ( !reload ) {
glTexImage2D (t->texture_target, 0, GL_ALPHA, tex_w, tex_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texmem);
glTexImage2D (t->texture_target, 0, aa_format, tex_w, tex_h, 0, aa_format, GL_UNSIGNED_BYTE, texmem);
} else { // faster anis
glTexSubImage2D (t->texture_target, 0, 0, 0, tex_w, tex_h, GL_ALPHA, GL_UNSIGNED_BYTE, texmem);
glTexSubImage2D (t->texture_target, 0, 0, 0, tex_w, tex_h, aa_format, GL_UNSIGNED_BYTE, texmem);
}
if (texmem != NULL) {
@@ -1096,6 +1105,10 @@ void gr_opengl_set_texture_panning(float u, float v, bool enable)
GLint current_matrix;
if (enable) {
vm_matrix4_set_identity(&GL_texture_matrix);
GL_texture_matrix.vec.pos.xyzw.x = u;
GL_texture_matrix.vec.pos.xyzw.y = v;
glGetIntegerv(GL_MATRIX_MODE, &current_matrix);
glMatrixMode( GL_TEXTURE );
glPushMatrix();
@@ -1104,6 +1117,8 @@ void gr_opengl_set_texture_panning(float u, float v, bool enable)
GL_texture_panning_enabled = 1;
} else if (GL_texture_panning_enabled) {
vm_matrix4_set_identity(&GL_texture_matrix);
glGetIntegerv(GL_MATRIX_MODE, &current_matrix);
glMatrixMode( GL_TEXTURE );
glPopMatrix();
@@ -1295,6 +1310,15 @@ int opengl_get_texture( GLenum target, GLenum pixel_format, GLenum data_format,
return m_offset;
}
void gr_opengl_get_texture_scale(int bitmap_handle, float *u_scale, float *v_scale)
{
int n = bm_get_cache_slot (bitmap_handle, 1);
tcache_slot_opengl *t = &Textures[n];
*u_scale = t->u_scale;
*v_scale = t->v_scale;
}
/**
* Sends a texture object out to "image_data"
*
@@ -1393,7 +1417,7 @@ void gr_opengl_update_texture(int bitmap_handle, int bpp, const ubyte* data, int
}
if (byte_mult == 1) {
texFormat = GL_UNSIGNED_BYTE;
glFormat = GL_ALPHA;
glFormat = is_minimum_GLSL_version() ? GL_RED : GL_ALPHA;
texmem = (ubyte *) vm_malloc (width*height*byte_mult);
ubyte* texmemp = texmem;
+3
View File
@@ -50,6 +50,8 @@ typedef struct tcache_slot_opengl {
}
} tcache_slot_opengl;
extern matrix4 GL_texture_matrix;
extern int GL_min_texture_width;
extern GLint GL_max_texture_width;
extern int GL_min_texture_height;
@@ -87,5 +89,6 @@ void gr_opengl_set_texture_panning(float u, float v, bool enable);
void gr_opengl_set_texture_addressing(int mode);
GLuint opengl_get_rtt_framebuffer();
void gr_opengl_bm_generate_mip_maps(int slot);
void gr_opengl_get_texture_scale(int bitmap_handle, float *u_scale, float *v_scale);
#endif //_GROPENGLTEXTURE_H
File diff suppressed because it is too large. Load diff
+29 -6
View File
@@ -33,6 +33,13 @@ extern float shadow_middist;
extern float shadow_fardist;
extern bool Rendering_to_shadow_map;
extern matrix4 GL_view_matrix;
extern matrix4 GL_model_view_matrix;
extern matrix4 GL_projection_matrix;
extern matrix4 GL_last_projection_matrix;
extern int GL_immediate_buffer_handle;
void gr_opengl_start_instance_matrix(const vec3d *offset, const matrix *rotation);
void gr_opengl_start_instance_angles(const vec3d *pos, const angles *rotation);
void gr_opengl_end_instance_matrix();
@@ -45,23 +52,33 @@ void gr_opengl_end_2d_matrix();
void gr_opengl_push_scale_matrix(const vec3d *scale_factor);
void gr_opengl_pop_scale_matrix();
void opengl_create_perspective_projection_matrix(matrix4 *out, float left, float right, float bottom, float top, float near_dist, float far_dist);
void opengl_create_orthographic_projection_matrix(matrix4* out, float left, float right, float bottom, float top, float near_dist, float far_dist);
void opengl_create_view_matrix(matrix4 *out, const vec3d *pos, const matrix *orient);
void gr_opengl_start_clip_plane();
void gr_opengl_end_clip_plane();
int gr_opengl_create_vertex_buffer(bool static_buffer);
int gr_opengl_create_index_buffer(bool static_buffer);
int gr_opengl_create_buffer();
bool gr_opengl_pack_buffer(const int buffer_id, vertex_buffer *vb);
bool gr_opengl_config_buffer(const int buffer_id, vertex_buffer *vb, bool update_ibuffer_only);
void gr_opengl_destroy_buffer(int idx);
void gr_opengl_set_buffer(int idx);
void gr_opengl_render_buffer(int start, const vertex_buffer *bufferp, size_t texi, int flags);
void gr_opengl_render_buffer(int start, vertex_buffer *bufferp, size_t texi, int flags);
void gr_opengl_render_to_env(int FACE);
void gr_opengl_update_buffer_object(int handle, size_t size, void* data);
void opengl_delete_buffer_object(int handle);
void opengl_bind_buffer_object(int handle);
void gr_opengl_update_buffer_data(int handle, size_t size, void* data);
void gr_opengl_delete_buffer(int handle);
void gr_opengl_update_transform_buffer(void* data, size_t size);
void gr_opengl_set_transform_buffer_offset(size_t offset);
uint opengl_add_to_immediate_buffer(uint size, void *data);
void opengl_reset_immediate_buffer();
int gr_opengl_create_stream_buffer_object();
void gr_opengl_render_stream_buffer(int buffer_handle, size_t offset, size_t n_verts, int flags);
@@ -71,8 +88,14 @@ void gr_opengl_set_team_color(const team_color *colors);
void opengl_tnl_init();
void opengl_tnl_shutdown();
void opengl_tnl_set_material(int flags, uint shader_flags, int tmap_type);
void opengl_tnl_set_material_distortion(uint flags);
void opengl_tnl_set_material_soft_particle(uint flags);
void gr_opengl_render_model(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, int texi);
void opengl_render_model_program(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, buffer_data *datap);
void opengl_render_model_fixed(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer *bufferp, buffer_data *datap);
void opengl_tnl_set_material(material* material_info, bool set_base_map);
void opengl_tnl_set_material_distortion(distortion_material* material_info);
void opengl_tnl_set_material_particle(particle_material * material_info);
void opengl_tnl_set_model_material(model_material *material_info);
#endif //_GROPENGLTNL_H
+79 -4
View File
@@ -9,6 +9,7 @@
#include "graphics/grinternal.h"
#include "jpgutils/jpgutils.h"
#include "model/model.h"
#include "graphics/material.h"
#include "pcxutils/pcxutils.h"
#include "pngutils/pngutils.h"
#include "tgautils/tgautils.h"
@@ -22,6 +23,21 @@ uint gr_stub_lock()
return 1;
}
int gr_stub_create_vertex_buffer(bool static_buffer)
{
return -1;
}
int gr_stub_create_index_buffer(bool static_buffer)
{
return -1;
}
void gr_stub_delete_buffer(int handle)
{
}
// NOTE: should return a failure
int gr_stub_create_buffer()
{
@@ -222,7 +238,7 @@ void gr_stub_rect(int x, int y, int w, int h, int resize_mode)
{
}
void gr_stub_render_buffer(int start, const vertex_buffer *bufferp, size_t texi, int flags)
void gr_stub_render_buffer(int start, vertex_buffer *bufferp, size_t texi, int flags)
{
}
@@ -254,7 +270,7 @@ void gr_stub_set_buffer(int idx)
{
}
void gr_stub_update_buffer_object(int handle, size_t size, void* data)
void gr_stub_update_buffer_data(int handle, size_t size, void* data)
{
}
@@ -462,6 +478,10 @@ void gr_stub_draw_htl_sphere(float rad)
{
}
void gr_stub_draw_sphere(material *material_def, float rad)
{
}
void gr_stub_draw_line_list(const colored_vector *lines, int num)
{
}
@@ -522,7 +542,7 @@ void gr_stub_set_animated_effect(int effect, float timer)
void gr_stub_set_team_color(const team_color *colors) {
}
void gr_stub_shadow_map_start(const matrix4 *shadow_view_matrix, const matrix* light_matrix)
void gr_stub_shadow_map_start(matrix4 *shadow_view_matrix, const matrix* light_matrix)
{
}
@@ -530,6 +550,46 @@ void gr_stub_shadow_map_end()
{
}
void gr_stub_render_model(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, int texi)
{
}
void gr_stub_render_primitives(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
}
void gr_stub_render_primitives_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
}
void gr_stub_render_primitives_2d(material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
}
void gr_stub_render_primitives_2d_immediate(material* material_info, primitive_type prim_type, vertex_layout* layout, int n_verts, void* data, int size)
{
}
void gr_stub_render_primitives_particle(particle_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
}
void gr_stub_render_primitives_distortion(distortion_material* material_info, primitive_type prim_type, vertex_layout* layout, int offset, int n_verts, int buffer_handle)
{
}
bool gr_stub_is_capable(gr_capability capability)
{
return false;
}
bool gr_stub_init()
{
if (gr_screen.res != GR_640) {
@@ -638,6 +698,9 @@ bool gr_stub_init()
gr_screen.gf_set_fill_mode = gr_set_fill_mode_stub;
gr_screen.gf_set_texture_panning = gr_stub_set_texture_panning;
gr_screen.gf_create_vertex_buffer = gr_stub_create_vertex_buffer;
gr_screen.gf_create_index_buffer = gr_stub_create_index_buffer;
gr_screen.gf_delete_buffer = gr_stub_delete_buffer;
gr_screen.gf_create_buffer = gr_stub_create_buffer;
gr_screen.gf_config_buffer = gr_stub_config_buffer;
gr_screen.gf_pack_buffer = gr_stub_pack_buffer;
@@ -646,7 +709,7 @@ bool gr_stub_init()
gr_screen.gf_set_buffer = gr_stub_set_buffer;
gr_screen.gf_update_transform_buffer = gr_stub_update_transform_buffer;
gr_screen.gf_update_buffer_object = gr_stub_update_buffer_object;
gr_screen.gf_update_buffer_data = gr_stub_update_buffer_data;
gr_screen.gf_set_transform_buffer_offset = gr_stub_set_transform_buffer_offset;
gr_screen.gf_create_stream_buffer = gr_stub_create_stream_buffer;
@@ -701,6 +764,7 @@ bool gr_stub_init()
gr_screen.gf_line_htl = gr_stub_draw_htl_line;
gr_screen.gf_sphere_htl = gr_stub_draw_htl_sphere;
gr_screen.gf_sphere = gr_stub_draw_sphere;
gr_screen.gf_shadow_map_start = gr_stub_shadow_map_start;
gr_screen.gf_shadow_map_end = gr_stub_shadow_map_end;
@@ -715,5 +779,16 @@ bool gr_stub_init()
gr_screen.gf_update_texture = gr_stub_update_texture;
gr_screen.gf_get_bitmap_from_texture = gr_stub_get_bitmap_from_texture;
gr_screen.gf_render_model = gr_stub_render_model;
gr_screen.gf_render_primitives = gr_stub_render_primitives;
gr_screen.gf_render_primitives_immediate = gr_stub_render_primitives_immediate;
gr_screen.gf_render_primitives_2d = gr_stub_render_primitives_2d;
gr_screen.gf_render_primitives_2d_immediate = gr_stub_render_primitives_2d_immediate;
gr_screen.gf_render_primitives_particle = gr_stub_render_primitives_particle;
gr_screen.gf_render_primitives_distortion = gr_stub_render_primitives_distortion;
gr_screen.gf_is_capable = gr_stub_is_capable;
return true;
}
+771
View File
@@ -0,0 +1,771 @@
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
#include "graphics/2d.h"
#include "graphics/material.h"
#include "globalincs/systemvars.h"
#include "cmdline/cmdline.h"
gr_alpha_blend material_determine_blend_mode(int base_bitmap, bool blending)
{
if ( blending ) {
if ( base_bitmap >= 0 && bm_has_alpha_channel(base_bitmap) ) {
return ALPHA_BLEND_ALPHA_BLEND_ALPHA;
}
return ALPHA_BLEND_ADDITIVE;
}
return ALPHA_BLEND_ALPHA_BLEND_ALPHA;
}
gr_zbuffer_type material_determine_depth_mode(bool depth_testing, bool blending)
{
if ( depth_testing ) {
if ( blending ) {
return ZBUFFER_TYPE_READ;
}
return ZBUFFER_TYPE_FULL;
}
return ZBUFFER_TYPE_NONE;
}
void material_set_unlit(material* mat_info, int texture, float alpha, bool blending, bool depth_testing)
{
mat_info->set_texture_map(TM_BASE_TYPE, texture);
gr_alpha_blend blend_mode = material_determine_blend_mode(texture, blending);
gr_zbuffer_type depth_mode = material_determine_depth_mode(depth_testing, blending);
mat_info->set_blend_mode(blend_mode);
mat_info->set_depth_mode(depth_mode);
mat_info->set_cull_mode(false);
mat_info->set_texture_source(TEXTURE_SOURCE_NO_FILTERING);
if ( blend_mode == ALPHA_BLEND_ADDITIVE ) {
mat_info->set_color(alpha, alpha, alpha, 1.0f);
} else {
mat_info->set_color(1.0f, 1.0f, 1.0f, alpha);
}
if ( texture >= 0 && bm_has_alpha_channel(texture) ) {
mat_info->set_texture_type(material::TEX_TYPE_XPARENT);
}
}
void material_set_unlit_emissive(material* mat_info, int texture, float alpha, float color_scale)
{
material_set_unlit(mat_info, texture, alpha, true, true);
mat_info->set_color_scale(color_scale);
}
void material_set_unlit_color(material* mat_info, int texture, color *clr, bool blending, bool depth_testing)
{
mat_info->set_texture_map(TM_BASE_TYPE, texture);
gr_alpha_blend blend_mode = material_determine_blend_mode(texture, blending);
gr_zbuffer_type depth_mode = material_determine_depth_mode(depth_testing, blending);
mat_info->set_blend_mode(blend_mode);
mat_info->set_depth_mode(depth_mode);
mat_info->set_cull_mode(false);
mat_info->set_texture_source(TEXTURE_SOURCE_NO_FILTERING);
mat_info->set_color(*clr);
}
void material_set_unlit_color(material* mat_info, int texture, color *clr, float alpha, bool blending, bool depth_testing)
{
color clr_with_alpha;
gr_init_alphacolor(&clr_with_alpha, clr->red, clr->green, clr->blue, fl2i(alpha * 255.0f));
material_set_unlit_color(mat_info, texture, &clr_with_alpha, blending, depth_testing);
}
void material_set_interface(material* mat_info, int texture, bool blended, float alpha)
{
mat_info->set_texture_map(TM_BASE_TYPE, texture);
mat_info->set_texture_type(material::TEX_TYPE_INTERFACE);
mat_info->set_blend_mode(material_determine_blend_mode(texture, blended));
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
mat_info->set_cull_mode(false);
mat_info->set_texture_source(TEXTURE_SOURCE_NO_FILTERING);
mat_info->set_color(1.0f, 1.0f, 1.0f, blended ? alpha : 1.0f);
}
void material_set_unlit_volume(particle_material* mat_info, int texture, bool point_sprites)
{
mat_info->set_point_sprite_mode(point_sprites);
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
mat_info->set_blend_mode(material_determine_blend_mode(texture, true));
mat_info->set_texture_map(TM_BASE_TYPE, texture);
mat_info->set_cull_mode(false);
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
}
void material_set_distortion(distortion_material *mat_info, int texture, bool thruster)
{
mat_info->set_thruster_rendering(thruster);
mat_info->set_depth_mode(ZBUFFER_TYPE_READ);
mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
mat_info->set_texture_map(TM_BASE_TYPE, texture);
mat_info->set_cull_mode(false);
mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
}
template <> SCP_vector<int>& uniform_data::get_array<int>() { return int_data; }
template <> SCP_vector<float>& uniform_data::get_array<float>() { return float_data; }
template <> SCP_vector<vec2d>& uniform_data::get_array<vec2d>() { return vec2_data; }
template <> SCP_vector<vec3d>& uniform_data::get_array<vec3d>() { return vec3_data; }
template <> SCP_vector<vec4>& uniform_data::get_array<vec4>() { return vec4_data; }
template <> SCP_vector<matrix4>& uniform_data::get_array<matrix4>() { return matrix4_data; }
template <> bool uniform_data::compare<int>(int index, const int& val)
{
return int_data[index] == val;
}
template <> bool uniform_data::compare<float>(int index, const float& val)
{
return fl_equal(float_data[index], val);
}
template <> bool uniform_data::compare<vec2d>(int index, const vec2d& val)
{
return vm_vec_equal(vec2_data[index], val);
}
template <> bool uniform_data::compare<vec3d>(int index, const vec3d& val)
{
return vm_vec_equal(vec3_data[index], val);
}
template <> bool uniform_data::compare<vec4>(int index, const vec4& val)
{
return vm_vec_equal(vec4_data[index], val);
}
template <> bool uniform_data::compare<matrix4>(int index, const matrix4& val)
{
return vm_matrix_equal(matrix4_data[index], val);
}
template <> bool uniform_data::compare<matrix4>(int index, matrix4* val, int count)
{
for (int i = 0; i < count; ++i) {
if (!vm_matrix_equal(matrix4_data[index + i], val[i])) {
return false;
}
}
return true;
}
template <> uniform::data_type uniform::determine_type<int>() { return INT; }
template <> uniform::data_type uniform::determine_type<float>() { return FLOAT; }
template <> uniform::data_type uniform::determine_type<vec2d>() { return VEC2; }
template <> uniform::data_type uniform::determine_type<vec3d>() { return VEC3; }
template <> uniform::data_type uniform::determine_type<vec4>() { return VEC4; }
template <> uniform::data_type uniform::determine_type<matrix4>() { return MATRIX4; }
material::material():
Sdr_handle(-1),
Sdr_type(SDR_TYPE_NONE),
Tex_source(TEXTURE_SOURCE_NO_FILTERING),
Tex_type(TEX_TYPE_NORMAL),
Texture_addressing(TMAP_ADDRESS_WRAP),
Depth_bias(0),
Depth_mode(ZBUFFER_TYPE_NONE),
Blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA),
Cull_mode(true),
Fill_mode(GR_FILL_MODE_SOLID),
Clr_scale(1.0f)
{
gr_init_alphacolor(&Clr, 255, 255, 255, 255);
Texture_maps[TM_BASE_TYPE] = -1;
Texture_maps[TM_GLOW_TYPE] = -1;
Texture_maps[TM_SPECULAR_TYPE] = -1;
Texture_maps[TM_NORMAL_TYPE] = -1;
Texture_maps[TM_HEIGHT_TYPE] = -1;
Texture_maps[TM_MISC_TYPE] = -1;
Texture_maps[TM_SPEC_GLOSS_TYPE] = -1;
Texture_maps[TM_AMBIENT_TYPE] = -1;
Fog_params.dist_near = -1.0f;
Fog_params.dist_far = -1.0f;
Fog_params.r = 0;
Fog_params.g = 0;
Fog_params.b = 0;
Fog_params.enabled = false;
Clip_params.enabled = false;
};
void material::set_shader_type(shader_type init_sdr_type)
{
Sdr_type = init_sdr_type;
}
void material::set_shader_handle(int handle)
{
Sdr_handle = handle;
}
int material::get_shader_handle()
{
return Sdr_handle;
}
void material::set_texture_map(int texture_type, int texture_num)
{
Assert(texture_type > -1 && texture_type < TM_NUM_TYPES);
Texture_maps[texture_type] = texture_num;
}
int material::get_texture_map(int texture_type)
{
Assert(texture_type > -1 && texture_type < TM_NUM_TYPES);
return Texture_maps[texture_type];
}
bool material::is_textured()
{
return
Texture_maps[TM_BASE_TYPE] > -1 ||
Texture_maps[TM_GLOW_TYPE] > -1 ||
Texture_maps[TM_SPECULAR_TYPE] > -1 ||
Texture_maps[TM_NORMAL_TYPE] > -1 ||
Texture_maps[TM_HEIGHT_TYPE] > -1 ||
Texture_maps[TM_MISC_TYPE] > -1;
}
void material::set_texture_type(texture_type t_type)
{
Tex_type = t_type;
}
int material::get_texture_type()
{
switch ( Tex_type ) {
default:
case TEX_TYPE_NORMAL:
return TCACHE_TYPE_NORMAL;
case TEX_TYPE_XPARENT:
return TCACHE_TYPE_XPARENT;
case TEX_TYPE_INTERFACE:
return TCACHE_TYPE_INTERFACE;
case TEX_TYPE_AABITMAP:
return TCACHE_TYPE_AABITMAP;
}
}
void material::set_texture_source(gr_texture_source source)
{
Tex_source = source;
}
gr_texture_source material::get_texture_source()
{
return Tex_source;
}
bool material::is_clipped()
{
return Clip_params.enabled;
}
void material::set_clip_plane(const vec3d &normal, const vec3d &position)
{
Clip_params.enabled = true;
Clip_params.normal = normal;
Clip_params.position = position;
}
void material::set_clip_plane()
{
Clip_params.enabled = false;
}
material::clip_plane& material::get_clip_plane()
{
return Clip_params;
}
void material::set_texture_addressing(int addressing)
{
Texture_addressing = addressing;
}
int material::get_texture_addressing()
{
return Texture_addressing;
}
void material::set_fog(int r, int g, int b, float near, float far)
{
Fog_params.enabled = true;
Fog_params.r = r;
Fog_params.g = g;
Fog_params.b = b;
Fog_params.dist_near = near;
Fog_params.dist_far = far;
}
void material::set_fog()
{
Fog_params.enabled = false;
}
bool material::is_fogged()
{
return Fog_params.enabled;
}
material::fog& material::get_fog()
{
return Fog_params;
}
void material::set_depth_mode(gr_zbuffer_type mode)
{
Depth_mode = mode;
}
gr_zbuffer_type material::get_depth_mode()
{
return Depth_mode;
}
void material::set_cull_mode(bool mode)
{
Cull_mode = mode;
}
bool material::get_cull_mode()
{
return Cull_mode;
}
void material::set_fill_mode(int mode)
{
Fill_mode = mode;
}
int material::get_fill_mode()
{
return Fill_mode;
}
void material::set_blend_mode(gr_alpha_blend mode)
{
Blend_mode = mode;
}
gr_alpha_blend material::get_blend_mode()
{
return Blend_mode;
}
void material::set_depth_bias(int bias)
{
Depth_bias = bias;
}
int material::get_depth_bias()
{
return Depth_bias;
}
void material::set_color(float red, float green, float blue, float alpha)
{
set_color(fl2i(red * 255.0f), fl2i(green * 255.0f), fl2i(blue * 255.0f), fl2i(alpha * 255.0f));
}
void material::set_color(int r, int g, int b, int a)
{
gr_init_alphacolor(&Clr, r, g, b, a);
}
void material::set_color(color &clr_in)
{
if ( clr_in.is_alphacolor ) {
Clr = clr_in;
} else {
gr_init_alphacolor(&Clr, clr_in.red, clr_in.green, clr_in.blue, 255);
}
}
color& material::get_color()
{
return Clr;
}
void material::set_color_scale(float scale)
{
Clr_scale = scale;
}
float material::get_color_scale()
{
return Clr_scale;
}
model_material::model_material():
material(),
Animated_effect(-1),
Animated_timer(0.0f),
Thrust_scale(-1.0f),
lighting(false),
Light_factor(1.0f),
Batched(false),
Team_color_set(false),
Center_alpha(0),
Desaturate(false),
Normal_alpha(false),
Normal_alpha_min(0.0f),
Normal_alpha_max(1.0f),
Normal_extrude(false),
Deferred(false),
HDR(false)
{
set_shader_type(SDR_TYPE_MODEL);
}
void model_material::set_desaturation(bool enabled)
{
Desaturate = enabled;
}
bool model_material::is_desaturated()
{
return Desaturate;
}
void model_material::set_shadow_casting(bool enabled)
{
Shadow_casting = enabled;
}
void model_material::set_light_factor(float factor)
{
Light_factor = factor;
}
float model_material::get_light_factor()
{
return Light_factor;
}
void model_material::set_lighting(bool mode)
{
lighting = mode;
}
bool model_material::is_lit()
{
return lighting;
}
void model_material::set_deferred_lighting(bool enabled)
{
Deferred = enabled;
}
void model_material::set_high_dynamic_range(bool enabled)
{
HDR = enabled;
}
void model_material::set_center_alpha(int c_alpha)
{
Center_alpha = c_alpha;
}
int model_material::get_center_alpha()
{
return Center_alpha;
}
void model_material::set_thrust_scale(float scale)
{
Thrust_scale = scale;
}
float model_material::get_thrust_scale()
{
return Thrust_scale;
}
void model_material::set_team_color(const team_color &color)
{
Team_color_set = true;
Tm_color = color;
}
void model_material::set_team_color()
{
Team_color_set = false;
}
team_color& model_material::get_team_color()
{
return Tm_color;
}
void model_material::set_animated_effect(int effect, float time)
{
Animated_effect = effect;
Animated_timer = time;
}
void model_material::set_animated_effect()
{
Animated_effect = 0;
Animated_timer = 0.0f;
}
int model_material::get_animated_effect()
{
return Animated_effect;
}
float model_material::get_animated_effect_time()
{
return Animated_timer;
}
void model_material::set_batching(bool enabled)
{
Batched = enabled;
}
bool model_material::is_batched()
{
return Batched;
}
void model_material::set_normal_alpha(float min, float max)
{
Normal_alpha = true;
Normal_alpha_min = min;
Normal_alpha_max = max;
}
void model_material::set_normal_alpha()
{
Normal_alpha = false;
}
bool model_material::is_normal_alpha_active()
{
return Normal_alpha;
}
float model_material::get_normal_alpha_min()
{
return Normal_alpha_min;
}
float model_material::get_normal_alpha_max()
{
return Normal_alpha_max;
}
void model_material::set_normal_extrude(float width)
{
Normal_extrude = true;
Normal_extrude_width = width;
}
void model_material::set_normal_extrude()
{
Normal_extrude = false;
}
bool model_material::is_normal_extrude_active()
{
return Normal_extrude;
}
float model_material::get_normal_extrude_width()
{
return Normal_extrude_width;
}
uint model_material::get_shader_flags()
{
uint Shader_flags = 0;
if ( is_clipped() ) {
Shader_flags |= SDR_FLAG_MODEL_CLIP;
}
if ( is_batched() ) {
Shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
}
if ( Shadow_casting ) {
// if we're building the shadow map, we likely only need the flags here and above so bail
Shader_flags |= SDR_FLAG_MODEL_SHADOW_MAP;
return Shader_flags;
}
if ( is_fogged() ) {
Shader_flags |= SDR_FLAG_MODEL_FOG;
}
if ( Animated_effect >= 0 ) {
Shader_flags |= SDR_FLAG_MODEL_ANIMATED;
}
if ( get_texture_map(TM_BASE_TYPE) > 0 && !Basemap_override ) {
Shader_flags |= SDR_FLAG_MODEL_DIFFUSE_MAP;
}
if ( get_texture_map(TM_GLOW_TYPE) > 0 ) {
Shader_flags |= SDR_FLAG_MODEL_GLOW_MAP;
}
if ( lighting ) {
Shader_flags |= SDR_FLAG_MODEL_LIGHT;
if ( ( get_texture_map(TM_SPECULAR_TYPE) > 0) && !Specmap_override ) {
Shader_flags |= SDR_FLAG_MODEL_SPEC_MAP;
if ( (ENVMAP > 0) && !Envmap_override ) {
Shader_flags |= SDR_FLAG_MODEL_ENV_MAP;
}
}
if ( (get_texture_map(TM_NORMAL_TYPE) > 0) && !Normalmap_override ) {
Shader_flags |= SDR_FLAG_MODEL_NORMAL_MAP;
}
if ( (get_texture_map(TM_HEIGHT_TYPE) > 0) && !Heightmap_override ) {
Shader_flags |= SDR_FLAG_MODEL_HEIGHT_MAP;
}
if ( Cmdline_shadow_quality && !Shadow_casting && !Shadow_override ) {
Shader_flags |= SDR_FLAG_MODEL_SHADOWS;
}
}
if ( get_texture_map(TM_MISC_TYPE) > 0 ) {
Shader_flags |= SDR_FLAG_MODEL_MISC_MAP;
if ( Team_color_set ) {
Shader_flags |= SDR_FLAG_MODEL_TEAMCOLOR;
}
}
if ( Deferred ) {
Shader_flags |= SDR_FLAG_MODEL_DEFERRED;
}
if ( HDR ) {
Shader_flags |= SDR_FLAG_MODEL_HDR;
}
if ( Thrust_scale > 0.0f ) {
Shader_flags |= SDR_FLAG_MODEL_THRUSTER;
}
if ( Normal_alpha ) {
Shader_flags |= SDR_FLAG_MODEL_NORMAL_ALPHA;
}
if ( Normal_extrude ) {
Shader_flags |= SDR_FLAG_MODEL_NORMAL_EXTRUDE;
}
return Shader_flags;
}
int model_material::get_shader_handle()
{
int handle = material::get_shader_handle();
if ( handle >= 0 ) {
return handle;
}
set_shader_handle(gr_maybe_create_shader(SDR_TYPE_MODEL, get_shader_flags()));
return material::get_shader_handle();
}
particle_material::particle_material():
material()
{
set_shader_type(SDR_TYPE_EFFECT_PARTICLE);
}
void particle_material::set_point_sprite_mode(bool enabled)
{
Point_sprite = enabled;
}
bool particle_material::get_point_sprite_mode()
{
return Point_sprite;
}
int particle_material::get_shader_handle()
{
int handle = material::get_shader_handle();
if ( handle >= 0 ) {
return handle;
}
uint flags = 0;
if ( Point_sprite ) {
flags |= SDR_FLAG_PARTICLE_POINT_GEN;
}
set_shader_handle(gr_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, flags));
return material::get_shader_handle();
}
distortion_material::distortion_material():
material()
{
set_shader_type(SDR_TYPE_EFFECT_DISTORTION);
}
void distortion_material::set_thruster_rendering(bool enabled)
{
Thruster_render = enabled;
}
bool distortion_material::get_thruster_rendering()
{
return Thruster_render;
}
int distortion_material::get_shader_handle()
{
int handle = material::get_shader_handle();
if ( handle >= 0 ) {
return handle;
}
set_shader_handle(gr_maybe_create_shader(SDR_TYPE_EFFECT_DISTORTION, 0));
return material::get_shader_handle();
}
+554
View File
@@ -0,0 +1,554 @@
#ifndef _MATERIAL_H
#define _MATERIAL_H
#include "graphics/grinternal.h"
#include "model/model.h"
struct uniform_data
{
// when adding a new data type to support, create a vector for it here
SCP_vector<int> int_data;
SCP_vector<float> float_data;
SCP_vector<vec2d> vec2_data;
SCP_vector<vec3d> vec3_data;
SCP_vector<vec4> vec4_data;
SCP_vector<matrix4> matrix4_data;
void clear()
{
int_data.clear();
float_data.clear();
vec2_data.clear();
vec3_data.clear();
vec4_data.clear();
matrix4_data.clear();
}
template <class T> SCP_vector<T>& get_array();
// add a single value to the data pool
template <class T> int set_value(const T& val)
{
SCP_vector<T>& data = get_array<T>();
data.push_back(val);
return (int)data.size() - 1;
}
// overwrite an existing single value to the data pool
template <class T> void set_value(int location, const T& val)
{
SCP_vector<T>& data = get_array<T>();
Assert(location < (int)data.size());
data[location] = val;
}
// add multiple values to the data pool
template <class T> int set_values(T* val, int size)
{
SCP_vector<T>& data = get_array<T>();
int start_index = data.size();
for ( int i = 0; i < size; i++ ) {
data.push_back(val[i]);
}
return start_index;
}
// overwrite multiple existing values to the data pool
template <class T> void set_values(int location, T* val, int size)
{
SCP_vector<T>& data = get_array<T>();
Assert(location < (int)data.size());
for (int i = 0; i < size; i++) {
// check to make sure we don't go out of bounds
if ( location + i < (int)data.size() ) {
data[location + i] = val[i];
} else {
data.push_back(val[i]);
}
}
}
template <class T> bool compare(int index, const T& val);
template <class T> bool compare(int index, T* val, int count);
};
struct uniform
{
SCP_string name;
enum data_type {
INT,
FLOAT,
VEC2,
VEC3,
VEC4,
MATRIX4
};
data_type type;
int index;
int count;
uniform_data *data_src;
uniform(): data_src(NULL)
{
}
uniform(uniform_data* _data_src):
data_src(_data_src)
{
}
void operator=(uniform& u)
{
name = u.name;
type = u.type;
index = u.index;
count = u.count;
data_src = u.data_src;
}
template <class T> static data_type determine_type();
template <class T>
void init(const SCP_string& init_name, const T& val)
{
name = init_name;
type = determine_type<T>();
count = 1;
index = data_src->set_value(val);
}
template <class T>
void init(const SCP_string &init_name, T* val, int size)
{
name = init_name;
type = determine_type<T>();
count = size;
index = data_src->set_values(val, size);
}
template <class T>
bool update(const T& val)
{
data_type uniform_type = determine_type<T>();
if ( uniform_type == type ) {
if ( count == 1 && data_src->compare(index, val) ) {
return false;
}
count = 1;
data_src->set_value(index, val);
return true;
}
count = 1;
uniform_type = type;
index = data_src->set_value(val);
return true;
}
template <class T>
bool update(T* val, int size)
{
data_type uniform_type = uniform::determine_type<T>();
if (uniform_type == type) {
if (count == size && data_src->compare(index, val, size)) {
return false;
}
if (count < size) {
// we're going to overflow so append instead of replace
count = size;
index = data_src->set_values(val, size);
} else {
count = size;
data_src->set_values(index, val, size);
}
return true;
}
count = size;
uniform_type = type;
index = data_src->set_values(val, size);
return true;
}
};
class uniform_block
{
SCP_vector<uniform> Uniforms;
uniform_data* Data_store;
bool Local_data_store;
int find_uniform(const SCP_string& name)
{
size_t count = Uniforms.size();
for (size_t i = 0; i < count; ++i) {
uniform& u = Uniforms[i];
if (u.name == name) {
return i;
}
}
return -1;
}
public:
uniform_block(uniform_data* data_store = NULL)
{
if (Data_store != NULL) {
Local_data_store = false;
} else {
// allocate our own data storage
Data_store = new uniform_data;
Local_data_store = true;
}
}
~uniform_block()
{
if (Local_data_store && Data_store != NULL) {
delete Data_store;
Data_store = NULL;
}
}
template <class T> bool set_value(const SCP_string& name, const T& val)
{
Assert(Data_store != NULL);
int index = find_uniform(name);
if (index >= 0) {
return Uniforms[index].update(val);
}
uniform u(Data_store);
u.init(name, val);
Uniforms.push_back(u);
return true;
}
template <class T> bool set_values(const SCP_string& name, T* val, int size)
{
Assert(Data_store != NULL);
int index = find_uniform(name);
if (index >= 0) {
return Uniforms[index].update(val, size);
}
uniform u(Data_store);
u.init(name, val, size);
Uniforms.push_back(u);
return true;
}
void invalidate_value(const SCP_string& name)
{
int index = find_uniform(name);
if ( index < 0 ) {
return;
}
Uniforms[index] = Uniforms.back();
Uniforms.pop_back();
}
int num_uniforms()
{
return (int)Uniforms.size();
}
uniform::data_type get_type(int i)
{
Assert(i < (int)Uniforms.size());
return Uniforms[i].type;
}
const SCP_string& get_name(int i)
{
Assert(i < (int)Uniforms.size());
return Uniforms[i].name;
}
template <class T> T& get_value(int i)
{
int index = Uniforms[i].index;
Assert(Data_store != NULL);
Assert(Uniforms[i].type == uniform::determine_type<T>());
SCP_vector<T>& data = Data_store->get_array<T>();
return data[index];
}
template <class T> T& get_value(int i, int offset)
{
int index = Uniforms[i].index;
Assert(Data_store != NULL);
Assert(Uniforms[i].type == uniform::determine_type<T>());
Assert(offset < Uniforms[i].count);
SCP_vector<T>& data = Data_store->get_array<T>();
Assert(index + offset < (int)data.size());
return data[index + offset];
}
};
class material
{
public:
struct fog
{
bool enabled;
int r;
int g;
int b;
float dist_near;
float dist_far;
};
struct clip_plane
{
bool enabled;
vec3d normal;
vec3d position;
};
enum texture_type {
TEX_TYPE_NORMAL,
TEX_TYPE_XPARENT,
TEX_TYPE_AABITMAP,
TEX_TYPE_INTERFACE
};
private:
shader_type Sdr_type;
int Sdr_handle;
int Texture_maps[TM_NUM_TYPES];
texture_type Tex_type;
gr_texture_source Tex_source;
clip_plane Clip_params;
int Texture_addressing;
fog Fog_params;
gr_zbuffer_type Depth_mode;
gr_alpha_blend Blend_mode;
bool Cull_mode;
int Fill_mode;
color Clr;
float Clr_scale;
int Depth_bias;
protected:
void set_shader_type(shader_type init_sdr_type = SDR_TYPE_NONE);
public:
material();
void set_shader_handle(int handle);
virtual int get_shader_handle();
void set_texture_map(int texture_type, int texture_num);
int get_texture_map(int texture_type);
bool is_textured();
void set_texture_type(texture_type t_type);
int get_texture_type();
void set_texture_source(gr_texture_source source);
gr_texture_source get_texture_source();
bool is_clipped();
void set_clip_plane(const vec3d &normal, const vec3d &position);
void set_clip_plane();
clip_plane& get_clip_plane();
void set_texture_addressing(int addressing);
int get_texture_addressing();
void set_fog(int r, int g, int b, float near, float far);
void set_fog();
bool is_fogged();
fog& get_fog();
void set_depth_mode(gr_zbuffer_type mode);
gr_zbuffer_type get_depth_mode();
void set_cull_mode(bool mode);
bool get_cull_mode();
void set_fill_mode(int mode);
int get_fill_mode();
void set_blend_mode(gr_alpha_blend mode);
gr_alpha_blend get_blend_mode();
void set_depth_bias(int bias);
int get_depth_bias();
void set_color(float red, float green, float blue, float alpha);
void set_color(int r, int g, int b, int a);
void set_color(color &clr_in);
color& get_color();
void set_color_scale(float scale);
float get_color_scale();
};
class model_material : public material
{
bool Desaturate;
bool Shadow_casting;
bool Batched;
bool Deferred;
bool HDR;
bool lighting;
float Light_factor;
int Center_alpha;
int Animated_effect;
float Animated_timer;
float Thrust_scale;
bool Team_color_set;
team_color Tm_color;
bool Normal_alpha;
float Normal_alpha_min;
float Normal_alpha_max;
bool Normal_extrude;
float Normal_extrude_width;
public:
model_material();
void set_desaturation(bool enabled);
bool is_desaturated();
void set_shadow_casting(bool enabled);
bool is_shadow_casting();
void set_light_factor(float factor);
float get_light_factor();
void set_lighting(bool mode);
bool is_lit();
void set_deferred_lighting(bool enabled);
void set_high_dynamic_range(bool enabled);
void set_center_alpha(int center_alpha);
int get_center_alpha();
void set_thrust_scale(float scale = -1.0f);
float get_thrust_scale();
void set_team_color(const team_color &color);
void set_team_color();
team_color& get_team_color();
void set_animated_effect(int effect, float time);
void set_animated_effect();
int get_animated_effect();
float get_animated_effect_time();
void set_normal_alpha(float min, float max);
void set_normal_alpha();
bool is_normal_alpha_active();
float get_normal_alpha_min();
float get_normal_alpha_max();
void set_normal_extrude(float width);
void set_normal_extrude();
bool is_normal_extrude_active();
float get_normal_extrude_width();
void set_batching(bool enabled);
bool is_batched();
uint get_shader_flags();
virtual int get_shader_handle();
};
class particle_material : public material
{
bool Point_sprite;
public:
particle_material();
void set_point_sprite_mode(bool enabled);
bool get_point_sprite_mode();
virtual int get_shader_handle();
};
class distortion_material: public material
{
bool Thruster_render;
public:
distortion_material();
void set_thruster_rendering(bool enabled);
bool get_thruster_rendering();
virtual int get_shader_handle();
};
gr_alpha_blend material_determine_blend_mode(int base_bitmap, bool is_transparent);
gr_zbuffer_type material_determine_depth_mode(bool depth_testing, bool is_transparent);
void material_set_interface(material* mat_info, int texture, bool blended, float alpha);
void material_set_unlit(material* mat_info, int texture, float alpha, bool blending, bool depth_testing);
void material_set_unlit_emissive(material* mat_info, int texture, float alpha, float color_scale);
void material_set_unlit_color(material* mat_info, int texture, color *clr, bool blending, bool depth_testing);
void material_set_unlit_color(material* mat_info, int texture, color *clr, float alpha, bool blending, bool depth_testing);
void material_set_unlit_volume(particle_material* mat_info, int texture, bool point_sprites);
void material_set_distortion(distortion_material *mat_info, int texture, bool thruster);
#endif
+12 -6
View File
@@ -11,7 +11,8 @@
#include "nanovg/nanovg.h"
// NanoVG supports OpenGL 2 and 3, we currently use OpenGL 2
#define NANOVG_GL2_IMPLEMENTATION
//#define NANOVG_GL2_IMPLEMENTATION
#define NANOVG_GL3_IMPLEMENTATION
#include "nanovg/nanovg_gl.h"
#pragma GCC diagnostic pop
@@ -42,15 +43,16 @@ namespace
GL_state.Texture.SetTarget(0);
GL_state.Texture.DisableAll();
if ( GL_version >= 30 ) {
glBindVertexArray(GL_vao);
}
GL_state.Array.BindArrayBuffer(0);
GL_state.Array.BindUniformBuffer(0);
opengl_shader_set_current(nullptr);
GL_state.Uniform.reset();
// State that is not currently tracked by FSO:
// glBindVertexArray(arr);
// Now reset the values to what we need
GL_state.SetStencilType(STENCIL_TYPE_NONE);
GL_state.StencilTest(GL_FALSE);
@@ -68,14 +70,14 @@ namespace graphics
{
NVGRenderer::NVGRenderer() : m_inFrame(false)
{
m_context = nvgCreateGL2(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
m_context = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
}
NVGRenderer::~NVGRenderer()
{
if (m_context)
{
nvgDeleteGL2(m_context);
nvgDeleteGL3(m_context);
m_context = nullptr;
}
}
@@ -96,6 +98,10 @@ namespace graphics
void NVGRenderer::endFrame()
{
if ( GL_version >= 30 ) {
glBindVertexArray(0);
}
gr_opengl_set_2d_matrix();
nvgEndFrame(m_context);
+18 -9
View File
@@ -177,14 +177,23 @@ void shadows_debug_show_frustum(matrix* orient, vec3d *pos, float fov, float asp
vm_vec_add2(&far_bottom_left, pos);
gr_set_color(0, 255, 255);
g3_draw_htl_line(&near_bottom_left, &near_bottom_right);
g3_draw_htl_line(&near_bottom_right, &near_top_right);
g3_draw_htl_line(&near_bottom_right, &near_top_left);
g3_draw_htl_line(&near_top_right, &near_top_left);
g3_draw_htl_line(&far_top_left, &far_top_right);
g3_draw_htl_line(&far_top_right, &far_bottom_right);
g3_draw_htl_line(&far_bottom_right, &far_bottom_left);
g3_draw_htl_line(&far_bottom_left, &far_top_left);
// g3_draw_htl_line(&near_bottom_left, &near_bottom_right);
// g3_draw_htl_line(&near_bottom_right, &near_top_right);
// g3_draw_htl_line(&near_bottom_right, &near_top_left);
// g3_draw_htl_line(&near_top_right, &near_top_left);
// g3_draw_htl_line(&far_top_left, &far_top_right);
// g3_draw_htl_line(&far_top_right, &far_bottom_right);
// g3_draw_htl_line(&far_bottom_right, &far_bottom_left);
// g3_draw_htl_line(&far_bottom_left, &far_top_left);
g3_render_line_3d(true, &near_bottom_left, &near_bottom_right);
g3_render_line_3d(true, &near_bottom_right, &near_top_right);
g3_render_line_3d(true, &near_bottom_right, &near_top_left);
g3_render_line_3d(true, &near_top_right, &near_top_left);
g3_render_line_3d(true, &far_top_left, &far_top_right);
g3_render_line_3d(true, &far_top_right, &far_bottom_right);
g3_render_line_3d(true, &far_bottom_right, &far_bottom_left);
g3_render_line_3d(true, &far_bottom_left, &far_top_left);
}
void shadows_construct_light_frustum(light_frustum_info *shadow_data, matrix *light_matrix, matrix *orient, vec3d *pos, float fov, float aspect, float z_near, float z_far)
@@ -467,7 +476,7 @@ void shadows_render_all(float fov, matrix *eye_orient, vec3d *eye_pos)
}
scene.init_render();
scene.render_all(GR_ZBUFF_FULL);
scene.render_all(ZBUFFER_TYPE_FULL);
shadows_end_render();
+2 -1
View File
@@ -874,7 +874,8 @@ void HudGaugeShield::renderShieldIcon(coord2d coords[6])
coords[i].y += ny;
}
gr_shield_icon(coords);
//gr_shield_icon(coords);
g3_render_shield_icon(coords);
gr_reset_screen_scale();
}
+20 -15
View File
@@ -2879,24 +2879,32 @@ void hud_tri(float x1,float y1,float x2,float y2,float x3,float y3)
for (i=0; i<3; i++)
gr_resize_screen_posf(&verts[i].screen.xyw.x, &verts[i].screen.xyw.y);
uint saved_mode = gr_zbuffer_get();
int cull = gr_set_cull(0);
//uint saved_mode = gr_zbuffer_get();
//int cull = gr_set_cull(0);
gr_zbuffer_set( GR_ZBUFF_NONE );
//gr_zbuffer_set( GR_ZBUFF_NONE );
//gr_tmapper( 3, vertlist, TMAP_FLAG_TRILIST );
g3_draw_poly_constant_sw(3, vertlist, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_ALPHA, 0.1f);
material material_def;
gr_zbuffer_set( saved_mode );
gr_set_cull(cull);
material_def.set_blend_mode(ALPHA_BLEND_NONE);
material_def.set_depth_mode(ZBUFFER_TYPE_NONE);
material_def.set_texture_source(TEXTURE_SOURCE_NONE);
material_def.set_cull_mode(false);
g3_render_primitives_colored(&material_def, verts, 3, PRIM_TYPE_TRIFAN, true);
//g3_draw_poly_constant_sw(3, vertlist, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_ALPHA, 0.1f);
//gr_zbuffer_set( saved_mode );
//gr_set_cull(cull);
}
void hud_tri_empty(float x1,float y1,float x2,float y2,float x3,float y3)
{
gr_line(fl2i(x1),fl2i(y1),fl2i(x2),fl2i(y2));
gr_line(fl2i(x2),fl2i(y2),fl2i(x3),fl2i(y3));
gr_line(fl2i(x3),fl2i(y3),fl2i(x1),fl2i(y1));
gr_line(fl2i(x1),fl2i(y1),fl2i(x2),fl2i(y2));
gr_line(fl2i(x2),fl2i(y2),fl2i(x3),fl2i(y3));
gr_line(fl2i(x3),fl2i(y3),fl2i(x1),fl2i(y1));
}
HudGaugeReticleTriangle::HudGaugeReticleTriangle():
@@ -7160,11 +7168,9 @@ void HudGaugeHardpoints::render(float frametime)
gr_set_color_buffer(1);
gr_stencil_set(GR_STENCIL_READ);
gr_set_cull(cull);
gr_set_line_width(_line_width*2.0f);
//model_set_alpha( gr_screen.current_color.alpha / 255.0f );
//model_set_forced_texture(0);
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_NO_ZBUFFER | MR_NO_CULL);
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_NO_ZBUFFER | MR_NO_CULL);
render_info.set_normal_extrude_width(_line_width * 0.01f);
model_render_immediate(
&render_info,
@@ -7175,7 +7181,6 @@ void HudGaugeHardpoints::render(float frametime)
gr_stencil_set(GR_STENCIL_NONE);
gr_zbuffer_set(zbuffer);
gr_set_line_width(1.0f);
// draw weapon models
int i, k;
+18 -11
View File
@@ -27,6 +27,7 @@
#include "object/objectsnd.h"
#include "playerman/managepilot.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "species_defs/species_defs.h"
#include "weapon/beam.h"
@@ -1045,9 +1046,9 @@ void labviewer_render_model(float frametime)
Glowpoint_override = gpo_save;
}
batch_render_all();
batching_render_all();
gr_copy_effect_texture();
batch_render_distortion_map_bitmaps();
batching_render_distortions_all();
gr_end_view_matrix();
gr_end_proj_matrix();
@@ -1138,7 +1139,7 @@ void labviewer_render_bitmap(float frametime)
// draw the primary laser bitmap
gr_set_color_fast(&wip->laser_color_1);
//gr_set_color_fast(&wip->laser_color_1);
if (wip->laser_bitmap.num_frames > 1) {
current_frame += frametime;
@@ -1149,10 +1150,13 @@ void labviewer_render_bitmap(float frametime)
vec3d headp;
vm_vec_scale_add(&headp, &vmd_zero_vector, &Lab_viewer_orient.vec.fvec, wip->laser_length);
gr_set_bitmap(wip->laser_bitmap.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
if(wip->laser_length > 0.0001f)
g3_draw_laser(&headp, wip->laser_head_radius, &vmd_zero_vector, wip->laser_tail_radius, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(wip->laser_bitmap.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
if(wip->laser_length > 0.0001f) {
//g3_draw_laser(&headp, wip->laser_head_radius, &vmd_zero_vector, wip->laser_tail_radius, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit_color(&mat_params, wip->laser_bitmap.first_frame + framenum, &wip->laser_color_1, true, true);
g3_render_laser(&mat_params, &headp, wip->laser_head_radius, &vmd_zero_vector, wip->laser_tail_radius);
}
// now draw the laser glow bitmap, if there is one, and if we are supposed to
if ( !(Lab_model_flags & MR_NO_GLOWMAPS) && (wip->laser_glow_bitmap.first_frame >= 0) ) {
@@ -1201,9 +1205,13 @@ void labviewer_render_bitmap(float frametime)
CLAMP(framenum, 0, wip->laser_glow_bitmap.num_frames-1);
}
gr_set_bitmap(wip->laser_glow_bitmap.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, weapon_glow_alpha);
if(wip->laser_length > 0.0001f)
g3_draw_laser_rgb(&headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r, c.red, c.green, c.blue, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(wip->laser_glow_bitmap.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, weapon_glow_alpha);
if(wip->laser_length > 0.0001f) {
//g3_draw_laser_rgb(&headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r, c.red, c.green, c.blue, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit_color(&mat_params, wip->laser_glow_bitmap.first_frame + framenum, &c, weapon_glow_alpha, true, false);
g3_render_laser(&mat_params, &headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r);
}
}
// clean up and move on ...
@@ -1813,7 +1821,6 @@ void labviewer_make_render_options_window(Button *caller)
ADD_RENDER_FLAG("Show Damage Lightning", Lab_viewer_flags, LAB_FLAG_LIGHTNING_ARCS);
ADD_RENDER_FLAG("Rotate Subsystems", Lab_viewer_flags, LAB_FLAG_SUBMODEL_ROTATE);
if (is_minimum_GLSL_version()) {
ADD_RENDER_BOOL("Fixed Render Pipeline", GLSL_override);
if (Cmdline_postprocess) {
ADD_RENDER_BOOL("Hide Post Processing", PostProcessing_override);
ADD_RENDER_BOOL("Use FXAA", Cmdline_fxaa);
+3 -5
View File
@@ -1237,8 +1237,6 @@ bool scene_lights::setLights(const light_indexing_info *info)
gr_reset_lighting();
gr_set_lighting(true, true);
for ( size_t i = 0; i < StaticLightIndices.size(); ++i) {
auto light_index = StaticLightIndices[i];
@@ -1247,7 +1245,7 @@ bool scene_lights::setLights(const light_indexing_info *info)
extern bool Deferred_lighting;
if ( Deferred_lighting ) {
opengl_change_active_lights(0);
gr_set_lighting(true, true);
return false;
}
@@ -1256,7 +1254,7 @@ bool scene_lights::setLights(const light_indexing_info *info)
// check if there are any lights to actually set
if ( num_lights <= 0 ) {
opengl_change_active_lights(0);
gr_set_lighting(true, true);
return false;
}
@@ -1270,7 +1268,7 @@ bool scene_lights::setLights(const light_indexing_info *info)
gr_set_light(&AllLights[light_index]);
}
opengl_change_active_lights(0);
gr_set_lighting(true, true);
return true;
}
+1
View File
@@ -10,6 +10,7 @@
#ifndef _STATIC_RAND_H
#define _STATIC_RAND_H
#include "globalincs/pstypes.h"
+122
View File
@@ -22,6 +22,7 @@
#define CONVERT_RADIANS 0.017453 // conversion factor from degrees to radians
vec3d vmd_zero_vector = ZERO_VECTOR;
vec3d vmd_scale_identity_vector = SCALE_IDENTITY_VECTOR;
vec3d vmd_x_vector = { { { 1.0f, 0.0f, 0.0f } } };
vec3d vmd_y_vector = { { { 0.0f, 1.0f, 0.0f } } };
vec3d vmd_z_vector = { { { 0.0f, 0.0f, 1.0f } } };
@@ -2723,3 +2724,124 @@ bool vm_inverse_matrix4(const matrix4 *m, matrix4 *invOut)
return true;
}
void vm_matrix4_set_identity(matrix4 *out)
{
out->a2d[0][0] = 1.0f;
out->a2d[0][1] = 0.0f;
out->a2d[0][2] = 0.0f;
out->a2d[0][3] = 0.0f;
out->a2d[1][0] = 0.0f;
out->a2d[1][1] = 1.0f;
out->a2d[1][2] = 0.0f;
out->a2d[1][3] = 0.0f;
out->a2d[2][0] = 0.0f;
out->a2d[2][1] = 0.0f;
out->a2d[2][2] = 1.0f;
out->a2d[2][3] = 0.0f;
out->a2d[3][0] = 0.0f;
out->a2d[3][1] = 0.0f;
out->a2d[3][2] = 0.0f;
out->a2d[3][3] = 1.0f;
}
void vm_matrix4_set_transform(matrix4 *out, matrix *m, vec3d *v)
{
vm_matrix4_set_identity(out);
out->a2d[0][0] = m->a2d[0][0];
out->a2d[0][1] = m->a2d[0][1];
out->a2d[0][2] = m->a2d[0][2];
out->a2d[1][0] = m->a2d[1][0];
out->a2d[1][1] = m->a2d[1][1];
out->a2d[1][2] = m->a2d[1][2];
out->a2d[2][0] = m->a2d[2][0];
out->a2d[2][1] = m->a2d[2][1];
out->a2d[2][2] = m->a2d[2][2];
out->a2d[3][0] = v->a1d[0];
out->a2d[3][1] = v->a1d[1];
out->a2d[3][2] = v->a1d[2];
}
void vm_matrix4_get_orientation(matrix *out, matrix4 *m)
{
out->a2d[0][0] = m->a2d[0][0];
out->a2d[0][1] = m->a2d[0][1];
out->a2d[0][2] = m->a2d[0][2];
out->a2d[1][0] = m->a2d[1][0];
out->a2d[1][1] = m->a2d[1][1];
out->a2d[1][2] = m->a2d[1][2];
out->a2d[2][0] = m->a2d[2][0];
out->a2d[2][1] = m->a2d[2][1];
out->a2d[2][2] = m->a2d[2][2];
}
void vm_matrix4_get_offset(vec3d *out, matrix4 *m)
{
out->xyz.x = m->vec.pos.xyzw.x;
out->xyz.y = m->vec.pos.xyzw.y;
out->xyz.z = m->vec.pos.xyzw.z;
}
void vm_matrix4_x_matrix4(matrix4 *dest, const matrix4 *src0, const matrix4 *src1)
{
dest->vec.rvec.xyzw.x = vm_vec4_dot4(src0->vec.rvec.xyzw.x, src0->vec.uvec.xyzw.x, src0->vec.fvec.xyzw.x, src0->vec.pos.xyzw.x, &src1->vec.rvec);
dest->vec.uvec.xyzw.x = vm_vec4_dot4(src0->vec.rvec.xyzw.x, src0->vec.uvec.xyzw.x, src0->vec.fvec.xyzw.x, src0->vec.pos.xyzw.x, &src1->vec.uvec);
dest->vec.fvec.xyzw.x = vm_vec4_dot4(src0->vec.rvec.xyzw.x, src0->vec.uvec.xyzw.x, src0->vec.fvec.xyzw.x, src0->vec.pos.xyzw.x, &src1->vec.fvec);
dest->vec.pos.xyzw.x = vm_vec4_dot4(src0->vec.rvec.xyzw.x, src0->vec.uvec.xyzw.x, src0->vec.fvec.xyzw.x, src0->vec.pos.xyzw.x, &src1->vec.pos);
dest->vec.rvec.xyzw.y = vm_vec4_dot4(src0->vec.rvec.xyzw.y, src0->vec.uvec.xyzw.y, src0->vec.fvec.xyzw.y, src0->vec.pos.xyzw.y, &src1->vec.rvec);
dest->vec.uvec.xyzw.y = vm_vec4_dot4(src0->vec.rvec.xyzw.y, src0->vec.uvec.xyzw.y, src0->vec.fvec.xyzw.y, src0->vec.pos.xyzw.y, &src1->vec.uvec);
dest->vec.fvec.xyzw.y = vm_vec4_dot4(src0->vec.rvec.xyzw.y, src0->vec.uvec.xyzw.y, src0->vec.fvec.xyzw.y, src0->vec.pos.xyzw.y, &src1->vec.fvec);
dest->vec.pos.xyzw.y = vm_vec4_dot4(src0->vec.rvec.xyzw.y, src0->vec.uvec.xyzw.y, src0->vec.fvec.xyzw.y, src0->vec.pos.xyzw.y, &src1->vec.pos);
dest->vec.rvec.xyzw.z = vm_vec4_dot4(src0->vec.rvec.xyzw.z, src0->vec.uvec.xyzw.z, src0->vec.fvec.xyzw.z, src0->vec.pos.xyzw.z, &src1->vec.rvec);
dest->vec.uvec.xyzw.z = vm_vec4_dot4(src0->vec.rvec.xyzw.z, src0->vec.uvec.xyzw.z, src0->vec.fvec.xyzw.z, src0->vec.pos.xyzw.z, &src1->vec.uvec);
dest->vec.fvec.xyzw.z = vm_vec4_dot4(src0->vec.rvec.xyzw.z, src0->vec.uvec.xyzw.z, src0->vec.fvec.xyzw.z, src0->vec.pos.xyzw.z, &src1->vec.fvec);
dest->vec.pos.xyzw.z = vm_vec4_dot4(src0->vec.rvec.xyzw.z, src0->vec.uvec.xyzw.z, src0->vec.fvec.xyzw.z, src0->vec.pos.xyzw.z, &src1->vec.pos);
dest->vec.rvec.xyzw.w = vm_vec4_dot4(src0->vec.rvec.xyzw.w, src0->vec.uvec.xyzw.w, src0->vec.fvec.xyzw.w, src0->vec.pos.xyzw.w, &src1->vec.rvec);
dest->vec.uvec.xyzw.w = vm_vec4_dot4(src0->vec.rvec.xyzw.w, src0->vec.uvec.xyzw.w, src0->vec.fvec.xyzw.w, src0->vec.pos.xyzw.w, &src1->vec.uvec);
dest->vec.fvec.xyzw.w = vm_vec4_dot4(src0->vec.rvec.xyzw.w, src0->vec.uvec.xyzw.w, src0->vec.fvec.xyzw.w, src0->vec.pos.xyzw.w, &src1->vec.fvec);
dest->vec.pos.xyzw.w = vm_vec4_dot4(src0->vec.rvec.xyzw.w, src0->vec.uvec.xyzw.w, src0->vec.fvec.xyzw.w, src0->vec.pos.xyzw.w, &src1->vec.pos);
}
float vm_vec4_dot4(float x, float y, float z, float w, const vec4 *v)
{
return (x * v->xyzw.x) + (y * v->xyzw.y) + (z * v->xyzw.z) + (w * v->xyzw.w);
}
void vm_vec_transform(vec4 *dest, vec4 *src, matrix4 *m)
{
dest->xyzw.x = (m->vec.rvec.xyzw.x * src->xyzw.x) + (m->vec.uvec.xyzw.x * src->xyzw.y) + (m->vec.fvec.xyzw.x * src->xyzw.z) + (m->vec.pos.xyzw.x * src->xyzw.w);
dest->xyzw.y = (m->vec.rvec.xyzw.y * src->xyzw.x) + (m->vec.uvec.xyzw.y * src->xyzw.y) + (m->vec.fvec.xyzw.y * src->xyzw.z) + (m->vec.pos.xyzw.y * src->xyzw.w);
dest->xyzw.z = (m->vec.rvec.xyzw.z * src->xyzw.x) + (m->vec.uvec.xyzw.z * src->xyzw.y) + (m->vec.fvec.xyzw.z * src->xyzw.z) + (m->vec.pos.xyzw.z * src->xyzw.w);
dest->xyzw.w = (m->vec.rvec.xyzw.w * src->xyzw.x) + (m->vec.uvec.xyzw.w * src->xyzw.y) + (m->vec.fvec.xyzw.w * src->xyzw.z) + (m->vec.pos.xyzw.w * src->xyzw.w);
}
void vm_vec_transform(vec3d *dest, vec3d *src, matrix4 *m, bool pos)
{
vec4 temp_src, temp_dest;
temp_src.xyzw.x = src->xyz.x;
temp_src.xyzw.y = src->xyz.y;
temp_src.xyzw.z = src->xyz.z;
// whether to treat vec3d src as a position or a vector.
// 0.0f will prevent matrix4 m's offset from being added. 1.0f will add the offset.
temp_src.xyzw.w = pos ? 1.0f : 0.0f;
vm_vec_transform(&temp_dest, &temp_src, m);
dest->xyz.x = temp_dest.xyzw.x;
dest->xyz.y = temp_dest.xyzw.y;
dest->xyz.z = temp_dest.xyzw.z;
}
+15
View File
@@ -50,6 +50,7 @@ extern void vm_set_identity(matrix *m);
//Global constants
extern vec3d vmd_zero_vector;
extern vec3d vmd_scale_identity_vector;
extern vec3d vmd_x_vector;
extern vec3d vmd_y_vector;
extern vec3d vmd_z_vector;
@@ -58,6 +59,7 @@ extern matrix vmd_identity_matrix;
//Here's a handy constant
#define ZERO_VECTOR { { { 0.0f, 0.0f, 0.0f } } }
#define SCALE_IDENTITY_VECTOR { { { 1.0f, 1.0f, 1.0f } } }
//#define IDENTITY_MATRIX {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}
// first set of inside braces is for union, second set is for inside union, then for a2d[3][3] (some compiler warning messages just suck)
//#define IDENTITY_MATRIX { { { {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f} } } }
@@ -432,6 +434,19 @@ void vm_vec_boxscale(vec2d *vec, float scale);
bool vm_inverse_matrix4(const matrix4 *m, matrix4 *invOut);
void vm_matrix4_set_identity(matrix4 *out);
void vm_matrix4_set_transform(matrix4 *out, matrix *m, vec3d *v);
void vm_matrix4_get_orientation(matrix *out, matrix4 *m);
void vm_vec_transform(vec4 *dest, vec4 *src, matrix4 *m);
void vm_vec_transform(vec3d *dest, vec3d *src, matrix4 *m, bool pos = true);
void vm_matrix4_x_matrix4(matrix4 *dest, const matrix4 *src0, const matrix4 *src1);
float vm_vec4_dot4(float x, float y, float z, float w, const vec4 *v);
#endif
+2 -1
View File
@@ -26,6 +26,7 @@
#include "parse/parselo.h"
#include "playerman/player.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "sound/fsspeech.h"
#include "ui/ui.h"
@@ -586,7 +587,7 @@ void techroom_ships_render(float frametime)
Glowpoint_use_depth_buffer = true;
batch_render_all();
batching_render_all();
gr_end_view_matrix();
gr_end_proj_matrix();
+11 -6
View File
@@ -43,6 +43,7 @@
#include "parse/sexp.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "ui/uidefs.h"
#include "weapon/weapon.h"
@@ -1728,7 +1729,8 @@ void draw_model_rotating(model_render_params *render_info, int model_id, int x1,
stop.xyz.x = -size*start_scale;
stop.xyz.y = 0.0f;
stop.xyz.z = -clip;
g3_draw_htl_line(&start,&stop);
//g3_draw_htl_line(&start,&stop);
g3_render_line_3d(true, &start, &stop);
}
g3_done_instance(true);
@@ -1749,7 +1751,8 @@ void draw_model_rotating(model_render_params *render_info, int model_id, int x1,
for (i = -3; i < 4; i++) {
start.xyz.x = stop.xyz.x = size*0.333f*i;
g3_draw_htl_line(&start,&stop);
//g3_draw_htl_line(&start,&stop);
g3_render_line_3d(false, &start, &stop);
}
start.xyz.x = size;
@@ -1759,7 +1762,8 @@ void draw_model_rotating(model_render_params *render_info, int model_id, int x1,
start.xyz.z = stop.xyz.z = size*0.333f*i+offset*0.5f;
if ((time < 1.5f) && (start.xyz.z <= -clip))
break;
g3_draw_htl_line(&start,&stop);
//g3_draw_htl_line(&start,&stop);
g3_render_line_3d(false, &start, &stop);
}
g3_done_instance(true);
@@ -1835,14 +1839,15 @@ void draw_model_rotating(model_render_params *render_info, int model_id, int x1,
stop.xyz.y = 0.0f;
stop.xyz.z = -clip;
g3_start_instance_angles(&vmd_zero_vector,&view_angles);
g3_draw_htl_line(&start,&stop);
//g3_draw_htl_line(&start,&stop);
g3_render_line_3d(false, &start, &stop);
g3_done_instance(true);
}
}
gr_zbuffer_set(GR_ZBUFF_FULL); // Turn off depthbuffer again
batch_render_all();
batching_render_all();
Glowpoint_use_depth_buffer = true; // Back to normal
gr_end_view_matrix();
@@ -1924,7 +1929,7 @@ void draw_model_rotating(model_render_params *render_info, int model_id, int x1,
model_render_immediate(render_info, model_id, &model_orient, &vmd_zero_vector);
batch_render_all();
batching_render_all();
gr_end_view_matrix();
gr_end_proj_matrix();
+2 -1
View File
@@ -37,6 +37,7 @@
#include "parse/parselo.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "weapon/weapon.h"
@@ -914,7 +915,7 @@ void wl_render_overhead_view(float frametime)
Glowpoint_use_depth_buffer = true;
batch_render_all();
batching_render_all();
//NOW render the lines for weapons
gr_reset_clip();
+6 -1
View File
@@ -709,7 +709,7 @@ public:
n_thrusters(0), gun_banks(NULL), missile_banks(NULL), docking_bays(NULL), thrusters(NULL), ship_bay(NULL),
shield_collision_tree(NULL), sldc_size(0), n_paths(0), paths(NULL), mass(0), num_xc(0), xc(NULL), num_split_plane(0),
num_ins(0), used_this_mission(0), n_glow_point_banks(0), glow_point_banks(NULL), gun_submodel_rotation(0),
vertex_buffer_id(-1)
vertex_buffer_id(-1), vert_source()
{
filename[0] = 0;
mins = maxs = autocenter = center_of_mass = vmd_zero_vector;
@@ -818,6 +818,8 @@ public:
int vertex_buffer_id; // HTL vertex buffer id
indexed_vertex_source vert_source;
vertex_buffer detail_buffers[MAX_MODEL_DETAIL_LEVELS];
};
@@ -1357,6 +1359,9 @@ void model_draw_bay_paths(int model_num);
void model_draw_bay_paths_htl(int model_num);
bool model_interp_config_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb, bool update_ibuffer_only);
bool model_interp_pack_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb);
void glowpoint_init();
SCP_vector<glow_point_bank_override>::iterator get_glowpoint_bank_override_by_name(const char* name);
extern SCP_vector<glow_point_bank_override> glowpoint_bank_overrides;
+270 -16
View File
@@ -901,11 +901,12 @@ void model_draw_paths_htl( int model_num, uint flags )
gr_set_color( 255, 0, 0 );
}
g3_draw_htl_sphere(&pnt, 0.5f);
g3_render_sphere(&pnt, 0.5f);
if (j)
{
g3_draw_htl_line(&prev_pnt, &pnt);
//g3_draw_htl_line(&prev_pnt, &pnt);
g3_render_line_3d(true, &prev_pnt, &pnt);
}
prev_pnt = pnt;
@@ -937,8 +938,9 @@ void model_draw_bay_paths_htl(int model_num)
vm_vec_scale_add(&v2, &v1, &pm->docking_bays[idx].norm[s_idx], 10.0f);
// draw the point and normal
g3_draw_htl_sphere(&v1, 2.0);
g3_draw_htl_line(&v1, &v2);
g3_render_sphere(&v1, 2.0);
//g3_draw_htl_line(&v1, &v2);
g3_render_line_3d(true, &v1, &v2);
}
}
@@ -952,7 +954,8 @@ void model_draw_bay_paths_htl(int model_num)
v1 = pm->paths[idx].verts[s_idx].pos;
v2 = pm->paths[idx].verts[s_idx+1].pos;
g3_draw_htl_line(&v1, &v2);
//g3_draw_htl_line(&v1, &v2);
g3_render_line_3d(true, &v1, &v2);
}
}
}
@@ -2286,6 +2289,160 @@ void find_sortnorm(int offset, ubyte *bsp_data)
if (postlist) find_tri_counts(offset+postlist, bsp_data);
}
void model_interp_submit_buffers(indexed_vertex_source *vert_src)
{
Assert(vert_src != NULL);
if ( !(vert_src->Vertex_list_size > 0 && vert_src->Index_list_size > 0 ) ) {
return;
}
bool static_buffer = true;
vert_src->Vbuffer_handle = gr_create_vertex_buffer(static_buffer);
if ( vert_src->Vbuffer_handle > -1 && vert_src->Vertex_list != NULL ) {
gr_update_buffer_data(vert_src->Vbuffer_handle, vert_src->Vertex_list_size, vert_src->Vertex_list);
vm_free(vert_src->Vertex_list);
vert_src->Vertex_list = NULL;
}
vert_src->Ibuffer_handle = gr_create_index_buffer(static_buffer);
if ( vert_src->Ibuffer_handle > -1 && vert_src->Index_list != NULL ) {
gr_update_buffer_data(vert_src->Ibuffer_handle, vert_src->Index_list_size, vert_src->Index_list);
vm_free(vert_src->Index_list);
vert_src->Index_list = NULL;
}
}
bool model_interp_pack_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb)
{
if ( vert_src == NULL ) {
return false;
}
// NULL means that we are done with the buffer and can create the IBO/VBO
// returns false here only for some minor error prevention
if ( vb == NULL ) {
model_interp_submit_buffers(vert_src);
return false;
}
int i, n_verts = 0;
size_t j;
uint arsize = 0;
if ( vert_src->Vertex_list == NULL ) {
vert_src->Vertex_list = (float*)vm_malloc(vert_src->Vertex_list_size);
// return invalid if we don't have the memory
if ( vert_src->Vertex_list == NULL ) {
return false;
}
memset(vert_src->Vertex_list, 0, vert_src->Vertex_list_size);
}
if ( vert_src->Index_list == NULL ) {
vert_src->Index_list = (ubyte*)vm_malloc(vert_src->Index_list_size);
// return invalid if we don't have the memory
if ( vert_src->Index_list == NULL ) {
return false;
}
memset(vert_src->Index_list, 0, vert_src->Index_list_size);
}
// bump to our index in the array
float *array = vert_src->Vertex_list + (vb->vertex_offset / sizeof(float));
// generate the vertex array
n_verts = vb->model_list->n_verts;
for ( i = 0; i < n_verts; i++ ) {
vertex *vl = &vb->model_list->vert[i];
// don't try to generate more data than what's available
Assert(((arsize * sizeof(float)) + vb->stride) <= (vert_src->Vertex_list_size - vb->vertex_offset));
// NOTE: UV->NORM->TSB->MODEL_ID->VERT, This array order *must* be preserved!!
// tex coords
if ( vb->flags & VB_FLAG_UV1 ) {
array[arsize++] = vl->texture_position.u;
array[arsize++] = vl->texture_position.v;
} else {
array[arsize++] = 1.0f;
array[arsize++] = 1.0f;
}
// normals
if ( vb->flags & VB_FLAG_NORMAL ) {
Assert(vb->model_list->norm != NULL);
vec3d *nl = &vb->model_list->norm[i];
array[arsize++] = nl->xyz.x;
array[arsize++] = nl->xyz.y;
array[arsize++] = nl->xyz.z;
} else {
array[arsize++] = 0.0f;
array[arsize++] = 0.0f;
array[arsize++] = 1.0f;
}
// tangent space data
if ( vb->flags & VB_FLAG_TANGENT ) {
Assert(vb->model_list->tsb != NULL);
tsb_t *tsb = &vb->model_list->tsb[i];
array[arsize++] = tsb->tangent.xyz.x;
array[arsize++] = tsb->tangent.xyz.y;
array[arsize++] = tsb->tangent.xyz.z;
array[arsize++] = tsb->scaler;
} else {
array[arsize++] = 1.0f;
array[arsize++] = 0.0f;
array[arsize++] = 0.0f;
array[arsize++] = 0.0f;
}
if ( vb->flags & VB_FLAG_MODEL_ID ) {
Assert(vb->model_list->submodels != NULL);
array[arsize++] = (float)vb->model_list->submodels[i];
} else {
array[arsize++] = 0.0f;
}
// verts
array[arsize++] = vl->world.xyz.x;
array[arsize++] = vl->world.xyz.y;
array[arsize++] = vl->world.xyz.z;
}
// generate the index array
for ( j = 0; j < vb->tex_buf.size(); j++ ) {
buffer_data* tex_buf = &vb->tex_buf[j];
n_verts = tex_buf->n_verts;
uint offset = tex_buf->index_offset;
const uint *index = tex_buf->get_index();
// bump to our spot in the buffer
ubyte *ibuf = vert_src->Index_list + offset;
if ( vb->tex_buf[j].flags & VB_FLAG_LARGE_INDEX ) {
memcpy(ibuf, index, n_verts * sizeof(uint));
} else {
ushort *mybuf = (ushort*)ibuf;
for ( i = 0; i < n_verts; i++ ) {
mybuf[i] = (ushort)index[i];
}
}
}
return true;
}
void interp_pack_vertex_buffers(polymodel *pm, int mn)
{
Assert( pm->vertex_buffer_id >= 0 );
@@ -2297,10 +2454,10 @@ void interp_pack_vertex_buffers(polymodel *pm, int mn)
return;
}
bool rval = gr_pack_buffer(pm->vertex_buffer_id, &model->buffer);
bool rval = model_interp_pack_buffer(&pm->vert_source, &model->buffer);
if ( model->trans_buffer.flags & VB_FLAG_TRANS && model->trans_buffer.tex_buf.size() > 0 ) {
gr_pack_buffer(pm->vertex_buffer_id, &model->trans_buffer);
model_interp_pack_buffer(&pm->vert_source, &model->trans_buffer);
}
if ( !rval ) {
@@ -2308,6 +2465,97 @@ void interp_pack_vertex_buffers(polymodel *pm, int mn)
}
}
void model_interp_set_buffer_layout(vertex_layout *layout, uint stride, int flags)
{
Assert(layout != NULL);
uint offset = 0;
// NOTE: UV->NORM->TSB->MODEL_ID->VERT, This array order *must* be preserved!!
if ( flags & VB_FLAG_UV1 ) {
layout->add_vertex_component(vertex_format_data::TEX_COORD, stride, offset);
}
offset += (2 * sizeof(float));
if ( flags & VB_FLAG_NORMAL ) {
layout->add_vertex_component(vertex_format_data::NORMAL, stride, offset);
}
offset += (3 * sizeof(float));
if ( flags & VB_FLAG_TANGENT ) {
layout->add_vertex_component(vertex_format_data::TANGENT, stride, offset);
}
offset += (4 * sizeof(float));
if ( flags & VB_FLAG_MODEL_ID ) {
layout->add_vertex_component(vertex_format_data::MODEL_ID, stride, offset);
}
offset += (1 * sizeof(float));
Assert(flags & VB_FLAG_POSITION);
layout->add_vertex_component(vertex_format_data::POSITION3, stride, offset);
offset += (3 * sizeof(float));
}
bool model_interp_config_buffer(indexed_vertex_source *vert_src, vertex_buffer *vb, bool update_ibuffer_only)
{
if ( vb == NULL ) {
return false;
}
if ( !(vb->flags & VB_FLAG_POSITION) ) {
Int3();
return false;
}
vb->stride = 0;
// pad out the vertex buffer even if it doesn't use certain attributes
// we require consistent stride across vertex buffers so we can use base vertex offsetting for performance reasons
// uv coords
vb->stride += (2 * sizeof(float));
// normals
vb->stride += (3 * sizeof(float));
// tangent space data for normal maps (shaders only)
vb->stride += (4 * sizeof(float));
// model ID for batched submodel rendering (shaders only)
vb->stride += (1 * sizeof(float));
// position
vb->stride += (3 * sizeof(float));
model_interp_set_buffer_layout(&vb->layout, vb->stride, vb->flags);
// offsets for this chunk
if ( !update_ibuffer_only ) {
vb->vertex_offset = vert_src->Vertex_list_size;
vb->vertex_num_offset = vb->vertex_offset / vb->stride;
vert_src->Vertex_list_size += vb->stride * vb->model_list->n_verts;
}
for ( size_t idx = 0; idx < vb->tex_buf.size(); idx++ ) {
buffer_data *bd = &vb->tex_buf[idx];
bd->index_offset = vert_src->Index_list_size;
vert_src->Index_list_size += bd->n_verts * ((bd->flags & VB_FLAG_LARGE_INDEX) ? sizeof(uint) : sizeof(ushort));
// even out index buffer so we are always word aligned
vert_src->Index_list_size += vert_src->Index_list_size % sizeof(uint);
}
return true;
}
void interp_configure_vertex_buffers(polymodel *pm, int mn)
{
int i, j, first_index;
@@ -2323,6 +2571,8 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
tri_count[i] = 0;
}
int milliseconds = timer_get_milliseconds();
bsp_polygon_data *bsp_polies = new bsp_polygon_data(model->bsp_data);
for (i = 0; i < MAX_MODEL_TEXTURES; i++) {
@@ -2336,7 +2586,7 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
polygon_list[i].n_verts = vert_count;
// set submodel ID
if ( GLSL_version >= 130 ) {
if ( GLSL_version >= 150 ) {
for ( j = 0; j < polygon_list[i].n_verts; ++j ) {
polygon_list[i].submodels[j] = mn;
}
@@ -2361,6 +2611,10 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
// done with the bsp now that we have the vertex data
delete bsp_polies;
int time_elapsed = timer_get_milliseconds() - milliseconds;
mprintf(("BSP Parse took %d milliseconds.", time_elapsed));
if (total_verts < 1) {
return;
}
@@ -2392,7 +2646,7 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
memcpy( (model_list->tsb) + model_list->n_verts, polygon_list[i].tsb, sizeof(tsb_t) * polygon_list[i].n_verts );
}
if ( GLSL_version >= 130 ) {
if ( GLSL_version >= 150 ) {
memcpy( (model_list->submodels) + model_list->n_verts, polygon_list[i].submodels, sizeof(int) * polygon_list[i].n_verts );
}
@@ -2412,7 +2666,7 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
}
if ( model_list->submodels != NULL ) {
Assert( GLSL_version >= 130 );
Assert( GLSL_version >= 150 );
vertex_flags |= VB_FLAG_MODEL_ID;
}
@@ -2444,7 +2698,7 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
model->buffer.tex_buf.push_back( new_buffer );
}
bool rval = gr_config_buffer(pm->vertex_buffer_id, &model->buffer, false);
bool rval = model_interp_config_buffer(&pm->vert_source, &model->buffer, false);
if ( !rval ) {
Error( LOCATION, "Unable to configure vertex buffer for '%s'\n", pm->filename );
@@ -2457,7 +2711,7 @@ void interp_copy_index_buffer(vertex_buffer *src, vertex_buffer *dest, size_t *i
size_t src_buff_size;
buffer_data *src_buffer;
buffer_data *dest_buffer;
auto vert_offset = src->vertex_offset / src->stride; // assuming all submodels crunched into this index buffer have the same stride
size_t vert_offset = src->vertex_num_offset; // assuming all submodels crunched into this index buffer have the same stride
//int vert_offset = 0;
for ( i = 0; i < dest->tex_buf.size(); ++i ) {
@@ -2492,6 +2746,7 @@ void interp_fill_detail_index_buffer(SCP_vector<int> &submodel_list, polymodel *
}
buffer->vertex_offset = 0;
buffer->vertex_num_offset = 0;
buffer->model_list = new(std::nothrow) poly_list;
int num_buffers;
@@ -2565,15 +2820,13 @@ void interp_create_detail_index_buffer(polymodel *pm, int detail_num)
}
interp_fill_detail_index_buffer(submodel_list, pm, &pm->detail_buffers[detail_num]);
//interp_fill_detail_index_buffer(submodel_list, pm, &pm->trans_buff[detail_num]);
// check if anything was even put into this buffer
if ( pm->detail_buffers[detail_num].tex_buf.size() < 1 ) {
return;
}
gr_config_buffer(pm->vertex_buffer_id, &pm->detail_buffers[detail_num], true);
//gr_config_buffer(pm->vertex_buffer_id, &pm->trans_buff[detail_num], true);
model_interp_config_buffer(&pm->vert_source, &pm->detail_buffers[detail_num], true);
}
void interp_create_transparency_index_buffer(polymodel *pm, int mn)
@@ -2586,6 +2839,7 @@ void interp_create_transparency_index_buffer(polymodel *pm, int mn)
trans_buffer->model_list = new(std::nothrow) poly_list;
trans_buffer->vertex_offset = pm->submodel[mn].buffer.vertex_offset;
trans_buffer->vertex_num_offset = pm->submodel[mn].buffer.vertex_num_offset;
trans_buffer->stride = pm->submodel[mn].buffer.stride;
trans_buffer->flags = pm->submodel[mn].buffer.flags;
@@ -2680,7 +2934,7 @@ void interp_create_transparency_index_buffer(polymodel *pm, int mn)
}
if ( trans_buffer->flags & VB_FLAG_TRANS ) {
gr_config_buffer(pm->vertex_buffer_id, trans_buffer, true);
model_interp_config_buffer(&pm->vert_source, trans_buffer, true);
}
}
+27 -4
View File
@@ -299,6 +299,29 @@ void model_unload(int modelnum, int force)
vm_free(pm->shield_collision_tree);
}
if ( pm->vert_source.Vbuffer_handle > -1 ) {
gr_delete_buffer(pm->vert_source.Vbuffer_handle);
pm->vert_source.Vbuffer_handle = -1;
}
if ( pm->vert_source.Vertex_list != NULL ) {
vm_free(pm->vert_source.Vertex_list);
pm->vert_source.Vertex_list = NULL;
}
if ( pm->vert_source.Ibuffer_handle > -1 ) {
gr_delete_buffer(pm->vert_source.Ibuffer_handle);
pm->vert_source.Ibuffer_handle = -1;
}
if ( pm->vert_source.Index_list != NULL ) {
vm_free(pm->vert_source.Index_list);
pm->vert_source.Index_list = NULL;
}
pm->vert_source.Vertex_list_size = 0;
pm->vert_source.Index_list_size = 0;
for (i = 0; i < MAX_MODEL_DETAIL_LEVELS; ++i) {
pm->detail_buffers[i].clear();
}
@@ -876,7 +899,7 @@ void create_vertex_buffer(polymodel *pm)
bool use_batched_rendering = true;
if ( GLSL_version >= 130 && !Cmdline_no_batching ) {
if ( GLSL_version >= 150 && !Cmdline_no_batching ) {
size_t stride = 0;
// figure out if the vertex stride of this entire model matches. if not, turn off batched rendering for this model
@@ -917,7 +940,7 @@ void create_vertex_buffer(polymodel *pm)
continue;
}
gr_pack_buffer(pm->vertex_buffer_id, &pm->detail_buffers[i]);
model_interp_pack_buffer(&pm->vert_source, &pm->detail_buffers[i]);
pm->detail_buffers[i].release();
}
@@ -925,7 +948,7 @@ void create_vertex_buffer(polymodel *pm)
}
// ... and then finalize buffer
gr_pack_buffer(pm->vertex_buffer_id, NULL);
model_interp_pack_buffer(&pm->vert_source, NULL);
}
// Goober5000
@@ -2581,7 +2604,7 @@ void model_load_texture(polymodel *pm, int i, char *file)
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT);
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_FOG);
if( !Cmdline_no_batching && GLSL_version >= 130 ) {
if( !Cmdline_no_batching && GLSL_version >= 150 ) {
shader_flags &= ~SDR_FLAG_MODEL_DEFERRED;
shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
+363 -511
View File
File diff suppressed because it is too large. Load diff
+48 -129
View File
@@ -11,6 +11,7 @@
#define _MODELRENDER_H
#include "graphics/gropengltnl.h"
#include "graphics/material.h"
#include "lighting/lighting.h"
#include "math/vecmat.h"
#include "model/model.h"
@@ -51,13 +52,28 @@ inline int in_sphere(vec3d *pos, float radius, vec3d *view_pos)
extern int model_interp_get_texture(texture_info *tinfo, fix base_frametime);
struct transform
struct transform_old
{
matrix basis;
vec3d origin;
transform(): basis(vmd_identity_matrix), origin(vmd_zero_vector) {}
transform(matrix *m, vec3d *v): basis(*m), origin(*v) {}
transform_old(): basis(vmd_identity_matrix), origin(vmd_zero_vector) {}
transform_old(matrix *m, vec3d *v): basis(*m), origin(*v) {}
matrix4 get_matrix4()
{
matrix4 new_mat;
new_mat.a1d[0] = basis.vec.rvec.xyz.x; new_mat.a1d[4] = basis.vec.uvec.xyz.x; new_mat.a1d[8] = basis.vec.fvec.xyz.x;
new_mat.a1d[1] = basis.vec.rvec.xyz.y; new_mat.a1d[5] = basis.vec.uvec.xyz.y; new_mat.a1d[9] = basis.vec.fvec.xyz.y;
new_mat.a1d[2] = basis.vec.rvec.xyz.z; new_mat.a1d[6] = basis.vec.uvec.xyz.z; new_mat.a1d[10] = basis.vec.fvec.xyz.z;
new_mat.a1d[12] = origin.xyz.x;
new_mat.a1d[13] = origin.xyz.y;
new_mat.a1d[14] = origin.xyz.z;
new_mat.a1d[15] = 1.0f;
return new_mat;
}
};
class model_render_params
@@ -96,6 +112,13 @@ class model_render_params
float Animated_timer;
mst_info Thruster_info;
bool Normal_alpha;
float Normal_alpha_min;
float Normal_alpha_max;
bool Normal_extrude;
float Normal_extrude_width;
public:
model_render_params();
@@ -116,9 +139,13 @@ public:
void set_clip_plane(vec3d &pos, vec3d &normal);
void set_animated_effect(int effect_num, float timer);
void set_thruster_info(mst_info &info);
void set_normal_alpha(float min, float max);
void set_normal_extrude_width(float width);
bool is_clip_plane_set();
bool is_team_color_set();
bool is_normal_alpha_set();
bool is_normal_extrude_set();
uint get_model_flags();
uint get_debug_flags();
@@ -139,12 +166,9 @@ public:
int get_animated_effect_num();
float get_animated_effect_timer();
const mst_info& get_thruster_info();
};
struct clip_plane_state
{
vec3d normal;
vec3d point;
float get_normal_alpha_min();
float get_normal_alpha_max();
float get_normal_extrude_width();
};
struct arc_effect
@@ -165,106 +189,30 @@ struct insignia_draw_data
int bitmap_num;
// if there's a clip plane
int clip_plane;
};
struct render_state
{
int clip_plane_handle;
int texture_addressing;
int fill_mode;
int cull_mode;
int center_alpha;
int zbias;
int buffer_id;
float animated_timer;
int animated_effect;
bool lighting;
light_indexing_info lights;
float light_factor;
float thrust_scale;
bool using_team_color;
team_color tm_color;
color clr;
// fog state maybe shouldn't belong here. if we have fog, then it's probably occurring for all objects in scene.
int fog_mode;
int r;
int g;
int b;
float fog_near;
float fog_far;
render_state()
{
clip_plane_handle = -1;
texture_addressing = TMAP_ADDRESS_WRAP;
fill_mode = GR_FILL_MODE_SOLID;
buffer_id = -1;
lighting = false;
fog_mode = GR_FOGMODE_NONE;
r = 0;
g = 0;
b = 0;
fog_near = -1.0f;
fog_far = -1.0f;
lights.index_start = 0;
lights.num_lights = 0;
light_factor = 1.0f;
animated_timer = 0.0f;
animated_effect = 0;
thrust_scale = -1.0f;
gr_init_color(&clr, 255, 255, 255);
}
bool clip;
vec3d clip_normal;
vec3d clip_position;
};
struct queued_buffer_draw
{
int render_state_handle;
int texture_maps[TM_NUM_TYPES];
size_t transform_buffer_offset;
color clr;
int blend_filter;
float alpha;
int depth_mode;
model_material render_material;
transform transformation;
vec3d scale;
indexed_vertex_source *vert_src;
vertex_buffer *buffer;
size_t texi;
int flags;
int sdr_flags;
float thrust_scale;
light_indexing_info lights;
queued_buffer_draw()
{
depth_mode = GR_ZBUFF_FULL;
texture_maps[TM_BASE_TYPE] = -1;
texture_maps[TM_UNLIT_TYPE] = -1;
texture_maps[TM_GLOW_TYPE] = -1;
texture_maps[TM_HEIGHT_TYPE] = -1;
texture_maps[TM_MISC_TYPE] = -1;
texture_maps[TM_NORMAL_TYPE] = -1;
texture_maps[TM_SPECULAR_TYPE] = -1;
texture_maps[TM_SPEC_GLOSS_TYPE] = -1;
texture_maps[TM_AMBIENT_TYPE] = -1;
thrust_scale = 0.0f;
}
};
@@ -306,27 +254,14 @@ class draw_list
vec3d Current_scale;
SCP_vector<transform> Transform_stack;
render_state Current_render_state;
bool Dirty_render_state;
scene_lights Scene_light_handler;
int Current_textures[TM_NUM_TYPES];
int Current_blend_filter;
float Current_alpha;
int Current_depth_mode;
int Current_set_clip_plane;
light_indexing_info Current_lights_set;
void render_arc(arc_effect &arc);
void render_insignia(insignia_draw_data &insignia_info);
void render_outline(outline_draw &outline_info);
void render_buffer(queued_buffer_draw &render_elements);
uint determine_shader_flags(render_state *state, queued_buffer_draw *draw_info, vertex_buffer *buffer, int tmap_flags);
SCP_vector<clip_plane_state> Clip_planes;
SCP_vector<render_state> Render_states;
SCP_vector<queued_buffer_draw> Render_elements;
SCP_vector<int> Render_keys;
@@ -341,30 +276,10 @@ public:
draw_list();
void init();
void reset_state();
void set_clip_plane(const vec3d &position, const vec3d &normal);
void set_clip_plane();
void set_thrust_scale(float scale = -1.0f);
void set_texture(int texture_type, int texture_handle);
void set_depth_mode(int depth_set);
void set_blend_filter(int filter, float alpha);
void set_texture_addressing(int addressing);
void set_fog(int fog_mode, int r, int g, int b, float fog_near = -1.0f, float fog_far = -1.0f);
void set_fill_mode(int mode);
void set_cull_mode(int mode);
void set_zbias(int bias);
void set_center_alpha(int center_alpha);
void set_lighting(bool mode);
void set_buffer(int buffer);
void set_team_color(const team_color &clr);
void set_team_color();
void set_color(const color &clr);
void set_animated_timer(float time);
void set_animated_effect(int effect);
void add_submodel_to_batch(int model_num);
void start_model_batch(int n_models);
void add_buffer_draw(vertex_buffer *buffer, size_t texi, uint tmap_flags, model_render_params *interp);
void add_buffer_draw(model_material *render_material, indexed_vertex_source *vert_src, vertex_buffer *buffer, size_t texi, uint tmap_flags);
vec3d get_view_position();
void clear_transforms();
@@ -375,17 +290,16 @@ public:
void add_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
void render_arcs();
void add_insignia(polymodel *pm, int detail_level, int bitmap_num);
void add_insignia(model_render_params *params, polymodel *pm, int detail_level, int bitmap_num);
void render_insignias();
void add_outline(vertex* vert_array, int n_verts, color *clr);
void render_outlines();
void set_light_filter(int objnum, vec3d *pos, float rad);
void set_light_factor(float factor);
void init_render(bool sort = true);
void render_all(int depth_mode = -1);
void render_all(gr_zbuffer_type depth_mode = ZBUFFER_TYPE_DEFAULT);
void reset();
};
@@ -401,10 +315,15 @@ void model_render_immediate(model_render_params *render_info, int model_num, mat
void model_render_queue(model_render_params *render_info, draw_list* scene, int model_num, matrix *orient, vec3d *pos);
void submodel_render_immediate(model_render_params *render_info, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void submodel_render_queue(model_render_params *render_info, draw_list *scene, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void model_render_buffers(draw_list* scene, model_render_params* interp, vertex_buffer *buffer, polymodel *pm, int mn, int detail_level, uint tmap_flags);
void model_render_buffers(draw_list* scene, model_material *rendering_material, model_render_params* interp, vertex_buffer *buffer, polymodel *pm, int mn, int detail_level, uint tmap_flags);
void model_render_set_thrust(model_render_params *interp, int model_num, mst_info *mst);
void model_render_set_clip_plane(model_render_params *interp, vec3d *pos = NULL, vec3d *normal = NULL);
fix model_render_determine_base_frametime(int objnum, uint flags);
bool model_render_check_detail_box(vec3d *view_pos, polymodel *pm, int submodel_num, uint flags);
void model_render_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
void model_render_insignias(insignia_draw_data *insignia);
void model_render_determine_color(color *clr, float alpha, gr_alpha_blend blend_mode, bool no_texturing, bool desaturate);
gr_alpha_blend model_render_determine_blend_mode(int base_bitmap, bool blending);
#endif
+11 -7
View File
@@ -944,6 +944,7 @@ void neb2_render_player()
}
memset(&p, 0, sizeof(p));
memset(&ptemp, 0, sizeof(ptemp));
// get eye position and orientation
neb2_get_eye_pos(&eye_pos);
@@ -1036,10 +1037,10 @@ void neb2_render_player()
continue;
}
// rotate and project the vertex into viewspace
g3_rotate_vertex(&p, &Neb2_cubes[idx1][idx2][idx3].pt);
g3_transfer_vertex(&p, &Neb2_cubes[idx1][idx2][idx3].pt);
ptemp = p;
// rotate and project the vertex into viewspace
g3_rotate_vertex(&ptemp, &Neb2_cubes[idx1][idx2][idx3].pt);
g3_project_vertex(&ptemp);
// get the proper alpha value
@@ -1073,12 +1074,15 @@ void neb2_render_player()
}
// set the bitmap and render
gr_set_bitmap(Neb2_cubes[idx1][idx2][idx3].bmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, (alpha + Neb2_cubes[idx1][idx2][idx3].flash));
//gr_set_bitmap(Neb2_cubes[idx1][idx2][idx3].bmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, (alpha + Neb2_cubes[idx1][idx2][idx3].flash));
gr_set_lighting(false, false);
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
g3_draw_rotated_bitmap(&p, fl_radians(Neb2_cubes[idx1][idx2][idx3].rot), Nd->prad, TMAP_FLAG_TEXTURED);
}
//gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
//g3_draw_rotated_bitmap(&p, fl_radians(Neb2_cubes[idx1][idx2][idx3].rot), Nd->prad, TMAP_FLAG_TEXTURED);
material mat_params;
material_set_unlit(&mat_params, Neb2_cubes[idx1][idx2][idx3].bmap, alpha + Neb2_cubes[idx1][idx2][idx3].flash, true, true);
g3_render_rect_screen_aligned_rotated(&mat_params, &p, fl_radians(Neb2_cubes[idx1][idx2][idx3].rot), Nd->prad);
}
}
}
+7 -8
View File
@@ -19,6 +19,7 @@
#include "nebula/neblightning.h"
#include "network/multi.h"
#include "network/multimsgs.h"
#include "graphics/material.h"
#include "parse/parselo.h"
#include "render/3d.h"
#include "weapon/emp.h"
@@ -868,9 +869,10 @@ void nebl_render_section(bolt_type *bi, l_section *a, l_section *b)
vertex v[4];
vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]};
// Sets mode. Returns previous mode.
gr_zbuffer_set(GR_ZBUFF_FULL);
material material_params;
material_set_unlit_emissive(&material_params, bi->texture, Nebl_alpha, 2.0f);
// draw some stuff
for(size_t idx=0; idx<2; idx++){
v[0] = a->vex[idx];
@@ -886,8 +888,7 @@ void nebl_render_section(bolt_type *bi, l_section *a, l_section *b)
v[3].texture_position.u = 0.0f; v[3].texture_position.v = 1.0f;
// draw
gr_set_bitmap(bi->texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, Nebl_alpha);
g3_draw_poly(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE);
g3_render_primitives_textured(&material_params, v, 4, PRIM_TYPE_TRIFAN, false);
}
// draw
@@ -903,8 +904,7 @@ void nebl_render_section(bolt_type *bi, l_section *a, l_section *b)
v[3] = b->vex[2];
v[3].texture_position.u = 0.0f; v[3].texture_position.v = 1.0f;
gr_set_bitmap(bi->texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, Nebl_alpha);
g3_draw_poly(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE);
g3_render_primitives_textured(&material_params, v, 4, PRIM_TYPE_TRIFAN, false);
// draw the glow beam
verts[0] = &a->glow_vex[0];
@@ -919,8 +919,7 @@ void nebl_render_section(bolt_type *bi, l_section *a, l_section *b)
verts[3] = &b->glow_vex[0];
verts[3]->texture_position.v = 0.0f; verts[3]->texture_position.u = 1.0f;
gr_set_bitmap(bi->glow, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, Nebl_glow_alpha);
g3_draw_poly(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE);
g3_render_primitives_textured(&material_params, v, 4, PRIM_TYPE_TRIFAN, false);
}
// generate a section
+7 -6
View File
@@ -24,6 +24,7 @@
#include "object/object.h"
#include "parse/scripting.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "weapon/weapon.h"
@@ -384,7 +385,7 @@ void obj_render_queue_all()
scene.init_render();
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_FULL));
PROFILE("Submit Draws", scene.render_all(ZBUFFER_TYPE_FULL));
gr_zbuffer_set(ZBUFFER_TYPE_READ);
gr_zbias(0);
gr_set_cull(0);
@@ -402,8 +403,8 @@ void obj_render_queue_all()
gr_set_lighting(false, false);
// now render transparent meshes
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_READ));
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_NONE));
PROFILE("Submit Draws", scene.render_all(ZBUFFER_TYPE_READ));
PROFILE("Submit Draws", scene.render_all(ZBUFFER_TYPE_NONE));
// render electricity effects and insignias
scene.render_outlines();
@@ -422,15 +423,15 @@ void obj_render_queue_all()
gr_set_lighting(false, false);
//WMC - draw maneuvering thrusters
extern void batch_render_man_thrusters();
batch_render_man_thrusters();
//extern void batch_render_man_thrusters();
//batch_render_man_thrusters();
// if we're fullneb, switch off the fog effet
if((The_mission.flags[Mission::Mission_Flags::Fullneb]) && (Neb2_render_mode != NEB2_RENDER_NONE)){
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
}
PROFILE("Draw Effects", batch_render_all());
PROFILE("Draw Effects", batching_render_all());
gr_zbias(0);
gr_zbuffer_set(ZBUFFER_TYPE_READ);
+1 -1
View File
@@ -12,12 +12,12 @@
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "debugconsole/console.h"
#include "graphics/2d.h"
#include "graphics/grinternal.h"
#include "palman/palman.h"
#include "parse/parselo.h"
#include "pcxutils/pcxutils.h"
#define SQUARE(x) ((x)*(x))
#define NUM_BLEND_TABLES 3
+5 -2
View File
@@ -13797,8 +13797,11 @@ ADE_FUNC(drawPolygon, l_Graphics, "texture Texture, [vector Position={0,0,0}, or
if(!in_frame)
g3_start_frame(0);
gr_set_bitmap(tdx, lua_Opacity_type, GR_BITBLT_MODE_NORMAL, lua_Opacity);
g3_draw_polygon(&pos, orip, width, height, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(tdx, lua_Opacity_type, GR_BITBLT_MODE_NORMAL, lua_Opacity);
//g3_draw_polygon(&pos, orip, width, height, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit(&mat_params, tdx, lua_Opacity, lua_Opacity_type == GR_ALPHABLEND_FILTER ? true : false, false);
g3_render_rect_oriented(&mat_params, &pos, orip, width, height);
if(!in_frame)
g3_end_frame();
+10 -13
View File
@@ -17,8 +17,10 @@
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "graphics/grbatch.h"
#include "render/3d.h"
#include "object/object.h"
#include "particle/particle.h"
#include "render/3d.h"
#include "render/batching.h"
#include <glad/glad.h>
@@ -101,15 +103,12 @@ namespace particle
}
// grab a vertex buffer object
if (Particle_buffer_object < 0)
{
Particle_buffer_object = gr_create_stream_buffer();
if ( Particle_buffer_object < 0 ) {
Particle_buffer_object = gr_create_vertex_buffer();
}
if (Geometry_shader_buffer_object < 0 && !Cmdline_no_geo_sdr_effects &&
GLAD_GL_ARB_geometry_shader4)
{
Geometry_shader_buffer_object = gr_create_stream_buffer();
if ( Geometry_shader_buffer_object < 0 && !Cmdline_no_geo_sdr_effects && GLAD_GL_ARB_geometry_shader4 ) {
Geometry_shader_buffer_object = gr_create_vertex_buffer();
}
}
@@ -426,8 +425,7 @@ namespace particle
Assert( cur_frame < part->nframes );
batch_add_bitmap( framenum + cur_frame, tmap_flags | TMAP_FLAG_VERTEX_GEN, &pos,
part->particle_index % 8, part->radius, alpha );
batching_add_volume_bitmap(framenum + cur_frame, &pos, part->particle_index % 8, part->radius, alpha);
render_batch = true;
}
@@ -436,8 +434,7 @@ namespace particle
profile_begin("Batch Render");
if (render_batch)
{
geometry_batch_render(Geometry_shader_buffer_object);
batch_render_all(Particle_buffer_object);
batching_render_all();
}
profile_end("Batch Render");
}
+40 -17
View File
@@ -161,8 +161,11 @@ void HudGaugeRadarDradis::drawContact(vec3d *pnt, int idx, int clr_idx, float di
aspect_mp = (((float) h) / ((float) w));
}
gr_set_bitmap(clr_idx, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha);
g3_draw_polygon(&p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(clr_idx, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha);
//g3_draw_polygon(&p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit_color(&mat_params, clr_idx, &gr_screen.current_color, true, false);
g3_render_rect_oriented(&mat_params, &p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f);
}
if ( idx >= 0 ) {
@@ -174,8 +177,11 @@ void HudGaugeRadarDradis::drawContact(vec3d *pnt, int idx, int clr_idx, float di
aspect_mp = (((float) h) / ((float) w));
}
gr_set_bitmap(idx, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha);
g3_draw_polygon(&p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_FLAG_BW_TEXTURE | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(idx, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha);
//g3_draw_polygon(&p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_FLAG_BW_TEXTURE | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit_color(&mat_params, idx, &gr_screen.current_color, true, false);
g3_render_rect_oriented(&mat_params, &p, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f);
}
}
@@ -343,13 +349,20 @@ void HudGaugeRadarDradis::drawOutlinesHtl()
vm_angle_2_matrix(&base_tilt, PI/6, 0);
vm_vec_rotate(&base_tilt_norm, &vmd_y_vector, &base_tilt);
gr_set_bitmap(xy_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f); // base
g3_draw_polygon(&vmd_zero_vector, &base_tilt_norm, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
//gr_set_bitmap(xy_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f); // base
//g3_draw_polygon(&vmd_zero_vector, &base_tilt_norm, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit(&mat_params, xy_plane, 1.0f, true, false);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &base_tilt_norm, scale, scale);
gr_set_bitmap(xz_yz_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
//gr_set_bitmap(xz_yz_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
g3_draw_polygon(&vmd_zero_vector, &vmd_x_vector, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // forward facing ring
g3_draw_polygon(&vmd_zero_vector, &vmd_z_vector, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // side facing ring
//g3_draw_polygon(&vmd_zero_vector, &vmd_x_vector, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // forward facing ring
//g3_draw_polygon(&vmd_zero_vector, &vmd_z_vector, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // side facing ring
material_set_unlit(&mat_params, xz_yz_plane, 1.0f, true, false);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &vmd_x_vector, scale, scale); // forward facing ring
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &vmd_z_vector, scale, scale); // side facing ring
g3_done_instance(true);
}
@@ -373,11 +386,17 @@ void HudGaugeRadarDradis::drawSweeps()
vm_vec_copy_scale(&sweep_normal_y, &sweep_b, 1.0f);
g3_start_instance_matrix(&vmd_zero_vector, /*&Player_obj->orient*/&vmd_identity_matrix, true);
gr_set_bitmap(sweep_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
// gr_set_bitmap(sweep_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
g3_draw_polygon(&vmd_zero_vector, &sweep_a, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
g3_draw_polygon(&vmd_zero_vector, &sweep_b, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
g3_draw_polygon(&vmd_zero_vector, &sweep_c, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
// g3_draw_polygon(&vmd_zero_vector, &sweep_a, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
// g3_draw_polygon(&vmd_zero_vector, &sweep_b, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
// g3_draw_polygon(&vmd_zero_vector, &sweep_c, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit(&mat_params, sweep_plane, 1.0f, true, false);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_a, scale, scale);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_b, scale, scale);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_c, scale, scale);
float rotation = sweep_percent;
@@ -385,11 +404,15 @@ void HudGaugeRadarDradis::drawSweeps()
vm_rot_point_around_line(&sweep_b, &vmd_y_vector, rotation, &vmd_zero_vector, &vmd_x_vector); // Sweep line: YZ
vm_rot_point_around_line(&sweep_c, &vmd_x_vector,sweep_perc_z, &vmd_zero_vector, &vmd_y_vector); // Sweep line: YZ
gr_set_bitmap(sweep_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL);
//gr_set_bitmap(sweep_plane, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL);
g3_draw_polygon(&vmd_zero_vector, &sweep_a, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // Sweep line: XZ
g3_draw_polygon(&vmd_zero_vector, &sweep_b, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // Sweep line: YZ
g3_draw_polygon(&vmd_zero_vector, &sweep_c, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
// g3_draw_polygon(&vmd_zero_vector, &sweep_a, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // Sweep line: XZ
// g3_draw_polygon(&vmd_zero_vector, &sweep_b, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT); // Sweep line: YZ
// g3_draw_polygon(&vmd_zero_vector, &sweep_c, scale, scale, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_a, scale, scale); // Sweep line: XZ
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_b, scale, scale); // Sweep line: YZ
g3_render_rect_oriented(&mat_params, &vmd_zero_vector, &sweep_c, scale, scale);
/*int dist = 90;
+25 -12
View File
@@ -157,14 +157,15 @@ void HudGaugeRadarOrb::drawContactHtl(vec3d *pnt, int rad)
if (Missiontime & 8192)
return;
}
g3_draw_htl_sphere(pnt,size/100.0f);
g3_render_sphere(pnt,size/100.0f);
}
else
{
g3_draw_htl_sphere(pnt,size/300.0f);
g3_render_sphere(pnt,size/300.0f);
}
g3_draw_htl_line(&p,pnt);
//g3_draw_htl_line(&p,pnt);
g3_render_line_3d(false, &p, pnt);
}
// radar is damaged, so make blips dance around
@@ -373,6 +374,7 @@ void HudGaugeRadarOrb::drawOutlines()
g3_draw_line(&proj_orb_lines_xz[i-1],&proj_orb_lines_xz[i]);
gr_set_color(112,16,192);
g3_draw_sphere(&proj_orb_lines_yz[i-1], .01f);
g3_draw_line(&proj_orb_lines_yz[i-1],&proj_orb_lines_yz[i]);
}
@@ -406,7 +408,7 @@ void HudGaugeRadarOrb::drawOutlinesHtl()
g3_start_instance_matrix(&vmd_zero_vector, &Player_obj->orient, true);
gr_set_color(255, 255, 255);
g3_draw_htl_sphere(&vmd_zero_vector, .05f);
g3_render_sphere(&vmd_zero_vector, .05f);
gr_set_line_width(2.0f);
@@ -414,15 +416,18 @@ void HudGaugeRadarOrb::drawOutlinesHtl()
{
gr_init_alphacolor(&Orb_color_orange, 192, 96, 32, calcAlpha(&orb_ring_xy[last]));
gr_set_color_fast(&Orb_color_orange);
g3_draw_htl_line(&orb_ring_xy[last],&orb_ring_xy[i]);
//g3_draw_htl_line(&orb_ring_xy[last],&orb_ring_xy[i]);
g3_render_line_3d(false, &orb_ring_xy[last],&orb_ring_xy[i]);
gr_init_alphacolor(&Orb_color_teal, 48, 160, 96, calcAlpha(&orb_ring_xz[last]));
gr_set_color_fast(&Orb_color_teal);
g3_draw_htl_line(&orb_ring_xz[last],&orb_ring_xz[i]);
//g3_draw_htl_line(&orb_ring_xz[last],&orb_ring_xz[i]);
g3_render_line_3d(false, &orb_ring_xz[last],&orb_ring_xz[i]);
gr_init_alphacolor(&Orb_color_purple, 112, 16, 192, calcAlpha(&orb_ring_yz[last]));
gr_set_color_fast(&Orb_color_purple);
g3_draw_htl_line(&orb_ring_yz[last],&orb_ring_yz[i]);
//g3_draw_htl_line(&orb_ring_yz[last],&orb_ring_yz[i]);
g3_render_line_3d(false, &orb_ring_yz[last],&orb_ring_yz[i]);
last = i;
}
@@ -547,7 +552,7 @@ void HudGaugeRadarOrb::drawContactImage(vec3d *pnt, int rad, int idx, int clr_id
aspect_mp = (((float) h) / ((float) w));
}
gr_set_bitmap(idx,GR_ALPHABLEND_NONE,GR_BITBLT_MODE_NORMAL,1.0f);
//gr_set_bitmap(idx,GR_ALPHABLEND_NONE,GR_BITBLT_MODE_NORMAL,1.0f);
float sizef = fl_sqrt(vm_vec_dist(&Orb_eye_position, pnt) * 8.0f);
@@ -581,11 +586,17 @@ void HudGaugeRadarOrb::drawContactImage(vec3d *pnt, int rad, int idx, int clr_id
tmap_flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_BW_TEXTURE | TMAP_HTL_3D_UNLIT;
if ( idx >= 0 ) {
g3_draw_polygon(pnt, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, tmap_flags);
//g3_draw_polygon(pnt, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, tmap_flags);
material mat_params;
material_set_unlit_color(&mat_params, idx, &gr_screen.current_color, true, false);
g3_render_rect_oriented(&mat_params, pnt, &vmd_identity_matrix, sizef / 35.0f, aspect_mp * sizef / 35.0f);
}
if ( clr_idx >= 0 ) {
g3_draw_polygon(pnt, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
//g3_draw_polygon(pnt, &vmd_identity_matrix, sizef/35.0f, aspect_mp*sizef/35.0f, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
material mat_params;
material_set_unlit(&mat_params, clr_idx, 1.0f, true, false);
g3_render_rect_oriented(&mat_params, pnt, &vmd_identity_matrix, sizef / 35.0f, aspect_mp * sizef / 35.0f);
}
}
@@ -601,14 +612,16 @@ void HudGaugeRadarOrb::drawCrosshairs( vec3d pnt )
pnt_end = pnt_start = pnt;
pnt_start.xyz.x += (float) m*0.05f;
pnt_end.xyz.x += (float) m*0.15f;
g3_draw_htl_line(&pnt_start, &pnt_end);
//g3_draw_htl_line(&pnt_start, &pnt_end);
g3_render_line_3d(false, &pnt_start, &pnt_end);
}
for(j = 0; j < 2; j++) {
m = (j * 2) - 1;
pnt_end = pnt_start = pnt;
pnt_start.xyz.y += (float) m*0.05f;
pnt_end.xyz.y += (float) m*0.15f;
g3_draw_htl_line(&pnt_start, &pnt_end);
//g3_draw_htl_line(&pnt_start, &pnt_end);
g3_render_line_3d(false, &pnt_start, &pnt_end);
}
}
+35 -25
View File
@@ -303,33 +303,12 @@ float g3_draw_laser(const vec3d *headp, float head_width, const vec3d *tailp, fl
*/
float g3_draw_laser_rgb(const vec3d *headp, float head_width, const vec3d *tailp, float tail_width, int r, int g, int b, uint tmap_flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB, float max_len = 0.0f );
/**
* Draw a bitmap that is always facing, but rotates.
*
* If bitmap is not square, rad will be the 3d size of the smallest dimension.
*/
int g3_draw_rotated_bitmap(vertex *pnt, float angle, float radius, uint tmap_flags, float depth = 0.0f);
/**
* Draw a perspective bitmap based on angles and radius
*/
int g3_draw_perspective_bitmap(const angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags);
/**
* Draw a 2D shield icon w/ 6 points
*/
void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a);
/**
* Draw a 2D rectangle
*/
void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a);
/**
* Draw a 2d bitmap on a poly
*/
int g3_draw_2d_poly_bitmap(float x, float y, float w, float h, uint additional_tmap_flags = 0);
/**
* Enables clipping with an arbritary plane.
*
@@ -356,9 +335,6 @@ void g3_stop_user_clip_plane();
ubyte g3_transfer_vertex(vertex *dest, const vec3d *src);
int g3_draw_2d_poly_bitmap_list(bitmap_2d_list* b_list, int n_bm, uint additional_tmap_flags);
int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list* b_list, int n_bm, uint additional_tmap_flags);
/**
* Draw a line in HTL mode without having to go through the rotate/project stuff
*/
@@ -367,7 +343,41 @@ void g3_draw_htl_line(const vec3d *start, const vec3d *end);
/**
* Draw a sphere mode without having to go through the rotate/project stuff
*/
void g3_draw_htl_sphere(const vec3d *position, float radius);
void g3_draw_htl_sphere(color *clr, const vec3d *position, float radius);
void g3_draw_htl_sphere(const vec3d* position, float radius);
void g3_render_primitives_textured(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_primitives_colored(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_primitives_colored_textured(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_rod(color *clr, int num_points, vec3d *pvecs, float width);
void g3_render_laser(material *mat_params, vec3d *headp, float head_width, vec3d *tailp, float tail_width);
void g3_render_laser_2d(material *mat_params, vec3d *headp, float head_width, vec3d *tailp, float tail_width, float max_len);
void g3_render_rect_screen_aligned_rotated(material *mat_params, vertex *pnt, float angle, float rad);
void g3_render_rect_screen_aligned(material *mat_params, vertex *pnt, int orient, float rad, float depth = 0.0f);
void g3_render_rect_screen_aligned_2d(material *mat_params, vertex *pnt, int orient, float rad);
void g3_render_rect_oriented(material* mat_info, vec3d *pos, matrix *ori, float width, float height);
void g3_render_rect_oriented(material* mat_info, vec3d *pos, vec3d *norm, float width, float height);
void g3_render_line_3d(color *clr, bool depth_testing, const vec3d *start, const vec3d *end);
void g3_render_line_3d(bool depth_testing, const vec3d *start, const vec3d *end);
void g3_render_sphere(color *clr, vec3d* position, float radius);
void g3_render_sphere(vec3d* position, float radius);
void g3_render_shield_icon(color *clr, coord2d coords[6], int resize_mode = GR_RESIZE_FULL);
void g3_render_shield_icon(coord2d coords[6], int resize_mode = GR_RESIZE_FULL);
void g3_render_colored_rect(color *clr, int x, int y, int w, int h, int resize_mode);
typedef struct horz_pt {
float x, y;
int edge;
} horz_pt;
/**
* Flash ball
+971 -11
View File
File diff suppressed because it is too large. Load diff
+992
View File
@@ -0,0 +1,992 @@
/*
* Copyright (C) Freespace Open 2015. All rights reserved.
*
* All source code herein is the property of Freespace Open. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include "render/batching.h"
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "render/3d.h"
#include "graphics/material.h"
static SCP_map<batch_info, primitive_batch> Batching_primitives;
static SCP_map<batch_buffer_key, primitive_batch_buffer> Batching_buffers;
void primitive_batch::add_triangle(batch_vertex* v0, batch_vertex* v1, batch_vertex *v2)
{
Vertices.push_back(*v0);
Vertices.push_back(*v1);
Vertices.push_back(*v2);
}
void primitive_batch::add_point_sprite(batch_vertex *p)
{
Vertices.push_back(*p);
}
int primitive_batch::load_buffer(batch_vertex* buffer, int n_verts)
{
int verts_to_render = Vertices.size();
for ( int i = 0; i < verts_to_render; ++i) {
buffer[n_verts+i] = Vertices[i];
}
return verts_to_render;
}
void primitive_batch::clear()
{
Vertices.clear();
}
void batching_setup_vertex_layout(vertex_layout *layout, uint vert_mask)
{
int offset = 0;
int stride = sizeof(batch_vertex);
if ( vert_mask & vertex_format_data::mask(vertex_format_data::POSITION3) ) {
layout->add_vertex_component(vertex_format_data::POSITION3, stride, (int)offsetof(batch_vertex, position));
}
if ( vert_mask & vertex_format_data::mask(vertex_format_data::TEX_COORD) ) {
layout->add_vertex_component(vertex_format_data::TEX_COORD, stride, (int)offsetof(batch_vertex, tex_coord));
}
if ( vert_mask & vertex_format_data::mask(vertex_format_data::COLOR4) ) {
layout->add_vertex_component(vertex_format_data::COLOR4, stride, (int)offsetof(batch_vertex, r));
}
if ( vert_mask & vertex_format_data::mask(vertex_format_data::RADIUS) ) {
layout->add_vertex_component(vertex_format_data::RADIUS, stride, (int)offsetof(batch_vertex, radius));
}
if ( vert_mask & vertex_format_data::mask(vertex_format_data::UVEC) ) {
layout->add_vertex_component(vertex_format_data::UVEC, stride, (int)offsetof(batch_vertex, uvec));
}
}
void batching_init_buffer(primitive_batch_buffer *buffer, primitive_type prim_type, uint vertex_mask)
{
batching_setup_vertex_layout(&buffer->layout, vertex_mask);
buffer->buffer_num = gr_create_vertex_buffer();
buffer->buffer_ptr = NULL;
buffer->buffer_size = 0;
buffer->prim_type = prim_type;
}
void batching_determine_blend_color(color *clr, int texture, float alpha)
{
gr_alpha_blend blend_mode = material_determine_blend_mode(texture, true);
if ( blend_mode == ALPHA_BLEND_ADDITIVE ) {
gr_init_alphacolor(clr, fl2i(255.0f*alpha), fl2i(255.0f*alpha), fl2i(255.0f*alpha), 255);
} else {
gr_init_alphacolor(clr, 255, 255, 255, fl2i(255.0f*alpha));
}
}
primitive_batch_buffer* batching_find_buffer(uint vertex_mask, primitive_type prim_type)
{
batch_buffer_key query(vertex_mask, prim_type);
SCP_map<batch_buffer_key, primitive_batch_buffer>::iterator iter = Batching_buffers.find(query);
if ( iter == Batching_buffers.end() ) {
primitive_batch_buffer *buffer = &Batching_buffers[query];
batching_init_buffer(buffer, prim_type, vertex_mask);
return buffer;
} else {
return &iter->second;
}
}
primitive_batch* batching_find_batch(int texture, batch_info::material_type material_id, primitive_type prim_type, bool thruster)
{
batch_info query(material_id, texture, prim_type, thruster);
SCP_map<batch_info, primitive_batch>::iterator iter = Batching_primitives.find(query);
if ( iter == Batching_primitives.end() ) {
primitive_batch* batch = &Batching_primitives[query];
*batch = primitive_batch(query);
return batch;
} else {
return &iter->second;
}
}
uint batching_determine_vertex_layout(batch_info *info)
{
if ( info->prim_type == PRIM_TYPE_POINTS ) {
return vertex_format_data::mask(vertex_format_data::POSITION3)
| vertex_format_data::mask(vertex_format_data::RADIUS)
| vertex_format_data::mask(vertex_format_data::UVEC);
}
if ( info->mat_type == batch_info::VOLUME_EMISSIVE || info->mat_type == batch_info::DISTORTION ) {
return vertex_format_data::mask(vertex_format_data::POSITION3)
| vertex_format_data::mask(vertex_format_data::COLOR4)
| vertex_format_data::mask(vertex_format_data::TEX_COORD)
| vertex_format_data::mask(vertex_format_data::RADIUS);
} else {
return vertex_format_data::mask(vertex_format_data::POSITION3)
| vertex_format_data::mask(vertex_format_data::COLOR4)
| vertex_format_data::mask(vertex_format_data::TEX_COORD);
}
}
void batching_add_bitmap_internal(primitive_batch *batch, vertex *pnt, int orient, float rad, color *clr, float depth)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
float radius = rad;
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
vec3d PNT(pnt->world);
vec3d p[4];
vec3d fvec, rvec, uvec;
batch_vertex verts[6];
// get the direction from the point to the eye
vm_vec_sub(&fvec, &View_position, &PNT);
vm_vec_normalize_safe(&fvec);
// get an up vector in the general direction of what we want
uvec = View_matrix.vec.uvec;
// make a right vector from the f and up vector, this r vec is exactly what we want, so...
vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
vm_vec_normalize_safe(&rvec);
// fix the u vec with it
vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);
// move the center of the sprite based on the depth parameter
if ( depth != 0.0f )
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
// move one of the verts to the left
vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
// and one to the right
vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
// now move all oof the verts to were they need to be
vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
//move all the data from the vecs into the verts
//tri 1
verts[5].position = p[3];
verts[4].position = p[2];
verts[3].position = p[1];
//tri 2
verts[2].position = p[3];
verts[1].position = p[1];
verts[0].position = p[0];
// set up the UV coords
if ( orient & 1 ) {
// tri 1
verts[5].tex_coord.u = 1.0f;
verts[4].tex_coord.u = 0.0f;
verts[3].tex_coord.u = 0.0f;
// tri 2
verts[2].tex_coord.u = 1.0f;
verts[1].tex_coord.u = 0.0f;
verts[0].tex_coord.u = 1.0f;
} else {
// tri 1
verts[5].tex_coord.u = 0.0f;
verts[4].tex_coord.u = 1.0f;
verts[3].tex_coord.u = 1.0f;
// tri 2
verts[2].tex_coord.u = 0.0f;
verts[1].tex_coord.u = 1.0f;
verts[0].tex_coord.u = 0.0f;
}
if ( orient & 2 ) {
// tri 1
verts[5].tex_coord.v = 1.0f;
verts[4].tex_coord.v = 1.0f;
verts[3].tex_coord.v = 0.0f;
// tri 2
verts[2].tex_coord.v = 1.0f;
verts[1].tex_coord.v = 0.0f;
verts[0].tex_coord.v = 0.0f;
} else {
// tri 1
verts[5].tex_coord.v = 0.0f;
verts[4].tex_coord.v = 0.0f;
verts[3].tex_coord.v = 1.0f;
// tri 2
verts[2].tex_coord.v = 0.0f;
verts[1].tex_coord.v = 1.0f;
verts[0].tex_coord.v = 1.0f;
}
for (int i = 0; i < 6 ; i++) {
verts[i].r = clr->red;
verts[i].g = clr->green;
verts[i].b = clr->blue;
verts[i].a = clr->alpha;
verts[i].radius = radius;
}
batch->add_triangle(&verts[5], &verts[4], &verts[3]);
batch->add_triangle(&verts[2], &verts[1], &verts[0]);
}
void batching_add_point_bitmap(primitive_batch *batch, vertex *position, int orient, float rad, float depth)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS);
float radius = rad;
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
vec3d PNT(position->world);
vec3d fvec;
// get the direction from the point to the eye
vm_vec_sub(&fvec, &View_position, &PNT);
vm_vec_normalize_safe(&fvec);
// move the center of the sprite based on the depth parameter
if ( depth != 0.0f )
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
batch_vertex new_particle;
vec3d up;
new_particle.position = position->world;
new_particle.radius = rad;
int direction = orient % 4;
switch ( direction ) {
case 0:
up.xyz.x = 0.0f;
up.xyz.y = 1.0f;
up.xyz.z = 0.0f;
break;
case 1:
up.xyz.x = 0.0f;
up.xyz.y = -1.0f;
up.xyz.z = 0.0f;
break;
case 2:
up.xyz.x = -1.0f;
up.xyz.y = 0.0f;
up.xyz.z = 0.0f;
break;
case 3:
up.xyz.x = 1.0f;
up.xyz.y = 0.0f;
up.xyz.z = 0.0f;
break;
}
new_particle.uvec = up;
batch->add_point_sprite(&new_particle);
}
void batching_add_bitmap_rotated_internal(primitive_batch *batch, vertex *pnt, float angle, float rad, color *clr, float depth)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
float radius = rad;
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
extern float Physics_viewer_bank;
angle -= Physics_viewer_bank;
if ( angle < 0.0f )
angle += PI2;
else if ( angle > PI2 )
angle -= PI2;
vec3d PNT(pnt->world);
vec3d p[4];
vec3d fvec, rvec, uvec;
batch_vertex verts[6];
vm_vec_sub(&fvec, &View_position, &PNT);
vm_vec_normalize_safe(&fvec);
vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &View_matrix.vec.fvec);
vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
vm_vec_normalize_safe(&rvec);
vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
//move all the data from the vecs into the verts
//tri 1
verts[5].position = p[3];
verts[4].position = p[2];
verts[3].position = p[1];
//tri 2
verts[2].position = p[3];
verts[1].position = p[1];
verts[0].position = p[0];
//tri 1
verts[5].tex_coord.u = 0.0f; verts[5].tex_coord.v = 0.0f;
verts[4].tex_coord.u = 1.0f; verts[4].tex_coord.v = 0.0f;
verts[3].tex_coord.u = 1.0f; verts[3].tex_coord.v = 1.0f;
//tri 2
verts[2].tex_coord.u = 0.0f; verts[2].tex_coord.v = 0.0f;
verts[1].tex_coord.u = 1.0f; verts[1].tex_coord.v = 1.0f;
verts[0].tex_coord.u = 0.0f; verts[0].tex_coord.v = 1.0f;
for (int i = 0; i < 6 ; i++) {
verts[i].r = clr->red;
verts[i].g = clr->green;
verts[i].b = clr->blue;
verts[i].a = clr->alpha;
verts[i].radius = radius;
}
batch->add_triangle(&verts[0], &verts[1], &verts[2]);
batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
void batching_add_point_bitmap(primitive_batch *batch, vertex *position, float rad, float angle, float depth)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_POINTS);
float radius = rad;
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
vec3d PNT(position->world);
vec3d fvec;
// get the direction from the point to the eye
vm_vec_sub(&fvec, &View_position, &PNT);
vm_vec_normalize_safe(&fvec);
// move the center of the sprite based on the depth parameter
if ( depth != 0.0f )
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
batch_vertex new_particle;
vec3d up;
vm_rot_point_around_line(&up, &vmd_y_vector, angle, &vmd_zero_vector, &vmd_z_vector);
new_particle.position = position->world;
new_particle.radius = rad;
new_particle.uvec = up;
batch->add_point_sprite(&new_particle);
}
void batching_add_polygon_internal(primitive_batch *batch, int texture, vec3d *pos, matrix *orient, float width, float height, color *clr)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
//idiot-proof
if(width == 0 || height == 0)
return;
Assert(pos != NULL);
Assert(orient != NULL);
//Let's begin.
const int NUM_VERTICES = 4;
vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
batch_vertex v[NUM_VERTICES];
p[0].xyz.x = width;
p[0].xyz.y = height;
p[1].xyz.x = -width;
p[1].xyz.y = height;
p[2].xyz.x = -width;
p[2].xyz.y = -height;
p[3].xyz.x = width;
p[3].xyz.y = -height;
for(int i = 0; i < NUM_VERTICES; i++)
{
vec3d tmp = vmd_zero_vector;
//Rotate correctly
vm_vec_unrotate(&tmp, &p[i], orient);
//Move to point in space
vm_vec_add2(&tmp, pos);
v[i].position = tmp;
v[i].r = clr->red;
v[i].g = clr->green;
v[i].b = clr->blue;
v[i].a = clr->alpha;
}
v[0].tex_coord.u = 1.0f;
v[0].tex_coord.v = 0.0f;
v[1].tex_coord.u = 0.0f;
v[1].tex_coord.v = 0.0f;
v[2].tex_coord.u = 0.0f;
v[2].tex_coord.v = 1.0f;
v[3].tex_coord.u = 1.0f;
v[3].tex_coord.v = 1.0f;
batch->add_triangle(&v[0], &v[1], &v[2]);
batch->add_triangle(&v[0], &v[2], &v[3]);
}
void batching_add_quad_internal(primitive_batch *batch, int texture, vertex *verts)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
const int NUM_VERTICES = 4;
vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
batch_vertex v[NUM_VERTICES];
for ( int i = 0; i < NUM_VERTICES; i++ ) {
v[i].position = verts[i].world;
v[i].r = verts[i].r;
v[i].g = verts[i].g;
v[i].b = verts[i].b;
v[i].a = verts[i].a;
v[i].tex_coord.u = verts[i].texture_position.u;
v[i].tex_coord.v = verts[i].texture_position.v;
}
batch->add_triangle(&v[0], &v[1], &v[2]);
batch->add_triangle(&v[0], &v[2], &v[3]);
}
void batching_add_tri_internal(primitive_batch *batch, int texture, vertex *verts)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
const int NUM_VERTICES = 3;
vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
batch_vertex v[NUM_VERTICES];
for ( int i = 0; i < NUM_VERTICES; i++ ) {
v[i].position = verts[i].world;
v[i].r = verts[i].r;
v[i].g = verts[i].g;
v[i].b = verts[i].b;
v[i].a = verts[i].a;
v[i].tex_coord.u = verts[i].texture_position.u;
v[i].tex_coord.v = verts[i].texture_position.v;
}
batch->add_triangle(&v[0], &v[1], &v[2]);
}
void batching_add_beam_internal(primitive_batch *batch, vec3d *start, vec3d *end, float width, color *clr, float offset)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
vec3d p[4];
batch_vertex verts[6];
vec3d fvec, uvecs, uvece, evec;
vm_vec_sub(&fvec, start, end);
vm_vec_normalize_safe(&fvec);
vm_vec_sub(&evec, &View_position, start);
vm_vec_normalize_safe(&evec);
vm_vec_cross(&uvecs, &fvec, &evec);
vm_vec_normalize_safe(&uvecs);
vm_vec_sub(&evec, &View_position, end);
vm_vec_normalize_safe(&evec);
vm_vec_cross(&uvece, &fvec, &evec);
vm_vec_normalize_safe(&uvece);
vm_vec_scale_add(&p[0], start, &uvecs, width);
vm_vec_scale_add(&p[1], end, &uvece, width);
vm_vec_scale_add(&p[2], end, &uvece, -width);
vm_vec_scale_add(&p[3], start, &uvecs, -width);
//move all the data from the vecs into the verts
//tri 1
verts[0].position = p[3];
verts[1].position = p[2];
verts[2].position = p[1];
//tri 2
verts[3].position = p[3];
verts[4].position = p[1];
verts[5].position = p[0];
//set up the UV coords
//tri 1
verts[0].tex_coord.u = 0.0f; verts[0].tex_coord.v = 0.0f;
verts[1].tex_coord.u = 1.0f; verts[1].tex_coord.v = 0.0f;
verts[2].tex_coord.u = 1.0f; verts[2].tex_coord.v = 1.0f;
//tri 2
verts[3].tex_coord.u = 0.0f; verts[3].tex_coord.v = 0.0f;
verts[4].tex_coord.u = 1.0f; verts[4].tex_coord.v = 1.0f;
verts[5].tex_coord.u = 0.0f; verts[5].tex_coord.v = 1.0f;
for(int i = 0; i < 6; i++){
verts[i].r = clr->red;
verts[i].g = clr->green;
verts[i].b = clr->blue;
verts[i].a = clr->alpha;
if(offset > 0.0f) {
verts[i].radius = offset;
} else {
verts[i].radius = width;
}
}
batch->add_triangle(&verts[0], &verts[1], &verts[2]);
batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
void batching_add_laser_internal(primitive_batch *batch, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);
width1 *= 0.5f;
width2 *= 0.5f;
vec3d uvec, fvec, rvec, center, reye;
vm_vec_sub( &fvec, p0, p1 );
vm_vec_normalize_safe( &fvec );
vm_vec_avg( &center, p0, p1 ); // needed for the return value only
vm_vec_sub(&reye, &Eye_position, &center);
vm_vec_normalize(&reye);
// compute the up vector
vm_vec_cross(&uvec, &fvec, &reye);
vm_vec_normalize_safe(&uvec);
// ... the forward vector
vm_vec_cross(&fvec, &uvec, &reye);
vm_vec_normalize_safe(&fvec);
// now recompute right vector, in case it wasn't entirely perpendiclar
vm_vec_cross(&rvec, &uvec, &fvec);
// Now have uvec, which is up vector and rvec which is the normal
// of the face.
vec3d start, end;
vm_vec_scale_add(&start, p0, &fvec, -width1);
vm_vec_scale_add(&end, p1, &fvec, width2);
vec3d vecs[4];
batch_vertex verts[6];
vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );
verts[0].position = vecs[0];
verts[1].position = vecs[1];
verts[2].position = vecs[2];
verts[3].position = vecs[0];
verts[4].position = vecs[2];
verts[5].position = vecs[3];
verts[0].tex_coord.u = 1.0f;
verts[0].tex_coord.v = 0.0f;
verts[1].tex_coord.u = 0.0f;
verts[1].tex_coord.v = 0.0f;
verts[2].tex_coord.u = 0.0f;
verts[2].tex_coord.v = 1.0f;
verts[3].tex_coord.u = 1.0f;
verts[3].tex_coord.v = 0.0f;
verts[4].tex_coord.u = 0.0f;
verts[4].tex_coord.v = 1.0f;
verts[5].tex_coord.u = 1.0f;
verts[5].tex_coord.v = 1.0f;
verts[0].r = (ubyte)r;
verts[0].g = (ubyte)g;
verts[0].b = (ubyte)b;
verts[0].a = 255;
verts[1].r = (ubyte)r;
verts[1].g = (ubyte)g;
verts[1].b = (ubyte)b;
verts[1].a = 255;
verts[2].r = (ubyte)r;
verts[2].g = (ubyte)g;
verts[2].b = (ubyte)b;
verts[2].a = 255;
verts[3].r = (ubyte)r;
verts[3].g = (ubyte)g;
verts[3].b = (ubyte)b;
verts[3].a = 255;
verts[4].r = (ubyte)r;
verts[4].g = (ubyte)g;
verts[4].b = (ubyte)b;
verts[4].a = 255;
verts[5].r = (ubyte)r;
verts[5].g = (ubyte)g;
verts[5].b = (ubyte)b;
verts[5].a = 255;
batch->add_triangle(&verts[0], &verts[1], &verts[2]);
batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
void batching_add_bitmap(int texture, vertex *pnt, int orient, float rad, float alpha, float depth)
{
if (texture < 0) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_bitmap_internal(batch, pnt, orient, rad, &clr, depth);
}
void batching_add_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha, float depth)
{
if ( texture < 0 ) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_bitmap_rotated_internal(batch, pnt, angle, rad, &clr, depth);
}
void batching_add_volume_bitmap(int texture, vertex *pnt, int orient, float rad, float alpha, float depth)
{
if (texture < 0) {
Int3();
return;
}
primitive_batch *batch;
if ( gr_is_capable(CAPABILITY_SOFT_PARTICLES) ) {
batch = batching_find_batch(texture, batch_info::VOLUME_EMISSIVE);
} else {
batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
}
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_bitmap_internal(batch, pnt, orient, rad, &clr, depth);
}
void batching_add_volume_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha, float depth)
{
if ( texture < 0 ) {
Int3();
return;
}
primitive_batch *batch;
if ( gr_is_capable(CAPABILITY_SOFT_PARTICLES) ) {
batch = batching_find_batch(texture, batch_info::VOLUME_EMISSIVE);
} else {
batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
}
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_bitmap_rotated_internal(batch, pnt, angle, rad, &clr, depth);
}
void batching_add_distortion_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha, float depth)
{
if (texture < 0) {
Int3();
return;
}
if ( !gr_is_capable(CAPABILITY_DISTORTION) ) {
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::DISTORTION);
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_bitmap_rotated_internal(batch, pnt, angle, rad, &clr, depth);
}
void batching_add_distortion_beam(int texture, vec3d *start, vec3d *end, float width, float intensity, float offset)
{
if (texture < 0) {
Int3();
return;
}
if ( !gr_is_capable(CAPABILITY_DISTORTION) ) {
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::DISTORTION, PRIM_TYPE_TRIS, true);
color clr;
batching_determine_blend_color(&clr, texture, intensity);
batching_add_beam_internal(batch, start, end, width, &clr, offset);
}
void batching_add_beam(int texture, vec3d *start, vec3d *end, float width, float intensity)
{
if (texture < 0) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
color clr;
batching_determine_blend_color(&clr, texture, intensity);
batching_add_beam_internal(batch, start, end, width, &clr, 0.0f);
}
void batching_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
if (texture < 0) {
Int3();
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
batching_add_laser_internal(batch, p0, width1, p1, width2, r, g, b);
}
void batching_add_polygon(int texture, vec3d *pos, matrix *orient, float width, float height, float alpha)
{
if (texture < 0) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
color clr;
batching_determine_blend_color(&clr, texture, alpha);
batching_add_polygon_internal(batch, texture, pos, orient, width, height, &clr);
}
void batching_add_quad(int texture, vertex *verts)
{
if ( texture < 0 ) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
batching_add_quad_internal(batch, texture, verts);
}
void batching_add_tri(int texture, vertex *verts)
{
if ( texture < 0 ) {
Int3();
return;
}
primitive_batch *batch = batching_find_batch(texture, batch_info::FLAT_EMISSIVE);
batching_add_tri_internal(batch, texture, verts);
}
void batching_render_batch_item(primitive_batch_item *item, vertex_layout *layout, primitive_type prim_type, int buffer_num)
{
if ( item->batch_item_info.mat_type == batch_info::VOLUME_EMISSIVE ) { // Cmdline_softparticles
particle_material material_def;
material_set_unlit_volume(&material_def, item->batch_item_info.texture, prim_type == PRIM_TYPE_POINTS);
gr_render_primitives_particle(&material_def, prim_type, layout, item->offset, item->n_verts, buffer_num);
} else if ( item->batch_item_info.mat_type == batch_info::DISTORTION ) {
distortion_material material_def;
material_set_distortion(&material_def, item->batch_item_info.texture, item->batch_item_info.thruster);
gr_render_primitives_distortion(&material_def, PRIM_TYPE_TRIS, layout, item->offset, item->n_verts, buffer_num);
} else {
material material_def;
material_set_unlit_emissive(&material_def, item->batch_item_info.texture, 1.0f, 2.0f);
gr_render_primitives(&material_def, PRIM_TYPE_TRIS, layout, item->offset, item->n_verts, buffer_num);
}
}
void batching_allocate_and_load_buffer(primitive_batch_buffer *draw_queue)
{
Assert(draw_queue != NULL);
if ( draw_queue->buffer_size < draw_queue->desired_buffer_size ) {
if ( draw_queue->buffer_ptr != NULL ) {
vm_free(draw_queue->buffer_ptr);
}
draw_queue->buffer_size = draw_queue->desired_buffer_size;
draw_queue->buffer_ptr = vm_malloc(draw_queue->desired_buffer_size);
}
draw_queue->desired_buffer_size = 0;
int offset = 0;
size_t num_items = draw_queue->items.size();
for ( size_t i = 0; i < num_items; ++i ) {
primitive_batch_item *item = &draw_queue->items[i];
item->offset = offset;
item->n_verts = item->batch->load_buffer((batch_vertex*)draw_queue->buffer_ptr, offset);
item->batch->clear();
offset += item->n_verts;
}
if ( draw_queue->buffer_num >= 0 ) {
gr_update_buffer_data(draw_queue->buffer_num, draw_queue->buffer_size, draw_queue->buffer_ptr);
}
}
void batching_load_buffers(bool distortion)
{
SCP_map<batch_info, primitive_batch>::iterator bi;
SCP_map<batch_buffer_key, primitive_batch_buffer>::iterator buffer_iter;
for ( buffer_iter = Batching_buffers.begin(); buffer_iter != Batching_buffers.end(); ++buffer_iter ) {
// zero out the buffers
buffer_iter->second.desired_buffer_size = 0;
}
// assign primitive batch items
for ( bi = Batching_primitives.begin(); bi != Batching_primitives.end(); ++bi ) {
if ( bi->first.mat_type == batch_info::DISTORTION ) {
if ( !distortion ) {
continue;
}
} else {
if ( distortion ) {
continue;
}
}
int num_verts = bi->second.num_verts();
if ( num_verts > 0 ) {
batch_info render_info = bi->second.get_render_info();
uint vertex_mask = batching_determine_vertex_layout(&render_info);
primitive_batch_buffer *buffer = batching_find_buffer(vertex_mask, render_info.prim_type);
primitive_batch_item draw_item;
draw_item.batch_item_info = render_info;
draw_item.offset = -1;
draw_item.n_verts = num_verts;
draw_item.batch = &bi->second;
buffer->desired_buffer_size += num_verts * sizeof(batch_vertex);
buffer->items.push_back(draw_item);
}
}
for ( buffer_iter = Batching_buffers.begin(); buffer_iter != Batching_buffers.end(); ++buffer_iter ) {
batching_allocate_and_load_buffer(&buffer_iter->second);
}
}
void batching_render_buffer(primitive_batch_buffer *buffer)
{
size_t num_batches = buffer->items.size();
for ( int j = 0; j < batch_info::NUM_RENDER_TYPES; ++j ) {
for ( size_t i = 0; i < num_batches; ++i ) {
if ( buffer->items[i].batch_item_info.mat_type != j ) {
continue;
}
batching_render_batch_item(&buffer->items[i], &buffer->layout, buffer->prim_type, buffer->buffer_num);
}
}
buffer->items.clear();
}
void batching_render_all(bool render_distortions)
{
batching_load_buffers(render_distortions);
SCP_map<batch_buffer_key, primitive_batch_buffer>::iterator bi;
for ( bi = Batching_buffers.begin(); bi != Batching_buffers.end(); ++bi ) {
batching_render_buffer(&bi->second);
}
gr_clear_states();
}
void batching_render_distortions_all()
{
batching_render_all(true);
}
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright (C) Freespace Open 2015. All rights reserved.
*
* All source code herein is the property of Freespace Open. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "graphics/material.h"
struct batch_vertex {
vec3d position;
uv_pair tex_coord;
ubyte r, g, b, a;
float radius;
vec3d uvec;
};
struct batch_info {
enum material_type {
FLAT_EMISSIVE,
VOLUME_EMISSIVE,
DISTORTION,
NUM_RENDER_TYPES
};
material_type mat_type;
int texture;
primitive_type prim_type;
bool thruster; // only used by distortion
batch_info(): mat_type(FLAT_EMISSIVE), texture(-1), prim_type(PRIM_TYPE_TRIS), thruster(false) {}
batch_info(material_type mat, int tex, primitive_type prim, bool thrust): mat_type(mat), texture(tex), prim_type(prim), thruster(thrust) {}
bool operator < (const batch_info& batch) const {
if ( mat_type != batch.mat_type ) {
return mat_type < batch.mat_type;
}
if ( texture != batch.texture ) {
return texture < batch.texture;
}
if ( prim_type != batch.prim_type ) {
return prim_type < batch.prim_type;
}
return thruster != batch.thruster;
}
};
struct batch_buffer_key {
uint Vertex_mask;
primitive_type Prim_type;
batch_buffer_key(): Vertex_mask(0), Prim_type(PRIM_TYPE_TRIS) {}
batch_buffer_key(uint vertex_mask, primitive_type prim_type): Vertex_mask(vertex_mask), Prim_type(prim_type) {}
bool operator < (const batch_buffer_key& key) const {
if ( Vertex_mask != key.Vertex_mask ) {
return Vertex_mask < key.Vertex_mask;
}
return Prim_type < key.Prim_type;
}
};
class primitive_batch
{
batch_info render_info;
SCP_vector<batch_vertex> Vertices;
public:
primitive_batch() : render_info() {}
primitive_batch(batch_info info): render_info(info) {}
batch_info &get_render_info() { return render_info; }
void add_triangle(batch_vertex* v0, batch_vertex* v1, batch_vertex* v2);
void add_point_sprite(batch_vertex *p);
int load_buffer(batch_vertex* buffer, int n_verts);
size_t num_verts() { return Vertices.size(); }
void clear();
};
struct primitive_batch_item {
batch_info batch_item_info;
int offset;
int n_verts;
primitive_batch *batch;
};
struct primitive_batch_buffer {
vertex_layout layout;
int buffer_num;
void* buffer_ptr;
int buffer_size;
int desired_buffer_size;
primitive_type prim_type;
SCP_vector<primitive_batch_item> items;
};
primitive_batch* batching_find_batch(int texture, batch_info::material_type material_id, primitive_type prim_type = PRIM_TYPE_TRIS, bool thruster = false);
void batching_add_bitmap(int texture, vertex *pnt, int orient, float rad, float alpha = 1.0f, float depth = 0.0f);
void batching_add_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
void batching_add_volume_bitmap(int texture, vertex *pnt, int orient, float rad, float alpha = 1.0f, float depth = 0.0f);
void batching_add_volume_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
void batching_add_distortion_bitmap_rotated(int texture, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
void batching_add_distortion_beam(int texture, vec3d *start, vec3d *end, float width, float intensity, float offset);
void batching_add_beam(int texture, vec3d *start, vec3d *end, float width, float intensity);
void batching_add_polygon(int texture, vec3d *pos, matrix *orient, float width, float height, float alpha = 1.0f);
void batching_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r = 255, int g = 255, int b = 255);
void batching_add_quad(int texture, vertex *verts);
void batching_add_tri(int texture, vertex *verts);
void batching_render_all(bool render_distortions = false);
void batching_render_distortions_all();
+62 -42
View File
@@ -15,12 +15,12 @@
// 3 Shrink-wrapped texture. Lasts half-time.
// 4 Shrink-wrapped texture. Lasts full-time.
#include "render/3d.h"
#include "model/model.h"
#include "freespace.h"
#include "mission/missionparse.h"
#include "model/model.h"
#include "network/multi.h"
#include "object/objectshield.h"
#include "render/3d.h"
#include "ship/ship.h"
#include "species_defs/species_defs.h"
@@ -251,7 +251,7 @@ void free_global_tri_records(int shnum)
}
}
void render_low_detail_shield_bitmap(gshield_tri *trip, matrix *orient, vec3d *pos, ubyte r, ubyte g, ubyte b)
void shield_render_low_detail_bitmap(int texture, float alpha, gshield_tri *trip, matrix *orient, vec3d *pos, ubyte r, ubyte g, ubyte b)
{
int j;
vec3d pnt;
@@ -285,26 +285,41 @@ void render_low_detail_shield_bitmap(gshield_tri *trip, matrix *orient, vec3d *p
vec3d norm;
vm_vec_perp(&norm, &trip->verts[0].pos, &trip->verts[1].pos, &trip->verts[2].pos);
vertex *vertlist[4];
//vertex *vertlist[4];
vertex vertlist[4];
if ( vm_vec_dot(&norm, &trip->verts[1].pos ) < 0.0 ) {
vertlist[0] = &verts[3];
vertlist[1] = &verts[2];
vertlist[2] = &verts[1];
vertlist[3] = &verts[0];
g3_draw_poly( 4, vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_HTL_3D_UNLIT);
vertlist[0] = verts[3];
vertlist[1] = verts[2];
vertlist[2] = verts[1];
vertlist[3] = verts[0];
//vertlist[0] = &verts[3];
//vertlist[1] = &verts[2];
//vertlist[2] = &verts[1];
//vertlist[3] = &verts[0];
//g3_draw_poly( 4, vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_HTL_3D_UNLIT);
} else {
vertlist[0] = &verts[0];
vertlist[1] = &verts[1];
vertlist[2] = &verts[2];
vertlist[3] = &verts[3];
g3_draw_poly( 4, vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_HTL_3D_UNLIT);
vertlist[0] = verts[0];
vertlist[1] = verts[1];
vertlist[2] = verts[2];
vertlist[3] = verts[3];
//vertlist[0] = &verts[0];
//vertlist[1] = &verts[1];
//vertlist[2] = &verts[2];
//vertlist[3] = &verts[3];
//g3_draw_poly( 4, vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_HTL_3D_UNLIT);
}
material material_params;
material_set_unlit_emissive(&material_params, texture, alpha, 2.0f);
g3_render_primitives_colored_textured(&material_params, vertlist, 4, PRIM_TYPE_TRIFAN, false);
}
/**
* Render one triangle of a shield hit effect on one ship.
* Each frame, the triangle needs to be rotated into global coords.
*
* @param texture handle to desired bitmap to render with
* @param alpha alpha value for color blending
* @param trip pointer to triangle in global array
* @param orient orientation of object shield is associated with
* @param pos center point of object
@@ -312,12 +327,11 @@ void render_low_detail_shield_bitmap(gshield_tri *trip, matrix *orient, vec3d *p
* @param g Green colour
* @param b Blue colour
*/
void render_shield_triangle(gshield_tri *trip, matrix *orient, vec3d *pos, ubyte r, ubyte g, ubyte b)
void shield_render_triangle(int texture, float alpha, gshield_tri *trip, matrix *orient, vec3d *pos, ubyte r, ubyte g, ubyte b)
{
int j;
vec3d pnt;
vertex *verts[3];
vertex points[3];
vertex verts[3];
memset(&verts, 0, sizeof(verts));
@@ -332,39 +346,41 @@ void render_shield_triangle(gshield_tri *trip, matrix *orient, vec3d *pos, ubyte
// Pnt is now the x,y,z world coordinates of this vert.
// For this example, I am just drawing a sphere at that point.
g3_transfer_vertex(&points[j],&pnt);
g3_transfer_vertex(&verts[j],&pnt);
points[j].texture_position.u = trip->verts[j].u;
points[j].texture_position.v = trip->verts[j].v;
verts[j].texture_position.u = trip->verts[j].u;
verts[j].texture_position.v = trip->verts[j].v;
Assert((trip->verts[j].u >= 0.0f) && (trip->verts[j].u <= UV_MAX));
Assert((trip->verts[j].v >= 0.0f) && (trip->verts[j].v <= UV_MAX));
verts[j] = &points[j];
}
verts[0]->r = r;
verts[0]->g = g;
verts[0]->b = b;
verts[1]->r = r;
verts[1]->g = g;
verts[1]->b = b;
verts[2]->r = r;
verts[2]->g = g;
verts[2]->b = b;
verts[0].r = r;
verts[0].g = g;
verts[0].b = b;
verts[1].r = r;
verts[1].g = g;
verts[1].b = b;
verts[2].r = r;
verts[2].g = g;
verts[2].b = b;
vec3d norm;
Poly_count++;
vm_vec_perp(&norm,&verts[0]->world,&verts[1]->world,&verts[2]->world);
vm_vec_perp(&norm, &verts[0].world, &verts[1].world, &verts[2].world);
int flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE;
material material_params;
material_set_unlit(&material_params, texture, alpha, true, true);
material_params.set_color_scale(2.0f);
if ( vm_vec_dot(&norm,&verts[1]->world ) >= 0.0 ) {
vertex *vertlist[3];
if ( vm_vec_dot(&norm, &verts[1].world) >= 0.0 ) {
vertex vertlist[3];
vertlist[0] = verts[2];
vertlist[1] = verts[1];
vertlist[2] = verts[0];
g3_draw_poly( 3, vertlist, flags);
vertlist[2] = verts[0];
g3_render_primitives_colored_textured(&material_params, vertlist, 3, PRIM_TYPE_TRIFAN, false);
} else {
g3_draw_poly( 3, verts, flags);
g3_render_primitives_colored_textured(&material_params, verts, 3, PRIM_TYPE_TRIFAN, false);
}
}
@@ -450,16 +466,18 @@ void render_shield(int shield_num)
alpha *= 0.85f;
}
gr_set_bitmap(bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
//gr_set_bitmap(bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
if ( (Detail.shield_effects == 1) || (Detail.shield_effects == 2) ) {
if ( bitmap_id != - 1 ) {
render_low_detail_shield_bitmap(&Global_tris[Shield_hits[shield_num].tri_list[0]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
//render_low_detail_shield_bitmap(&Global_tris[Shield_hits[shield_num].tri_list[0]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
shield_render_low_detail_bitmap(bitmap_id, alpha, &Global_tris[Shield_hits[shield_num].tri_list[0]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
}
} else {
if ( bitmap_id != - 1 ) {
for (i=0; i<Shield_hits[shield_num].num_tris; i++) {
render_shield_triangle(&Global_tris[Shield_hits[shield_num].tri_list[i]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
shield_render_triangle(bitmap_id, alpha, &Global_tris[Shield_hits[shield_num].tri_list[i]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
//render_shield_triangle(&Global_tris[Shield_hits[shield_num].tri_list[i]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]);
}
}
}
@@ -932,10 +950,12 @@ void ship_draw_shield( object *objp)
// point.
g3_rotate_vertex(&tmp, &pnt);
if (j)
if (j) {
g3_draw_line(&prev_pnt, &tmp);
else
} else {
pnt0 = tmp;
}
prev_pnt = tmp;
}
+5 -8
View File
@@ -69,6 +69,7 @@
#include "radar/radar.h"
#include "radar/radarsetup.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/afterburner.h"
#include "ship/ship.h"
#include "ship/shipcontrails.h"
@@ -6907,7 +6908,6 @@ man_thruster_renderer *man_thruster_get_slot(int bmap_frame)
}
//WMC - used for FTL and maneuvering thrusters
geometry_batcher fx_batcher;
extern bool Rendering_to_shadow_map;
void ship_render_cockpit(object *objp)
@@ -18532,7 +18532,6 @@ void ship_render_batch_thrusters(object *obj)
physics_info *pi = &Objects[shipp->objnum].phys_info;
float render_amount;
fx_batcher.allocate(sip->num_maneuvering); //Act as if all thrusters are going.
for ( int i = 0; i < sip->num_maneuvering; i++ ) {
man_thruster *mtp = &sip->maneuvering[i];
@@ -18620,16 +18619,14 @@ void ship_render_batch_thrusters(object *obj)
vm_vec_unrotate(&end, &tmpend, &obj->orient);
vm_vec_add2(&end, &obj->pos);
//Draw
fx_batcher.draw_beam(&start, &end, rad, 1.0f);
int bmap_frame = mtp->tex_id;
if(mtp->tex_nframes > 0)
bmap_frame += bm_get_anim_frame(mtp->tex_id, i2fl(timestamp() - shipp->thrusters_start[i]) / 1000.0f, 0.0f, true);
man_thruster_renderer *mtr = man_thruster_get_slot(bmap_frame);
mtr->man_batcher.add_allocate(1);
mtr->man_batcher.draw_beam(&start, &end, rad, 1.0f);
//man_thruster_renderer *mtr = man_thruster_get_slot(bmap_frame);
//mtr->man_batcher.add_allocate(1);
//mtr->man_batcher.draw_beam(&start, &end, rad, 1.0f);
batching_add_beam(bmap_frame, &start, &end, rad, 1.0f);
}
} else if ( shipp->thrusters_start[i] > 0 ) {
// We've stopped firing a thruster
+5 -5
View File
@@ -35,6 +35,7 @@
#include "particle/particle.h"
#include "playerman/player.h"
#include "render/3d.h" // needed for View_position, which is used when playing a 3D sound
#include "render/batching.h"
#include "ship/ship.h"
#include "ship/shipfx.h"
#include "ship/shiphit.h"
@@ -4004,7 +4005,8 @@ int WE_BSG::warpShipRender()
vm_vec_scale_add(&end, &pos, &objp->orient.vec.fvec, z_offset_max);
//Render the warpout effect
batch_add_beam(anim + anim_frame, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE, &start, &end, tube_radius*2.0f, 1.0f);
//batch_add_beam(anim + anim_frame, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT, &start, &end, tube_radius*2.0f, 1.0f);
batching_add_beam(anim + anim_frame, &start, &end, tube_radius * 2.0f, 1.0f);
}
}
@@ -4020,7 +4022,7 @@ int WE_BSG::warpShipRender()
g3_transfer_vertex(&p, &pos);
batch_add_bitmap(shockwave + shockwave_frame, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_EMISSIVE, &p, 0, shockwave_radius, 1.0f);
batching_add_volume_bitmap(shockwave + shockwave_frame, &p, 0, shockwave_radius, 1.0f);
}
}
@@ -4296,9 +4298,7 @@ int WE_Homeworld::warpShipRender()
frame = fl2i( (int)(((float)(timestamp() - (float)total_time_start)/1000.0f) * (float)anim_fps) % anim_nframes);
//Set the correct frame
// gr_set_bitmap(anim + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
// g3_draw_polygon(&pos, &objp->orient, width, height, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
batch_add_polygon(anim + frame, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE, &pos, &objp->orient, width, height);
batching_add_polygon(anim + frame, &pos, &objp->orient, width, height);
return 1;
}
+4
View File
@@ -304,6 +304,8 @@ set (file_root_graphics
graphics/tmapper.h
graphics/shadows.cpp
graphics/shadows.h
graphics/material.cpp
graphics/material.h
)
# Graphics -> OpenGLGr files
@@ -884,6 +886,8 @@ set (file_root_render
render/3dlaser.cpp
render/3dmath.cpp
render/3dsetup.cpp
render/batching.cpp
render/batching.h
)
# Ship files
+32 -20
View File
@@ -14,10 +14,11 @@
#include "math/vecmat.h"
#include "mission/missionparse.h"
#include "nebula/neb.h"
#include "palman/palman.h"
#include "graphics/material.h"
#include "render/3d.h"
#include "starfield/nebula.h"
#define MAX_TRIS 200
#define MAX_POINTS 300
@@ -162,14 +163,21 @@ void nebula_init( const char *filename, angles * pbh )
}
}
void nebula_get_color_from_palette(ubyte *r, ubyte *g, ubyte *b, ubyte index)
{
int pal = (index * (NEBULA_INDEXED_COLORS-1)) / 255;
*r = gr_palette[pal*3+0];
*g = gr_palette[pal*3+1];
*b = gr_palette[pal*3+2];
}
void nebula_render()
{
int i;
// int r, g, b;
if (Fred_running) {
// no nebula for you!
return;
// no nebula for you!
return;
}
if ( !Nebula_loaded ) {
@@ -188,29 +196,33 @@ void nebula_render()
g3_project_vertex( &nebula_verts[i] );
}
int saved_gr_zbuffering = gr_zbuffer_get();
material nebula_material;
gr_zbuffer_set(GR_ZBUFF_NONE);
nebula_material.set_depth_mode(ZBUFFER_TYPE_NONE);
nebula_material.set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
nebula_material.set_cull_mode(false);
nebula_material.set_texture_source(TEXTURE_SOURCE_NONE);
for (i=0; i<num_tris; i++ ) {
for ( i = 0 ; i < num_tris; i++ ) {
ubyte r, g, b;
vertex verts[3];
verts[0] = nebula_verts[tri[i][0]];
verts[1] = nebula_verts[tri[i][1]];
verts[2] = nebula_verts[tri[i][2]];
vertex * verts[3];
nebula_get_color_from_palette(&verts[0].r, &verts[0].g, &verts[0].b, verts[0].b);
nebula_get_color_from_palette(&verts[1].r, &verts[1].g, &verts[1].b, verts[1].b);
nebula_get_color_from_palette(&verts[2].r, &verts[2].g, &verts[2].b, verts[2].b);
verts[0] = &nebula_verts[tri[i][0]];
verts[1] = &nebula_verts[tri[i][1]];
verts[2] = &nebula_verts[tri[i][2]];
verts[0].a = 255;
verts[1].a = 255;
verts[2].a = 255;
g3_draw_poly(3, verts, TMAP_FLAG_RAMP | TMAP_FLAG_GOURAUD | TMAP_FLAG_NEBULA );
}
g3_render_primitives_colored(&nebula_material, verts, 3, PRIM_TYPE_TRIFAN, true);
}
g3_done_instance(false);
gr_zbuffer_set(saved_gr_zbuffering);
// always switch off fogging for good measure
if((The_mission.flags[Mission::Mission_Flags::Fullneb]) && (Neb2_render_mode == NEB2_RENDER_NONE)){
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
}
}
DCF(nebula,"Loads a different nebula")
+2
View File
@@ -26,4 +26,6 @@ void nebula_init( const char *filename, angles *pbh = /*NULL*/ 0 );
void nebula_close();
void nebula_render();
#define NEBULA_INDEXED_COLORS 20
#endif //_NEBULA_H
+74 -45
View File
@@ -1087,16 +1087,36 @@ void stars_draw_sun(int show_sun)
local_scale = 1.0f;
// draw the sun itself, keep track of how many we drew
int bitmap_id = -1;
if (bm->fps) {
gr_set_bitmap(bm->bitmap_id + ((timestamp() / (int)(bm->fps)) % bm->n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
//gr_set_bitmap(bm->bitmap_id + ((timestamp() / (int)(bm->fps)) % bm->n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
bitmap_id = bm->bitmap_id + ((timestamp() / (int)(bm->fps)) % bm->n_frames);
} else {
gr_set_bitmap(bm->bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
//gr_set_bitmap(bm->bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
bitmap_id = bm->bitmap_id;
}
g3_rotate_faraway_vertex(&sun_vex, &sun_pos);
if ( !g3_draw_bitmap(&sun_vex, 0, 0.05f * Suns[idx].scale_x * local_scale, TMAP_FLAG_TEXTURED) )
Sun_drew++;
if ( sun_vex.codes & (CC_BEHIND|CC_OFF_USER) ) {
return;
}
if ( !(sun_vex.flags & PF_PROJECTED) ) {
g3_project_vertex(&sun_vex);
}
if ( sun_vex.flags & PF_OVERFLOW ) {
return;
}
material mat_params;
material_set_unlit(&mat_params, bitmap_id, 0.999f, true, false);
g3_render_rect_screen_aligned_2d(&mat_params, &sun_vex, 0, 0.05f * Suns[idx].scale_x * local_scale);
Sun_drew++;
// if ( !g3_draw_bitmap(&sun_vex, 0, 0.05f * Suns[idx].scale_x * local_scale, TMAP_FLAG_TEXTURED) )
// Sun_drew++;
}
}
@@ -1136,15 +1156,17 @@ void stars_draw_lens_flare(vertex *sun_vex, int sun_n)
if (bm->flare_bitmaps[j].bitmap_id < 0)
continue;
gr_set_bitmap(bm->flare_bitmaps[j].bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
//gr_set_bitmap(bm->flare_bitmaps[j].bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
for (i = 0; i < bm->n_flares; i++) {
// draw sorted by texture, to minimize texture changes. not the most efficient way, but better than non-sorted
if (bm->flare_infos[i].tex_num == j) {
// gr_set_bitmap(bm->flare_bitmaps[bm->flare_infos[i].tex_num], GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
flare_vex.screen.xyw.x = sun_vex->screen.xyw.x + dx * bm->flare_infos[i].pos;
flare_vex.screen.xyw.y = sun_vex->screen.xyw.y + dy * bm->flare_infos[i].pos;
g3_draw_bitmap(&flare_vex, 0, 0.05f * bm->flare_infos[i].scale, TMAP_FLAG_TEXTURED);
//g3_draw_bitmap(&flare_vex, 0, 0.05f * bm->flare_infos[i].scale, TMAP_FLAG_TEXTURED);
material mat_params;
material_set_unlit(&mat_params, bm->flare_bitmaps[j].bitmap_id, 0.999f, true, false);
g3_render_rect_screen_aligned_2d(&mat_params, &flare_vex, 0, 0.05f * bm->flare_infos[i].scale);
}
}
}
@@ -1194,15 +1216,21 @@ void stars_draw_sun_glow(int sun_n)
local_scale = 1.0f;
// draw the sun itself, keep track of how many we drew
int bitmap_id = -1;
if (bm->glow_fps) {
gr_set_bitmap(bm->glow_bitmap + ((timestamp() / (int)(bm->glow_fps)) % bm->glow_n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.5f);
//gr_set_bitmap(bm->glow_bitmap + ((timestamp() / (int)(bm->glow_fps)) % bm->glow_n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.5f);
bitmap_id = bm->glow_bitmap + ((timestamp() / (int)(bm->glow_fps)) % bm->glow_n_frames);
} else {
gr_set_bitmap(bm->glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.5f);
//gr_set_bitmap(bm->glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.5f);
bitmap_id = bm->glow_bitmap;
}
g3_rotate_faraway_vertex(&sun_vex, &sun_pos);
int zbuff = gr_zbuffer_set(GR_ZBUFF_NONE);
g3_draw_bitmap(&sun_vex, 0, 0.10f * Suns[sun_n].scale_x * local_scale, TMAP_FLAG_TEXTURED);
//int zbuff = gr_zbuffer_set(GR_ZBUFF_NONE);
//g3_draw_bitmap(&sun_vex, 0, 0.10f * Suns[sun_n].scale_x * local_scale, TMAP_FLAG_TEXTURED);
material mat_params;
material_set_unlit(&mat_params, bitmap_id, 0.5f, true, false);
g3_render_rect_screen_aligned_2d(&mat_params, &sun_vex, 0, 0.10f * Suns[sun_n].scale_x * local_scale);
if (bm->flare) {
vec3d light_dir;
@@ -1214,11 +1242,9 @@ void stars_draw_sun_glow(int sun_n)
stars_draw_lens_flare(&sun_vex, sun_n);
}
gr_zbuffer_set(zbuff);
//gr_zbuffer_set(zbuff);
}
// draw bitmaps
void stars_draw_bitmaps(int show_bitmaps)
{
int idx;
@@ -1238,13 +1264,6 @@ void stars_draw_bitmaps(int show_bitmaps)
gr_start_instance_matrix(&Eye_position, &vmd_identity_matrix);
// turn off culling
int cull = gr_set_cull(0);
// turn off zbuffering
int saved_zbuffer_mode = gr_zbuffer_get();
gr_zbuffer_set(GR_ZBUFF_NONE);
int sb_instances = (int)Starfield_bitmap_instances.size();
for (idx = 0; idx < sb_instances; idx++) {
@@ -1260,33 +1279,33 @@ void stars_draw_bitmaps(int show_bitmaps)
continue;
}
int tmap_flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_FLAG_TRILIST | TMAP_HTL_3D_UNLIT;
int bitmap_id;
bool blending = false;
float alpha = 1.0f;
if (Starfield_bitmaps[star_index].xparent) {
if (Starfield_bitmaps[star_index].fps) {
gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames));
bitmap_id = Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames);
} else {
gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id);
bitmap_id = Starfield_bitmaps[star_index].bitmap_id;
}
tmap_flags |= TMAP_FLAG_XPARENT;
} else {
if (Starfield_bitmaps[star_index].fps) {
gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
bitmap_id = Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames);
blending = true;
alpha = 0.9999f;
} else {
gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
bitmap_id = Starfield_bitmaps[star_index].bitmap_id;
blending = true;
alpha = 0.9999f;
}
}
gr_render(Starfield_bitmap_instances[idx].n_verts, Starfield_bitmap_instances[idx].verts, tmap_flags);
material material_params;
material_set_unlit(&material_params, bitmap_id, alpha, blending, false);
g3_render_primitives_textured(&material_params, Starfield_bitmap_instances[idx].verts, Starfield_bitmap_instances[idx].n_verts, PRIM_TYPE_TRIS, false);
}
// turn on culling
gr_set_cull(cull);
// restore zbuffer
gr_zbuffer_set(saved_zbuffer_mode);
gr_end_instance_matrix();
}
@@ -1464,14 +1483,19 @@ void subspace_render()
glow_pos.xyz.y = 0.0f;
glow_pos.xyz.z = 100.0f;
gr_set_bitmap(Subspace_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
//gr_set_bitmap(Subspace_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
material mat_params;
material_set_unlit(&mat_params, Subspace_glow_bitmap, 1.0f, true, false);
g3_rotate_faraway_vertex(&glow_vex, &glow_pos);
g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
//g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
g3_render_rect_screen_aligned_2d(&mat_params, &glow_vex, 0, 17.0f + 0.5f * Noise[framenum]);
glow_pos.xyz.z = -100.0f;
g3_rotate_faraway_vertex(&glow_vex, &glow_pos);
g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
//g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
g3_render_rect_screen_aligned_2d(&mat_params, &glow_vex, 0, 17.0f + 0.5f * Noise[framenum]);
Interp_subspace = 0;
gr_zbuffer_set(saved_gr_zbuffering);
@@ -1623,14 +1647,19 @@ void stars_draw_debris()
int frame = Missiontime / (DEBRIS_ROT_MIN + (i % DEBRIS_ROT_RANGE) * DEBRIS_ROT_RANGE_SCALER);
frame %= Debris_vclips[d->vclip].nframes;
if ( (The_mission.flags[Mission::Mission_Flags::Fullneb]) && (Neb2_render_mode != NEB2_RENDER_NONE) ) {
gr_set_bitmap( Debris_vclips[d->vclip].bm + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.3f);
} else {
gr_set_bitmap( Debris_vclips[d->vclip].bm + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
}
float alpha;
if ( (The_mission.flags[Mission::Mission_Flags::Fullneb]) && (Neb2_render_mode != NEB2_RENDER_NONE) ) {
alpha = 0.3f;
} else {
alpha = 1.0f;
}
vm_vec_add( &tmp, &d->last_pos, &Eye_position );
g3_draw_laser( &d->pos,d->size,&tmp,d->size, TMAP_FLAG_TEXTURED|TMAP_FLAG_XPARENT, 25.0f );
//g3_draw_laser( &d->pos,d->size,&tmp,d->size, TMAP_FLAG_TEXTURED|TMAP_FLAG_XPARENT, 25.0f );
material mat_params;
material_set_unlit(&mat_params, Debris_vclips[d->vclip].bm + frame, alpha, true, true);
g3_render_laser_2d(&mat_params, &d->pos, d->size, &tmp, d->size, 25.0f);
}
vm_vec_sub( &d->last_pos, &d->pos, &Eye_position );
+30 -23
View File
@@ -38,6 +38,7 @@
#include "ship/shiphit.h"
#include "weapon/beam.h"
#include "weapon/weapon.h"
#include "globalincs/globals.h"
// ------------------------------------------------------------------------------------------------
// BEAM WEAPON DEFINES/VARS
@@ -1174,7 +1175,7 @@ void beam_render(beam *b, float u_offset)
vm_vec_normalize_quick(&fvec);
// turn off backface culling
int cull = gr_set_cull(0);
//int cull = gr_set_cull(0);
length = vm_vec_dist(&b->last_start, &b->last_shot); // beam tileing -Bobboau
@@ -1246,15 +1247,13 @@ void beam_render(beam *b, float u_offset)
framenum = bm_get_anim_frame(bwsi->texture.first_frame, b->beam_section_frame[s_idx], bwsi->texture.total_time, true);
}
gr_set_bitmap(bwsi->texture.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
// added TMAP_FLAG_TILED flag for beam texture tileing -Bobboau
// added TMAP_FLAG_RGB and TMAP_FLAG_GOURAUD so the beam would apear to fade along it's length-Bobboau
g3_draw_poly( 4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_TILED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_EMISSIVE );
material material_params;
material_set_unlit_emissive(&material_params, bwsi->texture.first_frame + framenum, 0.9999f, 2.0f);
g3_render_primitives_colored_textured(&material_params, h1, 4, PRIM_TYPE_TRIFAN, false);
}
// turn backface culling back on
gr_set_cull(cull);
//gr_set_cull(cull);
}
// generate particles for the muzzle glow
@@ -1417,8 +1416,6 @@ void beam_render_muzzle_glow(beam *b)
vm_vec_copy_scale(&sub2, &fvec, bwi->glow_length);
vm_vec_add(&end, &start, &sub2);
int cull = gr_set_cull(0);
beam_calc_facing_pts(&top1, &bottom1, &fvec, &start, rad, 1.0f);
beam_calc_facing_pts(&top2, &bottom2, &fvec, &end, rad, 1.0f);
@@ -1459,47 +1456,57 @@ void beam_render_muzzle_glow(beam *b)
int framenum = 0;
if (bwi->beam_glow.num_frames > 1) {
if ( bwi->beam_glow.num_frames > 1 ) {
b->beam_glow_frame += flFrametime;
framenum = bm_get_anim_frame(bwi->beam_glow.first_frame, b->beam_glow_frame, bwi->beam_glow.total_time, true);
}
gr_set_bitmap(bwi->beam_glow.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha * pct);
//gr_set_bitmap(bwi->beam_glow.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha * pct);
// draw a poly
g3_draw_poly(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT);
//g3_draw_poly(4, verts, TMAP_FLAG_TEXTURED | TMAP_FLAG_CORRECT | TMAP_HTL_3D_UNLIT);
gr_set_cull(cull);
material material_info;
material_set_unlit_emissive(&material_info, bwi->beam_glow.first_frame + framenum, alpha * pct, 2.0f);
g3_render_primitives_textured(&material_info, h1, 4, PRIM_TYPE_TRIFAN, false);
} else {
// draw the bitmap
g3_transfer_vertex(&pt, &b->last_start);
int framenum = 0;
if (bwi->beam_glow.num_frames > 1) {
if ( bwi->beam_glow.num_frames > 1 ) {
b->beam_glow_frame += flFrametime;
framenum = bm_get_anim_frame(bwi->beam_glow.first_frame, b->beam_glow_frame, bwi->beam_glow.total_time, true);
}
gr_set_bitmap(bwi->beam_glow.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha * pct);
//gr_set_bitmap(bwi->beam_glow.first_frame + framenum, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha * pct);
// draw 1 bitmap
g3_draw_bitmap(&pt, 0, rad, tmap_flags);
//g3_draw_bitmap(&pt, 0, rad, tmap_flags);
material mat_params;
material_set_unlit_emissive(&mat_params, bwi->beam_glow.first_frame + framenum, alpha * pct, 2.0f);
g3_render_rect_screen_aligned(&mat_params, &pt, 0, rad, 0.0f);
// maybe draw more
if (pct > 0.3f)
g3_draw_bitmap(&pt, 0, rad * 0.75f, tmap_flags, rad * 0.25f);
if ( pct > 0.3f ) {
//g3_draw_bitmap(&pt, 0, rad * 0.75f, tmap_flags, rad * 0.25f);
g3_render_rect_screen_aligned(&mat_params, &pt, 0, rad * 0.75f, rad * 0.25f);
}
if (pct > 0.5f)
g3_draw_bitmap(&pt, 0, rad * 0.45f, tmap_flags, rad * 0.55f);
if ( pct > 0.5f ) {
//g3_draw_bitmap(&pt, 0, rad * 0.45f, tmap_flags, rad * 0.55f);
g3_render_rect_screen_aligned(&mat_params, &pt, 0, rad * 0.45f, rad * 0.55f);
}
if (pct > 0.7f)
g3_draw_bitmap(&pt, 0, rad * 0.25f, tmap_flags, rad * 0.75f);
if ( pct > 0.7f ) {
//g3_draw_bitmap(&pt, 0, rad * 0.25f, tmap_flags, rad * 0.75f);
g3_render_rect_screen_aligned(&mat_params, &pt, 0, rad * 0.25f, rad * 0.75f);
}
}
}
+6 -23
View File
@@ -16,6 +16,7 @@
#include "model/modelrender.h"
#include "object/object.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "ship/shiphit.h"
#include "weapon/shockwave.h"
@@ -397,36 +398,18 @@ void shockwave_render(object *objp, draw_list *scene)
if ( Cmdline_fb_explosions ) {
g3_transfer_vertex(&p, &sw->pos);
distortion_add_bitmap_rotated(
Shockwave_info[1].bitmap_id+shockwave_get_framenum(objp->instance, Shockwave_info[1].bitmap_id),
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_DISTORTION,
&p,
fl_radians(sw->rot_angles.p),
sw->radius,
((sw->time_elapsed/sw->total_time)>0.9f)?(1.0f-(sw->time_elapsed/sw->total_time))*10.0f:1.0f
);
float intensity = ((sw->time_elapsed / sw->total_time) > 0.9f) ? (1.0f - (sw->time_elapsed / sw->total_time))*10.0f : 1.0f;
batching_add_distortion_bitmap_rotated(Shockwave_info[1].bitmap_id + shockwave_get_framenum(objp->instance, 94), &p, fl_radians(sw->rot_angles.p), sw->radius, intensity);
}
} else {
g3_transfer_vertex(&p, &sw->pos);
if ( Cmdline_fb_explosions ) {
distortion_add_bitmap_rotated(
sw->current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_DISTORTION,
&p,
fl_radians(sw->rot_angles.p),
sw->radius,
((sw->time_elapsed/sw->total_time)>0.9f)?(1.0f-(sw->time_elapsed/sw->total_time))*10.0f:1.0f
);
float intensity = ((sw->time_elapsed / sw->total_time) > 0.9f) ? (1.0f - (sw->time_elapsed / sw->total_time)) * 10.0f : 1.0f;
batching_add_distortion_bitmap_rotated(sw->current_bitmap, &p, fl_radians(sw->rot_angles.p), sw->radius, intensity);
}
batch_add_bitmap_rotated(
sw->current_bitmap,
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_EMISSIVE,
&p,
fl_radians(sw->rot_angles.p),
sw->radius
);
batching_add_volume_bitmap_rotated(sw->current_bitmap, &p, fl_radians(sw->rot_angles.p), sw->radius);
}
}
+9 -8
View File
@@ -11,6 +11,8 @@
#include "cmdline/cmdline.h"
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "graphics/gropenglextension.h"
#include "io/timer.h"
#include "render/3d.h"
#include "ship/ship.h"
@@ -19,17 +21,11 @@
int Num_trails;
trail Trails;
int Trail_buffer_object = -1;
// Reset everything between levels
void trail_level_init()
{
Num_trails = 0;
Trails.next = &Trails;
if (Trail_buffer_object < 0) {
Trail_buffer_object = gr_create_stream_buffer();
}
}
void trail_level_close()
@@ -450,8 +446,13 @@ void trail_render( trail * trailp )
Warning( LOCATION, "even number of verts in trail render\n" );
profile_begin("Trail Draw");
gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
//gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
//gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
material material_def;
material_set_unlit(&material_def, ti->texture.bitmap_id, 1.0f, true, true);
g3_render_primitives_colored_textured(&material_def, Trail_v_list, nv, PRIM_TYPE_TRISTRIP, false);
profile_end("Trail Draw");
}
+4 -7
View File
@@ -40,6 +40,7 @@
#include "radar/radar.h"
#include "radar/radarsetup.h"
#include "render/3d.h"
#include "render/batching.h"
#include "ship/ship.h"
#include "ship/shiphit.h"
#include "stats/scoring.h"
@@ -4500,7 +4501,7 @@ void weapon_maybe_play_flyby_sound(object *weapon_objp, weapon *wp)
return;
}
if ( !(wp->weapon_flags & WF_PLAYED_FLYBY_SOUND) && (wp->weapon_flags & WF_CONSIDER_FOR_FLYBY_SOUND) ) {
if ( !(wp->weapon_flags & WF_PLAYED_FLYBY_SOUND) ) {
float dist, dot, radius;
if ( (Weapon_info[wp->weapon_info_index].wi_flags & WIF_CORKSCREW) ) {
@@ -7190,11 +7191,8 @@ void weapon_render(object* obj, draw_list *scene)
vec3d headp;
vm_vec_scale_add(&headp, &obj->pos, &obj->orient.vec.fvec, wip->laser_length);
wp->weapon_flags &= ~WF_CONSIDER_FOR_FLYBY_SOUND;
if ( batch_add_laser(wip->laser_bitmap.first_frame + framenum, &headp, wip->laser_head_radius, &obj->pos, wip->laser_tail_radius, alpha, alpha, alpha) ) {
wp->weapon_flags |= WF_CONSIDER_FOR_FLYBY_SOUND;
}
batching_add_laser(wip->laser_bitmap.first_frame + framenum, &headp, wip->laser_head_radius, &obj->pos, wip->laser_tail_radius, alpha, alpha, alpha);
}
// maybe draw laser glow bitmap
@@ -7238,7 +7236,7 @@ void weapon_render(object* obj, draw_list *scene)
alpha = weapon_glow_alpha;
}
batch_add_laser(wip->laser_glow_bitmap.first_frame + framenum, &headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r, (c.red*alpha)/255, (c.green*alpha)/255, (c.blue*alpha)/255);
batching_add_laser(wip->laser_glow_bitmap.first_frame + framenum, &headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r, (c.red*alpha)/255, (c.green*alpha)/255, (c.blue*alpha)/255);
}
break;
@@ -7299,7 +7297,6 @@ void weapon_render(object* obj, draw_list *scene)
render_info.set_flags(render_flags);
model_render_queue(&render_info, scene, wip->model_num, &obj->orient, &obj->pos);
wp->weapon_flags |= WF_CONSIDER_FOR_FLYBY_SOUND;
break;
}
+22 -2
View File
@@ -69,6 +69,14 @@ std::unique_ptr<os::OpenGLContext> SDLGraphicsOperations::createOpenGLContext(co
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (attrs.multi_samples == 0) ? 0 : 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attrs.multi_samples);
const int gl_versions[] = { 41, 40, 33, 32, 31, 30, 21, 20 };
const int num_gl_versions = sizeof(gl_versions) / sizeof(int);
int version_index = 0;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_versions[version_index] / 10);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl_versions[version_index] % 10);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
mprintf((" Requested SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n",
attrs.red_size, attrs.green_size, attrs.blue_size, attrs.depth_size, attrs.stencil_size, 1, attrs.multi_samples));
@@ -88,9 +96,21 @@ std::unique_ptr<os::OpenGLContext> SDLGraphicsOperations::createOpenGLContext(co
os_set_window(window);
auto ctx = SDL_GL_CreateContext(os_get_window());
SDL_GLContext ctx;
if (ctx == nullptr) {
// find the latest and greatest OpenGL context
while ( (ctx = SDL_GL_CreateContext(os_get_window())) == NULL ) {
++version_index;
if ( version_index >= num_gl_versions ) {
return nullptr;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_versions[version_index] / 10);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl_versions[version_index] % 10);
}
if ( ctx == nullptr) {
Error(LOCATION, "Could not create OpenGL Context: %s\n", SDL_GetError());
return nullptr;
}
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more