View Issue Details

IDProjectCategoryView StatusLast Update
0002395FSSCPOpenGLpublic2012-05-02 11:35
Reportercasual pilot Assigned ToThe_E  
PriorityhighSeveritymajorReproducibilityalways
Status resolvedResolutionreopened 
Product Version3.6.14 
Target Version3.6.14 
Summary0002395: Some models partially invisible
DescriptionSome models such as the Deimos and Sathanas are only partially rendered with many (most?) polygons missing.
Additional InformationLinux, r200 DRI driver (Radeon 9250).

Redefining DO_RENDER in code/graphics/gropengltnl.cpp to use glDrawElements instead of glDrawRangeElements appears to solve the problem (see attached patch). Hence I suspect that incorrect start and end values were given to glDrawRangeElements. That is an error in OpenGL with no diagnostic required, so some implementations may render as intended while others don't.
TagsNo tags attached.

Activities

2011-02-09 19:42

 

fso-rendering.patch (576 bytes)   
diff --git a/code/graphics/gropengltnl.cpp b/code/graphics/gropengltnl.cpp
index cc93dca..622d2c3 100644
--- a/code/graphics/gropengltnl.cpp
+++ b/code/graphics/gropengltnl.cpp
@@ -496,7 +496,7 @@ static void opengl_init_arrays(opengl_vertex_buffer *vbp, const vertex_buffer *b
 }
 
 #define DO_RENDER()	\
-	vglDrawRangeElements(GL_TRIANGLES, start, end, count, element_type, ibuffer + (datap->index_offset + start))
+	glDrawElements(GL_TRIANGLES, count, element_type, ibuffer + (datap->index_offset + start))
 
 int GL_last_shader_flags = -1;
 int GL_last_shader_index = -1;
fso-rendering.patch (576 bytes)   

The_E

2011-06-28 20:21

administrator   ~0012736

Fixed in revision 7289, by introducing a commandline flag (-use_gldrawelements) to switch between using glDrawElements and glDrawRangeElements, since the latter is noticeably faster.

casual pilot

2012-03-02 22:36

reporter   ~0013372

I have since verified that incorrect start and end values are indeed passed to glDrawRangeElements. Being unfamiliar with the model data structures I did not find an immediate way to obtain the actual range of vertex indices present in the array being drawn. Nevertheless, I did manage a crude fix by modifying buffer_data to keep track of the index range.

casual pilot

2012-03-02 22:38

reporter  

fso-vertex-range.patch (3,678 bytes)   
commit ff948a089ca61a60d8aabf225ae70993e65ba852
Author: Timo Korvola <tkorvola@iki.fi>
Date:   Tue Feb 21 23:11:48 2012 +0200

    Record the minimum and maximum indices when creating index buffers.
    
    The bounds can then be used in glDrawRangeElements, which appears
    somewhat faster than glDrawElements.
    
    Conflicts:
    
    	code/graphics/gropengltnl.cpp

diff --git a/code/graphics/2d.h b/code/graphics/2d.h
index e55f65e..92eebbf 100644
--- a/code/graphics/2d.h
+++ b/code/graphics/2d.h
@@ -109,7 +109,12 @@ struct buffer_data {
 
 	size_t index_offset;
 
-	uint *index;
+	const uint *get_index() const
+	{
+		return index;
+	}
+	
+        uint i_first, i_last;
 
 	void release()
 	{
@@ -119,10 +124,26 @@ struct buffer_data {
 		}
 	}
 
-	buffer_data() :
-		flags(0), texture(-1), n_verts(0), index_offset(0), index(NULL)
+	void assign(int i, uint j)
+	{
+		const_cast<uint *>(index)[i] = j;
+		if (i_first > i_last)
+			i_first = i_last = j;
+		else if (i_first > j)
+			i_first = j;
+		else if (i_last < j)
+			i_last = j;
+	}
+
+	buffer_data(int n_vrts) :
+		flags(0), texture(-1), n_verts(n_vrts), index_offset(0),
+		i_first(1), i_last(0)
 	{
+		index = new(std::nothrow) uint[n_verts];
 	}
+
+private:
+	uint *index;
 };
 
 struct vertex_buffer {
diff --git a/code/graphics/gropengltnl.cpp b/code/graphics/gropengltnl.cpp
index 6a07156..eeed02c 100644
--- a/code/graphics/gropengltnl.cpp
+++ b/code/graphics/gropengltnl.cpp
@@ -357,7 +357,7 @@ bool gr_opengl_pack_buffer(const int buffer_id, vertex_buffer *vb)
 	for (j = 0; j < vb->tex_buf.size(); j++) {
 		n_verts = vb->tex_buf[j].n_verts;
 		uint offset = vb->tex_buf[j].index_offset;
-		uint *index = vb->tex_buf[j].index;
+		const uint *index = vb->tex_buf[j].get_index();
 
 		// bump to our spot in the buffer
 		GLubyte *ibuf = m_vbp->index_list + offset;
@@ -494,7 +494,7 @@ static void opengl_init_arrays(opengl_vertex_buffer *vbp, const vertex_buffer *b
 	if (Cmdline_drawelements) \
 		glDrawElements(GL_TRIANGLES, count, element_type, ibuffer + (datap->index_offset + start)); \
 	else \
-		vglDrawRangeElements(GL_TRIANGLES, start, end, count, element_type, ibuffer + (datap->index_offset + start));
+		vglDrawRangeElements(GL_TRIANGLES, datap->i_first, datap->i_last, count, element_type, ibuffer + (datap->index_offset + start));
 
 int GL_last_shader_flags = -1;
 int GL_last_shader_index = -1;
diff --git a/code/model/modelinterp.cpp b/code/model/modelinterp.cpp
index 92c073f..d9aa672 100644
--- a/code/model/modelinterp.cpp
+++ b/code/model/modelinterp.cpp
@@ -4245,22 +4245,21 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
 		if ( !polygon_list[i].n_verts )
 			continue;
 
-		buffer_data new_buffer;
+		buffer_data new_buffer(polygon_list[i].n_verts);
 
-		new_buffer.index = new(std::nothrow) uint[polygon_list[i].n_verts];
-		Verify( new_buffer.index != NULL );
+		Verify( new_buffer.get_index() != NULL );
 
 		for (j = 0; j < polygon_list[i].n_verts; j++) {
 			if (ibuffer_info.read != NULL) {
 				first_index = cfread_int(ibuffer_info.read);
 				Assert( first_index >= 0 );
 
-				new_buffer.index[j] = (uint)first_index;
+				new_buffer.assign(j, first_index);
 			} else {
 				first_index = model_list->find_index(&polygon_list[i], j);
 				Assert(first_index != -1);
 
-				new_buffer.index[j] = (uint)first_index;
+				new_buffer.assign(j, first_index);
 
 				if (ibuffer_info.write != NULL) {
 					cfwrite_int(first_index, ibuffer_info.write);
@@ -4268,7 +4267,6 @@ void interp_configure_vertex_buffers(polymodel *pm, int mn)
 			}
 		}
 
-		new_buffer.n_verts = polygon_list[i].n_verts;
 		new_buffer.texture = i;
 
 		new_buffer.flags = 0;
fso-vertex-range.patch (3,678 bytes)   

Echelon9

2012-03-03 00:31

developer   ~0013374

This is a big issue, thanks for debugging.

Can we get that patch as a standard diff? I'd like to look into this more.

casual pilot

2012-03-03 08:55

reporter   ~0013375

Sorry, I don't understand what you mean by standard diff. patch -p1 seems to work fine on the attached patch.

The_E

2012-03-03 08:57

administrator   ~0013376

The problem is, you are attaching a git patch when we are using svn.

casual pilot

2012-03-03 09:37

reporter  

fso-vertex-range-svn.patch (3,087 bytes)   
Index: code/graphics/gropengltnl.cpp
===================================================================
--- code/graphics/gropengltnl.cpp	(revision 8555)
+++ code/graphics/gropengltnl.cpp	(working copy)
@@ -357,7 +357,7 @@
 	for (j = 0; j < vb->tex_buf.size(); j++) {
 		n_verts = vb->tex_buf[j].n_verts;
 		uint offset = vb->tex_buf[j].index_offset;
-		uint *index = vb->tex_buf[j].index;
+		const uint *index = vb->tex_buf[j].get_index();
 
 		// bump to our spot in the buffer
 		GLubyte *ibuf = m_vbp->index_list + offset;
@@ -494,7 +494,7 @@
 	if (Cmdline_drawelements) \
 		glDrawElements(GL_TRIANGLES, count, element_type, ibuffer + (datap->index_offset + start)); \
 	else \
-		vglDrawRangeElements(GL_TRIANGLES, start, end, count, element_type, ibuffer + (datap->index_offset + start));
+		vglDrawRangeElements(GL_TRIANGLES, datap->i_first, datap->i_last, count, element_type, ibuffer + (datap->index_offset + start));
 
 int GL_last_shader_flags = -1;
 int GL_last_shader_index = -1;
Index: code/graphics/2d.h
===================================================================
--- code/graphics/2d.h	(revision 8555)
+++ code/graphics/2d.h	(working copy)
@@ -109,7 +109,12 @@
 
 	size_t index_offset;
 
-	uint *index;
+	const uint *get_index() const
+	{
+		return index;
+	}
+	
+        uint i_first, i_last;
 
 	void release()
 	{
@@ -119,10 +124,26 @@
 		}
 	}
 
-	buffer_data() :
-		flags(0), texture(-1), n_verts(0), index_offset(0), index(NULL)
+	void assign(int i, uint j)
 	{
+		const_cast<uint *>(index)[i] = j;
+		if (i_first > i_last)
+			i_first = i_last = j;
+		else if (i_first > j)
+			i_first = j;
+		else if (i_last < j)
+			i_last = j;
 	}
+
+	buffer_data(int n_vrts) :
+		flags(0), texture(-1), n_verts(n_vrts), index_offset(0),
+		i_first(1), i_last(0)
+	{
+		index = new(std::nothrow) uint[n_verts];
+	}
+
+private:
+	uint *index;
 };
 
 struct vertex_buffer {
Index: code/model/modelinterp.cpp
===================================================================
--- code/model/modelinterp.cpp	(revision 8555)
+++ code/model/modelinterp.cpp	(working copy)
@@ -4244,22 +4244,21 @@
 		if ( !polygon_list[i].n_verts )
 			continue;
 
-		buffer_data new_buffer;
+		buffer_data new_buffer(polygon_list[i].n_verts);
 
-		new_buffer.index = new(std::nothrow) uint[polygon_list[i].n_verts];
-		Verify( new_buffer.index != NULL );
+		Verify( new_buffer.get_index() != NULL );
 
 		for (j = 0; j < polygon_list[i].n_verts; j++) {
 			if (ibuffer_info.read != NULL) {
 				first_index = cfread_int(ibuffer_info.read);
 				Assert( first_index >= 0 );
 
-				new_buffer.index[j] = (uint)first_index;
+				new_buffer.assign(j, first_index);
 			} else {
 				first_index = model_list->find_index(&polygon_list[i], j);
 				Assert(first_index != -1);
 
-				new_buffer.index[j] = (uint)first_index;
+				new_buffer.assign(j, first_index);
 
 				if (ibuffer_info.write != NULL) {
 					cfwrite_int(first_index, ibuffer_info.write);
@@ -4267,7 +4266,6 @@
 			}
 		}
 
-		new_buffer.n_verts = polygon_list[i].n_verts;
 		new_buffer.texture = i;
 
 		new_buffer.flags = 0;
fso-vertex-range-svn.patch (3,087 bytes)   

casual pilot

2012-03-03 09:38

reporter   ~0013377

That should not be a problem, because the unified diff format used by both is well established. Nevertheless, here is a version computed with svn diff against the current trunk.

The_E

2012-03-05 12:01

administrator   ~0013389

Fix committed to trunk@8577.

niffiwan

2012-05-02 11:35

developer   ~0013500

Fix committed to fs2_open_3_6_14@8716.

Related Changesets

fs2open: trunk r8577

2012-03-05 07:01

The_E


Ported: N/A

Details Diff
From casual_pilot: Fix for Mantis 2395 (incorrect index values passed to OpenGL) Affected Issues
0002395
mod - /trunk/fs2_open/code/model/modelinterp.cpp Diff File
mod - /trunk/fs2_open/code/graphics/gropengltnl.cpp Diff File
mod - /trunk/fs2_open/code/graphics/2d.h Diff File

fs2open: fs2_open_3_6_14 r8716

2012-05-02 07:36

niffiwan


Ported: N/A

Details Diff
Backport: Trunk r8577; From casual_pilot: Fix for Mantis 2395 (incorrect index values passed to OpenGL) Affected Issues
0002395
mod - /branches/fs2_open_3_6_14/code/model/modelinterp.cpp Diff File
mod - /branches/fs2_open_3_6_14/code/graphics/gropengltnl.cpp Diff File
mod - /branches/fs2_open_3_6_14/code/graphics/2d.h Diff File

Issue History

Date Modified Username Field Change
2011-02-09 19:42 casual pilot New Issue
2011-02-09 19:42 casual pilot File Added: fso-rendering.patch
2011-06-28 20:21 The_E Note Added: 0012736
2011-06-28 20:21 The_E Status new => resolved
2011-06-28 20:21 The_E Fixed in Version => 3.6.13
2011-06-28 20:21 The_E Resolution open => fixed
2011-06-28 20:21 The_E Assigned To => The_E
2012-03-02 22:36 casual pilot Note Added: 0013372
2012-03-02 22:36 casual pilot Status resolved => feedback
2012-03-02 22:36 casual pilot Resolution fixed => reopened
2012-03-02 22:38 casual pilot File Added: fso-vertex-range.patch
2012-03-03 00:31 Echelon9 Note Added: 0013374
2012-03-03 00:32 Echelon9 Priority normal => high
2012-03-03 00:32 Echelon9 Product Version 3.6.12 => 3.6.14
2012-03-03 00:32 Echelon9 Fixed in Version 3.6.13 =>
2012-03-03 00:32 Echelon9 Target Version => 3.6.14
2012-03-03 08:55 casual pilot Note Added: 0013375
2012-03-03 08:55 casual pilot Status feedback => assigned
2012-03-03 08:57 The_E Note Added: 0013376
2012-03-03 09:37 casual pilot File Added: fso-vertex-range-svn.patch
2012-03-03 09:38 casual pilot Note Added: 0013377
2012-03-05 12:01 The_E Changeset attached => fs2open trunk r8577
2012-03-05 12:01 The_E Note Added: 0013389
2012-03-05 12:01 The_E Status assigned => resolved
2012-05-02 11:35 niffiwan Changeset attached => fs2open fs2_open_3_6_14 r8716
2012-05-02 11:35 niffiwan Note Added: 0013500