Importing and Displaying .fbx files in OpenGl - c++

I have been trying to import and display an fbx file using the FBX SDK.Untill. I managed to load in the file, but I got stuck at the part where I have to display it.
The questions:
What exactly are those indices?
How should I display the vertices?
Here is the class that I made:
3dModelBasicStructs.h
struct vertex
{
float x,y,z;
};
struct texturecoords
{
float a,b;
};
struct poligon
{
int a,b,c;
};
Model.h
#ifndef MODEL_H
#define MODEL_H
#define FBXSDK_NEW_API
#define MAX_VERTICES 80000
#define MAX_POLIGONS 80000
#include <fbxsdk.h>
#include "3dModelBasicStructs.h"
#include <iostream>
#include <GL/glut.h>
using namespace std;
class Model
{
public:
Model(char*);
~Model();
void ShowDetails();
char* GetModelName();
void SetModelName( char* );
void GetFbxInfo( FbxNode* );
void RenderModel();
void InitializeVertexBuffer( vertex* );
private:
char Name[25];
vertex vertices[MAX_VERTICES];
poligon poligons[MAX_POLIGONS];
int *indices;
int numIndices;
int numVertices;
};
#endif
Model.cpp
#include "Model.h"
Model::Model(char *filename)
{
cout<<"\nA model has been built!";
numVertices=0;
numIndices=0;
FbxManager *manager = FbxManager::Create();
FbxIOSettings *ioSettings = FbxIOSettings::Create(manager, IOSROOT);
manager->SetIOSettings(ioSettings);
FbxImporter *importer=FbxImporter::Create(manager,"");
importer->Initialize(filename,-1,manager->GetIOSettings());
FbxScene *scene = FbxScene::Create(manager,"tempName");
importer->Import(scene);
importer->Destroy();
FbxNode* rootNode = scene->GetRootNode();
this->SetModelName(filename);
if(rootNode) { this->GetFbxInfo(rootNode); }
}
Model::~Model()
{
cout<<"\nA model has been destroied!";
}
void Model::ShowDetails()
{
cout<<"\nName:"<<Name;
cout<<"\nVertices Number:"<<numVertices;
cout<<"\nIndices which i never get:"<<indices;
}
char* Model::GetModelName()
{
return Name;
}
void Model::SetModelName(char *x)
{
strcpy(Name,x);
}
void Model::GetFbxInfo( FbxNode* Node )
{
int numKids = Node->GetChildCount();
FbxNode *childNode = 0;
for ( int i=0 ; i<numKids ; i++)
{
childNode = Node->GetChild(i);
FbxMesh *mesh = childNode->GetMesh();
if ( mesh != NULL)
{
//================= Get Vertices ====================================
int numVerts = mesh->GetControlPointsCount();
for ( int j=0; j<numVerts; j++)
{
FbxVector4 vert = mesh->GetControlPointAt(j);
vertices[numVertices].x=(float)vert.mData[0];
vertices[numVertices].y=(float)vert.mData[1];
vertices[numVertices++].z=(float)vert.mData[2];
cout<<"\n"<<vertices[numVertices-1].x<<" "<<vertices[numVertices- 1].y<<" "<<vertices[numVertices-1].z;
this->InitializeVertexBuffer(vertices);
}
//================= Get Indices ====================================
int *indices = mesh->GetPolygonVertices();
numIndices+=mesh->GetPolygonVertexCount();
}
this->GetFbxInfo(childNode);
}
}
void Model::RenderModel()
{
glDrawElements(GL_TRIANGLES,36,GL_INT,indices);
}
void Model::InitializeVertexBuffer(vertex *vertices)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vertices);
//glDrawArrays(GL_TRIANGLES,0,36);
}
Sadly , When i try to use drawelements i get this error:
Unhandled exception at 0x77e215de in A new begging.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.

2) How should I display the vertices?
Questions like these indicate, that you should work through some OpenGL tutorials. Those are the basics and you need to know them.
This is a good start regarding your problem, but you'll need to work through the whole tutorial
http://opengl.datenwolf.net/gltut/html/Basics/Tut01%20Following%20the%20Data.html
1) What exactly are those indices ?
You have a list of vertices. The index of a vertex is the position at which it is in that list. You can draw vertex arrays by its indices using glDrawElements
Update due to comment
Say you have a cube with shared vertices (uncommon in OpenGL, but I'm too lazy for writing down 24 vertices).
I have them in my program in an array, that forms a list of their positions. You load them from a file, I'm writing them a C array:
GLfloat vertices[3][] = {
{-1,-1, 1},
{ 1,-1, 1},
{ 1, 1, 1},
{-1, 1, 1},
{-1,-1,-1},
{ 1,-1,-1},
{ 1, 1,-1},
{-1, 1,-1},
};
This gives the vertices indices (position in the array), in the picture it looks like
To draw a cube we have to tell OpenGL in which vertices, in which order make a face. So let's have a look at the faces:
We're going to build that cube out of triangles. 3 consecutive indices make up a triangle. For the cube this is
GLuint face_indices[3][] = {
{0,1,2},{2,3,0},
{1,5,6},{6,2,1},
{5,4,7},{7,6,5},
{4,0,3},{3,7,4},
{3,2,6},{6,7,2},
{4,5,0},{1,0,5}
};
You can draw this then by pointing OpenGL to the vertex array
glVertexPointer(3, GL_FLOAT, 0, &vertices[0][0]);
and issuing a batches call on the array with vertices. There are 6*2 = 12 triangles, each triangle consisting of 3 vertices, which makes a list of 36 indices.
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, &face_indices[0][0]);

Related

Meshes loaded via Assimp look distorted

So I'm trying to load and render mesh with assimp and DirectX11.(Im loosely following tutorials on youtube) The problem is that it looks weird and distorted. I've checked my meshes - blender and assimp viewer load them correctly.
Results of rendering suzanne from obj file:
Suzanne from obj file
It looks kinda like the index buffer is wrong but i do not see a mistake when propagating it;
Mesh loading code:
struct Vertex
{
struct
{
float x;
float y;
float z;
}Position;
};
Model::Model(const std::string & path)
{
Ref<Zephyr::VertexShader> VertexShader = Zephyr::VertexShader::Create("MinimalShaders.hlsl", "VertexShaderMain");
AddBindable(VertexShader);
AddBindable(Zephyr::PixelShader::Create("MinimalShaders.hlsl", "PixelShaderMain"));
AddBindable(Zephyr::Topology::Create(Zephyr::Topology::TopologyType::TriangleList));
std::vector<Zephyr::InputLayout::InputLayoutElement> InputLayout =
{
{"Position",Zephyr::InputLayout::InputDataType::Float3}
};
AddBindable(Zephyr::InputLayout::Create(InputLayout, VertexShader));
Assimp::Importer Imp;
auto model = Imp.ReadFile(path, aiProcess_JoinIdenticalVertices | aiProcess_Triangulate);
const auto Mesh = model->mMeshes[0];
std::vector<Vertex> Vertices;
Vertices.reserve(Mesh->mNumVertices);
for (unsigned int i = 0; i < Mesh->mNumVertices; i++)
{
Vertex buf;
buf.Position = { Mesh->mVertices[i].x,Mesh->mVertices[i].y ,Mesh->mVertices[i].z };
Vertices.push_back(buf);
}
std::vector<unsigned short> Indices;
Indices.reserve(Mesh->mNumFaces * 3);
for (unsigned int i = 0; i < Mesh->mNumFaces; i++)
{
const auto & face = Mesh->mFaces[i];
if (face.mNumIndices != 3)
{
Zephyr::Log::Error("More than 3 indices per face ?!"); continue;
}
Indices.push_back(face.mIndices[0]);
Indices.push_back(face.mIndices[1]);
Indices.push_back(face.mIndices[2]);
}
AddBindable(Zephyr::VertexBuffer::Create(Vertices));
BindIndexBuffer(Zephyr::IndexBuffer::Create(Indices));
}
My shaders are pretty minimal to
cbuffer CBuff
{
matrix transform;
};
float4 VertexShaderMain(float3 position : Position) : SV_POSITION
{
return mul(float4(position, 1.0), transform);
}
float4 PixelShaderMain() : SV_TARGET
{
return float4(1.0,1.0,1.0,1.0);
}
My pipeline renders correctly, f. ex. cubes which are hard coded, but when i try to load cube from file this happens:
distorted cube
Assimp opens the file and loads the correct number of vertices. Also number of indices seems to be ok(for cube there are 12 triangles and 36 indices)
Honestly at this point I have no idea what im doing wrong. Am i missing sth obvious?
Thanks in advance
So I've figured it out. The issue was that in some other file i already defined structure named Vertex. That structure contained also uv's so ultimately my vertex buffer ended up being a mess. Silly mistake.

Class Object Not Modifying Other Class Object Correctly

I am trying to create a Model class that does the following:
- creates a Mesh class instance
- calls the addVertex function of the created Mesh object
- calls the addTriangle function of the created Mesh object
The Mesh class has two vectors to which the functions add to but when I print the contents in main.cpp they are empty.
Here is my code:
Model Class:
class Model
{
public:
/* Model Data */
/...
//using default constructor
Mesh createMesh() {
Mesh mesh;
meshes.push_back(mesh);
return mesh;
}
void addVertex(Mesh mesh, Vertex v) {
mesh.addVertex(v);
}
void addTriangle(Mesh mesh, Vertex a, Vertex b, Vertex c) {
mesh.addTriangle(a,b,c);
}
/...
Mesh Class:
class Mesh {
public:
/* Mesh Data */
vector<Vertex> vertices;
vector<unsigned int> indices;
/...
// constructor
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures)
{
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
for (Vertex v: vertices) {
pairings.insert( std::pair<Vertex,unsigned int>(v,count) );
count++;
}
setupMesh();
}
Mesh () {
}
//function 1
void addVertex(Vertex vertex) {
vertices.push_back(vertex);
pairings.insert( std::pair<Vertex,unsigned int>(vertex,count));
count++;
}
//function 2
void addTriangle(Vertex a, Vertex b, Vertex c) {
unsigned int index = pairings[a];
indices.push_back(index);
index = pairings[b];
indices.push_back(index);
index = pairings[c];
indices.push_back(index);
setupMesh();
}
main.cpp:
Model m;
Mesh mesh = m.createMesh();
Vertex a;
a.Position = glm::vec3 (-1,0,0);
m.addVertex(mesh, a);
Vertex b;
b.Position = glm::vec3 (0,1,0);
m.addVertex(mesh,b);
Vertex c;
c.Position = glm::vec3 (1,0,0);
m.addVertex(mesh,c);
m.addTriangle(mesh,a,b,c);
std::cout << mesh.indices.size(); //prints 0
Any help would be greatly appreciated!
I believe it is because on your addVertex and addTriangle methods within your Model class, you are passing the parameters by value, not by reference or pointer. This means that when you call the method you will pass a copy of your Mesh and Vertex objects and any changes you make inside the method will be lost as soon as execution of the method is complete. Try the following changes:
void addVertex(Mesh &mesh, Vertex &v) {
mesh.addVertex(v);
}
void addTriangle(Mesh &mesh, Vertex &a, Vertex &b, Vertex &c) {
mesh.addTriangle(a,b,c);
}
For more information on passing by reference, please refer to the following.

C++ obj loader texture coordinates messed up

I have written a simple obj parser in c++ that loads the vertices, indices and texture coordinates (that's all the data I need).
Here is the function:
Model* ModelLoader::loadFromOBJ(string objFile, ShaderProgram *shader, GLuint texture)
{
fstream file;
file.open(objFile);
if (!file.is_open())
{
cout << "ModelLoader: " << objFile << " was not found";
return NULL;
}
int vertexCount = 0;
int indexCount = 0;
vector<Vector3> vertices;
vector<Vector2> textureCoordinates;
vector<Vector2> textureCoordinatesFinal;
vector<unsigned int> vertexIndices;
vector<unsigned int> textureIndices;
string line;
while (getline(file, line))
{
vector<string> splitLine = Common::splitString(line, ' ');
// v - vertex
if (splitLine[0] == "v")
{
Vector3 vertex(stof(splitLine[1]), stof(splitLine[2]), stof(splitLine[3]));
vertices.push_back(vertex);
vertexCount++;
}
// vt - texture coordinate
else if (splitLine[0] == "vt")
{
Vector2 textureCoordinate(stof(splitLine[1]), 1 - stof(splitLine[2]));
textureCoordinates.push_back(textureCoordinate);
}
// f - face
else if (splitLine[0] == "f")
{
vector<string> faceSplit1 = Common::splitString(splitLine[1], '/');
vector<string> faceSplit2 = Common::splitString(splitLine[2], '/');
vector<string> faceSplit3 = Common::splitString(splitLine[3], '/');
unsigned int vi1 = stoi(faceSplit1[0]) - 1;
unsigned int vi2 = stoi(faceSplit2[0]) - 1;
unsigned int vi3 = stoi(faceSplit3[0]) - 1;
unsigned int ti1 = stoi(faceSplit1[1]) - 1;
unsigned int ti2 = stoi(faceSplit2[1]) - 1;
unsigned int ti3 = stoi(faceSplit3[1]) - 1;
vertexIndices.push_back(vi1);
vertexIndices.push_back(vi2);
vertexIndices.push_back(vi3);
textureIndices.push_back(ti1);
textureIndices.push_back(ti2);
textureIndices.push_back(ti3);
indexCount += 3;
}
}
// rearanging textureCoordinates into textureCoordinatesFinal based on textureIndices
for (int i = 0; i < indexCount; i++)
textureCoordinatesFinal.push_back(textureCoordinates[textureIndices[i]]);
Model *result = new Model(shader, vertexCount, &vertices[0], NULL, texture, indexCount, &textureCoordinatesFinal[0], &vertexIndices[0]);
models.push_back(result);
return result;
}
As you can see, I take into account the 1 - texCoord.y (because blender and opengl use a different coordinate system for textures).
I also arrange the texture coordinates based on the texture indices after the while loop.
However, the models I try to render have their textures messed up. Here is an example:
Texture messed up
I even tried it with a single cube which I unwrapped myself in blender and applied a very simple brick texture. In 1 or 2 faces, the texture was fine and working, then in some other faces, 1 of the tringles had a correct texture and the others appeared streched out (same as in the picture above).
To define a mesh, there is only one index list that indexes the vertex attributes. The vertex attributes (in your case the vertices and the texture coordinate) form a record set, which is referred by these indices.
This causes, that each vertex coordinate may occur several times in the list and each texture coordinate may occur several times in the list. But each combination of vertices and texture coordinates is unique.
Take the vertexIndices and textureIndices an create unique pairs of vertices and texture coordinates (verticesFinal, textureCoordinatesFinal).
Create new attribute_indices, which indexes the pairs.
Use the a temporary container attribute_pairs to manage the unique pairs and to identify their indices:
#include <vector>
#include <map>
// input
std::vector<Vector3> vertices;
std::vector<Vector2> textureCoordinates;
std::vector<unsigned int> vertexIndices;
std::vector<unsigned int> textureIndices;
std::vector<unsigned int> attribute_indices; // final indices
std::vector<Vector3> verticesFinal; // final vertices buffer
std::vector<Vector2> textureCoordinatesFinal; // final texture coordinate buffer
// map a pair of indices to the final attribute index
std::map<std::pair<unsigned int, unsigned int>, unsigned int> attribute_pairs;
// vertexIndices.size() == textureIndices.size()
for ( size_t i = 0; i < vertexIndices.size(); ++ i )
{
// pair of vertex index an texture index
auto attr = std::make_pair( vertexIndices[i], textureIndices[i] );
// check if the pair aready is a member of "attribute_pairs"
auto attr_it = attribute_pairs.find( attr );
if ( attr_it == attribute_pairs.end() )
{
// "attr" is a new pair
// add the attributes to the final buffers
verticesFinal.push_back( vertices[attr.first] );
textureCoordinatesFinal.push_back( textureCoordinates[attr.first] );
// the new final index is the next index
unsigned int new_index = (unsigned int)attribute_pairs.size();
attribute_indices.push_back( new_index );
// add the new map entry
attribute_pairs[attr] = new_index;
}
else
{
// the pair "attr" already exists: add the index which was found in the map
attribute_indices.push_back( attr_it->second );
}
}
Note the number of the vertex coordinates (verticesFinal.size()) is equal the number of the texture coordiantes (textureCoordinatesFinal.size()). But the number of the indices (attribute_indices.size()) is something completely different.
// verticesFinal.size() == textureCoordinatesFinal.size()
Model *result = new Model(
shader,
verticesFinal.size(),
verticesFinal.data(),
NULL, texture,
attribute_indices.size(),
textureCoordinatesFinal.data(),
attribute_indices.data() );

c++ OpenGL terrain generation

Im trying to make a terrain from a grid of vertices and i have a bug and just cant find it.Im stuck with it for 3 hours.Im using c++ and opengl.Im plan to use a blendmap for texturing and a height map later.Anyway here's the code:
Heres how it should look like: http://postimg.org/image/9431kcvy7/
Heres how it looks:
http://postimg.org/image/xxsoesqkp/
As you can see the tringles are separated by a 1 unit rectagle and it look like all the bottom points form a triangle with the point that has coordinates (0,0,0)
I know this problem might seem easy to solve but ive lost already 3 hours trying.Please help:)
Map.h
#ifndef MAP_H
#define MAP_H
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <windows.h>
using namespace std;
struct coordinate{
float x,y,z;
};
struct face{
int v[3];
int n[3];
};
struct uv{
float x;
float y;
};
class Map
{
private:
int mapX,mapY;
vector<coordinate> vertex;
vector<uv>textureCoordinates;
vector<coordinate>normals;
vector< vector<face> > faces;
string fileNameString;
sf::Image image[5];
sf::Color faceColor,blendPixel,p0,p1,p2;
sf::Image texture;
sf::Uint8 pixels[256*256*4];
unsigned int imageID[3],textureID;
public:
void load(const char *fileName);
void draw();
};
#endif // MAP_H
And Map.cpp
#include "Map.h"
#define blendMap 3
#define heightMap 4
void Map::load(const char *fileName)
{
int i,j;
fileNameString=fileName;
vector<face> F;
coordinate v;
face f;
image[0].loadFromFile(fileNameString+"/0.png");
image[1].loadFromFile(fileNameString+"/1.png");
image[2].loadFromFile(fileNameString+"/2.png");
image[blendMap].loadFromFile(fileNameString+"/blendMap.png");
image[heightMap].loadFromFile(fileNameString+"/heightMap.png");
mapX=image[blendMap].getSize().x;
mapY=image[blendMap].getSize().y;
for(i=-mapY/2;i<mapY/2;i++)
for(j=-mapX/2;j<mapX/2;j++)
{
v.x=j*0.5;
v.z=i*0.5;
vertex.push_back(v);
}
for(i=0;i<mapY-1;i++)
{
for(j=0;j<2*(mapX-1);j++)
F.push_back(f);
faces.push_back(F);
}
for(i=0;i<mapY-1;i++)
for(j=0;j<(mapX-1)*2;j+=2)
{
faces[i][j].v[0]=i*mapX+j;
faces[i][j].v[1]=i*mapX+j+1;
faces[i][j].v[2]=(i+1)*mapX+j;
faces[i][j+1].v[0]=i*mapX+j+1;
faces[i][j+1].v[1]=(i+1)*mapX+j+1;
faces[i][j+1].v[2]=(i+1)*mapX+j;
}
for(i=0;i<mapX*mapY;i++)
{
color=image[heightMap].getPixel(i/mapX,i%mapX);
vertex[i].y=0;//(float)color.r/25.5-10;
}
}
void Map::draw()
{
unsigned int i,j;
for(i=0;i<mapY-1;i++)
for(j=0;j<(mapX-1)*2;j+=2)
{
glBindTexture(GL_TEXTURE_2D,imageID[0]);
glBegin(GL_TRIANGLES);
glTexCoord2f (0,0);
glVertex3f(vertex[faces[i][j].v[0]].x , vertex[faces[i][j].v[0]].y , vertex[faces[i][j].v[0]].z);
glTexCoord2f (1,0);
glVertex3f(vertex[faces[i][j].v[1]].x , vertex[faces[i][j].v[1]].y , vertex[faces[i][j].v[1]].z);
glTexCoord2f (0,1);
glVertex3f(vertex[faces[i][j].v[2]].x , vertex[faces[i][j].v[2]].y , vertex[faces[i][j].v[2]].z);
glTexCoord2f (0,0);
glVertex3f(vertex[faces[i][j+1].v[0]].x , vertex[faces[i][j+1].v[0]].y , vertex[faces[i][j+1].v[0]].z);
glTexCoord2f (1,0);
glVertex3f(vertex[faces[i][j+1].v[1]].x , vertex[faces[i][j+1].v[1]].y , vertex[faces[i][j+1].v[1]].z);
glTexCoord2f (0,1);
glVertex3f(vertex[faces[i][j+1].v[2]].x , vertex[faces[i][j+1].v[2]].y , vertex[faces[i][j+1].v[2]].z);
glEnd();
}
}
A few things:
for(i=-mapY/2;i<mapY/2;i++)
This is dangerous and probably not the intention of the loop, anyway. You want to loop mapY times. However, if mapY is odd, you will loop only mapY - 1 times. E.g. if mapY = 3, then -mapY / 2 = -1; mapY / 2 = 1. So you will loop with the values -1 and 0. That's a first problem, which results in too few vertices in your buffer (this is probably the main problem). Instead do the shifting on the coordinate level:
for(i = 0; i < mapY; i++)
for(j = 0; j < mapX; j++)
{
v.x = j * 0.5 - mapY / 2.0;
v.z = i * 0.5 - mapX / 2.0;
vertex.push_back(v);
}
Is there a reason why you use a vector<vector<...>> for the faces? It will give you all kinds of problems regarding indexing as you already noticed. Just use a vector<Face> and put all your faces in there. Usually, you create this structure once and never touch it again. So the 2D indexing is probably not necessary. If you want to stay with the 2D indexing, this loop has wrong bounds:
for(j=0;j<(mapX-1)*2;j+=2)
This upper bound is an inclusive bound. Therefore, use
for(j = 0; j <= (mapX - 1) * 2; j += 2)

Tessellation - saving data

I am using tessellation in order to transfer non triangled polygons to triangle polygons.
I am trying to save the data in variable and run the tessellation code once while saving the data. The code use the saved data in order to draw it in draw function.
I am trying the draw a star polygon, The problem is that I can see some triangles but not a star. Why when I save the data the drawing go wrong?
Here is the initialize code:
#define callback void(CALLBACK*)()
void Init()
{
GLdouble star[5][6] = /* star data, The data is 100% perfect */
glColor3f(0.0f, 1.0f, 0.0f);
GLUtesselator *pTess = gluNewTess();
indexNum = 0;
gluTessCallback(pTess, GLU_TESS_BEGIN, (callback)glDrowMode);
gluTessCallback(pTess, GLU_TESS_VERTEX, (callback)saveData);
gluTessCallback(pTess, GLU_TESS_ERROR, (callback)tessError);
gluTessCallback(pTess, GLU_TESS_COMBINE, (callback) scbCombine);
gluTessProperty(pTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(pTess, NULL);
gluTessBeginContour(pTess);
for(int i = 0; i < 5; i++)
gluTessVertex(pTess, star[i], star[i]);
gluTessEndContour(pTess);
gluTessEndPolygon(pTess);
gluDeleteTess(pTess);
}
The saving data code and saving the drawing mode:
struct vecStruct
{
GLdouble *vertex, *color;
};
vecStruct vec[16];
int indexNum = 0;
void CALLBACK saveData(const GLvoid *ptr)
{
const GLdouble *data = (const GLdouble*)ptr;
vec[indexNum].vertex = new GLdouble[3];
vec[indexNum].color = new GLdouble[3];
vec[indexNum].vertex[0] = data[0];
vec[indexNum].vertex[1] = data[1];
vec[indexNum].vertex[2] = data[2];
vec[indexNum].color[0] = data[3];
vec[indexNum].color[1] = data[4];
vec[indexNum].color[2] = data[5];
indexNum++;
}
GLenum drawMode;
void CALLBACK glDrowMode(GLenum where)
{
drawMode = where;
}
And last the drow function:
void vboDraw()
{
glBegin(drawMode);
for (int i = 0; i < indexNum; i++)
{
glColor3dv(vec[i].color);
glVertex3dv(vec[i].vertex);
}
glEnd();
}
As I have said I should see star:
But what I can see is some triangles:
What is wrong with the code?
Why can not I save the data for doing the tessellation code only once?