mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 15:42:35 +00:00
Modern 'GL now renders properly, camera works as expected, added fallback to immediate mode if shader fails to compile.
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -1,5 +1,5 @@
|
|||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
gem "opengl-bindings"
|
gem "opengl-bindings", require: "opengl"
|
||||||
gem "cyberarm_engine"
|
gem "cyberarm_engine"
|
||||||
|
|
||||||
group(:packaging) do
|
group(:packaging) do
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class IMICFPS
|
|||||||
# Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen
|
# Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen
|
||||||
gluPerspective(@field_of_view, window.width / window.height, 0.1, @max_view_distance)
|
gluPerspective(@field_of_view, window.width / window.height, 0.1, @max_view_distance)
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
|
||||||
glRotatef(@orientation.z, 1, 0, 0)
|
glRotatef(@orientation.x, 1, 0, 0)
|
||||||
glRotatef(@orientation.y, 0, 1, 0)
|
glRotatef(@orientation.y, 0, 1, 0)
|
||||||
glTranslatef(-@position.x, -@position.y, -@position.z)
|
glTranslatef(-@position.x, -@position.y, -@position.z)
|
||||||
glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored.
|
glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored.
|
||||||
@@ -87,8 +87,8 @@ class IMICFPS
|
|||||||
@orientation.y -= delta
|
@orientation.y -= delta
|
||||||
@orientation.y %= 360.0
|
@orientation.y %= 360.0
|
||||||
|
|
||||||
@orientation.z -= Float(@true_mouse.y - self.mouse_y) / (@mouse_sensitivity * @field_of_view) * 70
|
@orientation.x -= Float(@true_mouse.y - self.mouse_y) / (@mouse_sensitivity * @field_of_view) * 70
|
||||||
@orientation.z = @orientation.z.clamp(-90.0, 90.0)
|
@orientation.x = @orientation.x.clamp(-90.0, 90.0)
|
||||||
|
|
||||||
if @entity
|
if @entity
|
||||||
@entity.orientation.y += delta
|
@entity.orientation.y += delta
|
||||||
@@ -170,27 +170,15 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def aspect_ratio
|
def aspect_ratio
|
||||||
window.width / window.height
|
window.width / window.height.to_f
|
||||||
end
|
end
|
||||||
|
|
||||||
def projection_matrix
|
def projection_matrix
|
||||||
fov = 1 / Math.tan(@field_of_view / 2) # field of view
|
Transform.perspective(@field_of_view, aspect_ratio, @min_view_distance, @max_view_distance)
|
||||||
zn = @max_view_distance - @min_view_distance # near plane
|
|
||||||
zf = @max_view_distance + @min_view_distance # far plane
|
|
||||||
z_num = -(2 * @max_view_distance * @min_view_distance) / zn # something
|
|
||||||
|
|
||||||
Transform.new(
|
|
||||||
[
|
|
||||||
fov / aspect_ratio, 0, 0, 0,
|
|
||||||
0, fov, 0, 0,
|
|
||||||
0, 0, -zf / zn, z_num,
|
|
||||||
0, 0, -1, 0
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def view_matrix
|
def view_matrix
|
||||||
Transform.identity# Transform.rotate_3d(@orientation) * Transform.translate_3d(@position)
|
Transform.translate_3d(@position * -1) * Transform.rotate_3d(@orientation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def model_matrix
|
def model_matrix
|
||||||
Transform.rotate_3d(@orientation) * Transform.translate_3d(@position)
|
Transform.rotate_3d(@orientation) * Transform.scale_3d(@scale) * Transform.translate_3d(@position)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
57
lib/model.rb
57
lib/model.rb
@@ -35,9 +35,11 @@ class IMICFPS
|
|||||||
|
|
||||||
puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if $debug.get(:stats)
|
puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if $debug.get(:stats)
|
||||||
|
|
||||||
allocate_gl_objects
|
if Shader.available?("default")
|
||||||
populate_vertex_buffer
|
allocate_gl_objects
|
||||||
configure_vao
|
populate_vertex_buffer
|
||||||
|
configure_vao
|
||||||
|
end
|
||||||
|
|
||||||
@objects.each {|o| @vertex_count+=o.vertices.size}
|
@objects.each {|o| @vertex_count+=o.vertices.size}
|
||||||
@objects.each_with_index do |o, i|
|
@objects.each_with_index do |o, i|
|
||||||
@@ -119,14 +121,14 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def populate_vertex_buffer
|
def populate_vertex_buffer
|
||||||
verts = []
|
pos = []
|
||||||
colors = []
|
colors = []
|
||||||
norms = []
|
norms = []
|
||||||
uvs = []
|
uvs = []
|
||||||
tex_ids = []
|
tex_ids = []
|
||||||
|
|
||||||
@faces.each do |face|
|
@faces.each do |face|
|
||||||
verts << face.vertices.map { |vert| [vert.x, vert.y, vert.z] }
|
pos << face.vertices.map { |vert| [vert.x, vert.y, vert.z] }
|
||||||
colors << face.colors.map { |vert| [vert.x, vert.y, vert.z] }
|
colors << face.colors.map { |vert| [vert.x, vert.y, vert.z] }
|
||||||
norms << face.normals.map { |vert| [vert.x, vert.y, vert.z, vert.weight] }
|
norms << face.normals.map { |vert| [vert.x, vert.y, vert.z, vert.weight] }
|
||||||
|
|
||||||
@@ -137,20 +139,20 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id)
|
||||||
glBufferData(GL_ARRAY_BUFFER, 3 * verts.size * Fiddle::SIZEOF_FLOAT, verts.flatten.pack("f*"), GL_STATIC_DRAW)
|
glBufferData(GL_ARRAY_BUFFER, pos.flatten.size * Fiddle::SIZEOF_FLOAT, pos.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @colors_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @colors_buffer_id)
|
||||||
glBufferData(GL_ARRAY_BUFFER, 3 * colors.size * Fiddle::SIZEOF_FLOAT, colors.flatten.pack("f*"), GL_STATIC_DRAW)
|
glBufferData(GL_ARRAY_BUFFER, colors.flatten.size * Fiddle::SIZEOF_FLOAT, colors.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
||||||
glBufferData(GL_ARRAY_BUFFER, 4 * norms.size * Fiddle::SIZEOF_FLOAT, norms.flatten.pack("f*"), GL_STATIC_DRAW)
|
glBufferData(GL_ARRAY_BUFFER, norms.flatten.size * Fiddle::SIZEOF_FLOAT, norms.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||||
|
|
||||||
if has_texture?
|
if has_texture?
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||||
glBufferData(GL_ARRAY_BUFFER, 3 * uvs.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW)
|
glBufferData(GL_ARRAY_BUFFER, uvs.flatten.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
||||||
glBufferData(GL_ARRAY_BUFFER, 1 * tex_ids.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW)
|
glBufferData(GL_ARRAY_BUFFER, tex_ids.flatten.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||||
end
|
end
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||||
@@ -159,12 +161,6 @@ class IMICFPS
|
|||||||
def configure_vao
|
def configure_vao
|
||||||
glBindVertexArray(@vertex_array_id)
|
glBindVertexArray(@vertex_array_id)
|
||||||
|
|
||||||
glEnableVertexAttribArray(0)
|
|
||||||
glEnableVertexAttribArray(1)
|
|
||||||
glEnableVertexAttribArray(2)
|
|
||||||
glEnableVertexAttribArray(3)
|
|
||||||
glEnableVertexAttribArray(4)
|
|
||||||
|
|
||||||
program = Shader.get("default").program
|
program = Shader.get("default").program
|
||||||
|
|
||||||
# index, size, type, normalized, stride, pointer
|
# index, size, type, normalized, stride, pointer
|
||||||
@@ -180,20 +176,17 @@ class IMICFPS
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
||||||
glVertexAttribPointer(glGetAttribLocation(program, "inNormal"), 4, GL_FLOAT, GL_FALSE, 0, nil)
|
glVertexAttribPointer(glGetAttribLocation(program, "inNormal"), 4, GL_FLOAT, GL_FALSE, 0, nil)
|
||||||
handleGlError
|
handleGlError
|
||||||
# uvs
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
|
||||||
glVertexAttribPointer(glGetAttribLocation(program, "inUV"), 3, GL_FLOAT, GL_FALSE, 0, nil)
|
|
||||||
handleGlError
|
|
||||||
# texture ids
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
|
||||||
glVertexAttribPointer(glGetAttribLocation(program, "inTextureID"), 1, GL_FLOAT, GL_FALSE, 0, nil)
|
|
||||||
handleGlError
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(4)
|
if has_texture?
|
||||||
glDisableVertexAttribArray(3)
|
# uvs
|
||||||
glDisableVertexAttribArray(2)
|
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||||
glDisableVertexAttribArray(1)
|
glVertexAttribPointer(glGetAttribLocation(program, "inUV"), 3, GL_FLOAT, GL_FALSE, 0, nil)
|
||||||
glDisableVertexAttribArray(0)
|
handleGlError
|
||||||
|
# texture ids
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(program, "inTextureID"), 1, GL_FLOAT, GL_FALSE, 0, nil)
|
||||||
|
handleGlError
|
||||||
|
end
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||||
glBindVertexArray(0)
|
glBindVertexArray(0)
|
||||||
@@ -201,6 +194,7 @@ class IMICFPS
|
|||||||
|
|
||||||
def build_collision_tree
|
def build_collision_tree
|
||||||
@aabb_tree = AABBTree.new
|
@aabb_tree = AABBTree.new
|
||||||
|
|
||||||
@faces.each do |face|
|
@faces.each do |face|
|
||||||
box = BoundingBox.new
|
box = BoundingBox.new
|
||||||
box.min = face.vertices.first.dup
|
box.min = face.vertices.first.dup
|
||||||
@@ -215,10 +209,11 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
# FIXME: Handle negatives
|
# FIXME: Handle negatives
|
||||||
box.min -= Vector.new(-0.1, -0.1, -0.1)
|
box.min *= 1.5
|
||||||
box.max += Vector.new( 0.1, 0.1, 0.1)
|
box.max *= 1.5
|
||||||
@aabb_tree.insert(face, box)
|
@aabb_tree.insert(face, box)
|
||||||
end
|
end
|
||||||
|
|
||||||
puts @aabb_tree.inspect if $debug.get(:stats)
|
puts @aabb_tree.inspect if $debug.get(:stats)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,17 @@ class IMICFPS
|
|||||||
class OpenGLRenderer
|
class OpenGLRenderer
|
||||||
include CommonMethods
|
include CommonMethods
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@immediate_mode_warning = false
|
||||||
|
end
|
||||||
|
|
||||||
def draw_object(camera, lights, object)
|
def draw_object(camera, lights, object)
|
||||||
if Shader.available?("default")
|
if Shader.available?("default")
|
||||||
Shader.use("default") do |shader|
|
Shader.use("default") do |shader|
|
||||||
shader.set_uniform("projection", camera.projection_matrix)
|
shader.set_uniform("projection", camera.projection_matrix)
|
||||||
shader.set_uniform("view", camera.view_matrix)
|
shader.set_uniform("view", camera.view_matrix)
|
||||||
shader.set_uniform("model", object.model_matrix)
|
shader.set_uniform("model", object.model_matrix)
|
||||||
|
shader.set_uniform("hasTexture", object.model.has_texture?)
|
||||||
|
|
||||||
# TODO: Upload and use lights
|
# TODO: Upload and use lights
|
||||||
|
|
||||||
@@ -16,10 +21,12 @@ class IMICFPS
|
|||||||
object.draw
|
object.draw
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @immediate_mode_warning
|
||||||
|
@immediate_mode_warning = true
|
||||||
|
|
||||||
handleGlError
|
handleGlError
|
||||||
lights.each(&:draw)
|
lights.each(&:draw)
|
||||||
camera.draw
|
camera.draw
|
||||||
glEnable(GL_DEPTH_TEST)
|
|
||||||
|
|
||||||
glEnable(GL_NORMALIZE)
|
glEnable(GL_NORMALIZE)
|
||||||
glPushMatrix
|
glPushMatrix
|
||||||
@@ -44,14 +51,18 @@ class IMICFPS
|
|||||||
glEnableVertexAttribArray(0)
|
glEnableVertexAttribArray(0)
|
||||||
glEnableVertexAttribArray(1)
|
glEnableVertexAttribArray(1)
|
||||||
glEnableVertexAttribArray(2)
|
glEnableVertexAttribArray(2)
|
||||||
glEnableVertexAttribArray(3)
|
if model.has_texture?
|
||||||
glEnableVertexAttribArray(4)
|
glEnableVertexAttribArray(3)
|
||||||
|
glEnableVertexAttribArray(4)
|
||||||
|
end
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, model.vertices.count)
|
glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3)
|
||||||
window.number_of_vertices+=model.vertices.size
|
window.number_of_vertices += model.faces.count * 3
|
||||||
|
|
||||||
glDisableVertexAttribArray(4)
|
if model.has_texture?
|
||||||
glDisableVertexAttribArray(3)
|
glDisableVertexAttribArray(4)
|
||||||
|
glDisableVertexAttribArray(3)
|
||||||
|
end
|
||||||
glDisableVertexAttribArray(2)
|
glDisableVertexAttribArray(2)
|
||||||
glDisableVertexAttribArray(1)
|
glDisableVertexAttribArray(1)
|
||||||
glDisableVertexAttribArray(0)
|
glDisableVertexAttribArray(0)
|
||||||
@@ -80,9 +91,6 @@ class IMICFPS
|
|||||||
glColorPointer(3, GL_FLOAT, 0, o.flattened_materials)
|
glColorPointer(3, GL_FLOAT, 0, o.flattened_materials)
|
||||||
glNormalPointer(GL_FLOAT, 0, o.flattened_normals)
|
glNormalPointer(GL_FLOAT, 0, o.flattened_normals)
|
||||||
|
|
||||||
# glBindBuffer(GL_ARRAY_BUFFER, model.vertices_buffer)
|
|
||||||
# glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
|
|
||||||
|
|
||||||
if $debug.get(:wireframe) # This is kinda expensive
|
if $debug.get(:wireframe) # This is kinda expensive
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def draw(camera, lights, entities)
|
def draw(camera, lights, entities)
|
||||||
|
glViewport(0, 0, window.width, window.height)
|
||||||
|
glEnable(GL_DEPTH_TEST)
|
||||||
|
|
||||||
entities.each do |object|
|
entities.each do |object|
|
||||||
if object.visible && object.renderable
|
if object.visible && object.renderable
|
||||||
# Render bounding boxes before transformation is applied
|
# Render bounding boxes before transformation is applied
|
||||||
|
|||||||
@@ -61,11 +61,12 @@ OpenGL Renderer: #{glGetString(GL_RENDERER)}
|
|||||||
OpenGL Version: #{glGetString(GL_VERSION)}
|
OpenGL Version: #{glGetString(GL_VERSION)}
|
||||||
OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)}
|
OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)}
|
||||||
|
|
||||||
Camera pitch: #{@camera.orientation.z.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.x.round(2)}
|
Camera Pitch: #{@camera.orientation.x.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.z.round(2)}
|
||||||
Camera X:#{@camera.position.x.round(2)} Y:#{@camera.position.y.round(2)} Z:#{@camera.position.z.round(2)}
|
Camera X: #{@camera.position.x.round(2)} Y: #{@camera.position.y.round(2)} Z: #{@camera.position.z.round(2)}
|
||||||
#{if @camera.entity then "Actor X:#{@camera.entity.position.x.round(2)} Y:#{@camera.entity.position.y.round(2)} Z:#{@camera.entity.position.z.round(2)}";end}
|
Camera Field Of View: #{@camera.field_of_view}
|
||||||
Field Of View: #{@camera.field_of_view}
|
Camera Mouse Sesitivity: #{@camera.mouse_sensitivity}
|
||||||
Mouse Sesitivity: #{@camera.mouse_sensitivity}
|
|
||||||
|
#{if @camera.entity then "Actor X: #{@camera.entity.position.x.round(2)} Y: #{@camera.entity.position.y.round(2)} Z: #{@camera.entity.position.z.round(2)}";end}
|
||||||
Last Frame: #{Gosu.milliseconds - window.delta_time}ms (#{Gosu.fps} fps)
|
Last Frame: #{Gosu.milliseconds - window.delta_time}ms (#{Gosu.fps} fps)
|
||||||
|
|
||||||
Vertices: #{formatted_number(window.number_of_vertices)}
|
Vertices: #{formatted_number(window.number_of_vertices)}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# version 330 core
|
# version 330 core
|
||||||
|
|
||||||
|
in vec3 outPosition;
|
||||||
in vec3 outColor;
|
in vec3 outColor;
|
||||||
in vec4 outNormal;
|
in vec4 outNormal;
|
||||||
in vec3 outUV;
|
in vec3 outUV;
|
||||||
@@ -11,5 +12,5 @@ vec4 lokiVar;
|
|||||||
void main() {
|
void main() {
|
||||||
lokiVar = vec4(outColor, 1.0) + outNormal + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0);
|
lokiVar = vec4(outColor, 1.0) + outNormal + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0);
|
||||||
lokiVar = normalize(lokiVar);
|
lokiVar = normalize(lokiVar);
|
||||||
gl_FragColor = vec4(lokiVar);
|
gl_FragColor = vec4(outColor, 1.0);
|
||||||
}
|
}
|
||||||
@@ -6,21 +6,26 @@ layout(location = 2) in vec4 inNormal;
|
|||||||
layout(location = 3) in vec3 inUV;
|
layout(location = 3) in vec3 inUV;
|
||||||
layout(location = 4) in float inTextureID;
|
layout(location = 4) in float inTextureID;
|
||||||
|
|
||||||
|
out vec3 outPosition;
|
||||||
out vec3 outColor;
|
out vec3 outColor;
|
||||||
out vec4 outNormal;
|
out vec4 outNormal;
|
||||||
out vec3 outUV;
|
out vec3 outUV;
|
||||||
out float outTextureID;
|
out float outTextureID;
|
||||||
|
out float outHasTexture;
|
||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
|
uniform int hasTexture;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// projection * view * model * position
|
// projection * view * model * position
|
||||||
|
outPosition = inPosition;
|
||||||
outColor = inColor;
|
outColor = inColor;
|
||||||
outNormal= inNormal;
|
outNormal= inNormal;
|
||||||
outUV = inUV;
|
outUV = inUV;
|
||||||
outTextureID = inTextureID;
|
outTextureID = inTextureID;
|
||||||
|
outHasTexture = hasTexture;
|
||||||
|
|
||||||
gl_Position = projection * view * model * vec4(inPosition, 1.0);
|
gl_Position = projection * view * model * vec4(inPosition, 1.0);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user