Just for clarity for TS, TS, you implement glNormal, glTexCoord in this manner if you going to use glBegin() and glEnd():
glBegin(GL_TRIANGLES);
glTexCoord(....);
glNormal3d(....);
glVertex3d(...);
glTexCoord(...);
glNormal3d(...);
glVertex3d(...);
glEnd();
You might want to google swiftless tutorials if you want to be up to speed.
Another note is to normalize all the normals once before throwing them into the rendering loop. You might want to check how to use array buffers in the meanwhile.
the actual normal should look like this:
![]()
but without normal i tilted a little
![]()
and with normal after implement glnormal3d()
![]()
big issues:right i have problems like files with X>1 cannot loads,rendered model don't look like the actual model,the normal calculate could be wrong,haven't implement half-edge data structure use array.
good thing is I have learned C++ with realloc and malloc and difference with the java,render model with lightning,troubleshooting using visual studio
i still need to implement:x,y,z axis,user interface with gluts,grid system with 10x10,aabb systems
glTexCoord is for what?texture?
void displayModel(void){
//enable openGL depth test
glEnable(GL_DEPTH_TEST);
// Just clean the screen
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// setup the perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, .1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5,0,0,0,0,1,0);
glPushMatrix();
//rotate and scale the object
glRotatef(x_angle,0,1,0);
glRotatef(y_angle,1,0,0);
glScalef(scale_size,scale_size,scale_size);
for(int i = 0;i < f_size - 1;i++){
face f = face_array[i];
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLES);
//glNormal3d(vertex_array[f.v1].nx,vertex_array[f.v1].ny,vertex_array[f.v1].nz);
glVertex3d(vertex_array[f.v1].x,vertex_array[f.v1].y,vertex_array[f.v1].z);
//glNormal3d(vertex_array[f.v2].nx,vertex_array[f.v2].ny,vertex_array[f.v2].nz);
glVertex3d(vertex_array[f.v2].x,vertex_array[f.v2].y,vertex_array[f.v2].z);
//glNormal3d(vertex_array[f.v3].nx,vertex_array[f.v3].ny,vertex_array[f.v3].nz);
glVertex3d(vertex_array[f.v3].x,vertex_array[f.v3].y,vertex_array[f.v3].z);
glEnd();
}
glPopMatrix();
glutSwapBuffers();
}
Code:void displayModel(void){ //enable openGL depth test glEnable(GL_DEPTH_TEST); // Just clean the screen glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // setup the perspective projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 1, .1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,5,0,0,0,0,1,0); glPushMatrix(); //rotate and scale the object glRotatef(x_angle,0,1,0); glRotatef(y_angle,1,0,0); glScalef(scale_size,scale_size,scale_size); for(int i = 0;i < f_size - 1;i++){ face f = face_array[i]; glColor3f(1.0, 1.0, 1.0); glBegin(GL_TRIANGLES); //glNormal3d(vertex_array[f.v1].nx,vertex_array[f.v1].ny,vertex_array[f.v1].nz); glVertex3d(vertex_array[f.v1].x,vertex_array[f.v1].y,vertex_array[f.v1].z); //glNormal3d(vertex_array[f.v2].nx,vertex_array[f.v2].ny,vertex_array[f.v2].nz); glVertex3d(vertex_array[f.v2].x,vertex_array[f.v2].y,vertex_array[f.v2].z); //glNormal3d(vertex_array[f.v3].nx,vertex_array[f.v3].ny,vertex_array[f.v3].nz); glVertex3d(vertex_array[f.v3].x,vertex_array[f.v3].y,vertex_array[f.v3].z); glEnd(); } glPopMatrix(); glutSwapBuffers(); }
my displaymodel() looks find rights?
then i need to do many printf and scanf.
Hi there,
i wrote a simple batch file to automate my work.
bcc32 read.c
read.exe
PAUSE
any suggestion?
and how do i check the first character of string
btw i tried all the stricmp,strstr,strchk,all even char ch,say ch[0],all doesn't work for me.
but i learnt that fgetc can get the first character of the string
Have you even read in from the file or not ?
You can try use fscanf(FILE *, "%s", str_array) to capture a non-whitespace string, then you can always use "str_array[0] == ..." to test for the first character.
How does accessing the first character not work for u? I think u need to be more informativeuse fscanf works for me.
str_array[0] doesn't work for me.
How does accessing the first character not work for u? I think u need to be more informative
i use char c;
$ gcc -o readchar readchar.c
$ ./readchar <(echo "ABCDEF")
FILENAME=/dev/fd/63
FIRST CHARACTER=A
$ ./readchar <(echo "123456")
FILENAME=/dev/fd/63
FIRST CHARACTER=1
$ cat readchar.c
#include <stdio.h>
int main(int argc, char **argv) {
char buf[100];
FILE *fp = fopen(argv[1], "r");
printf("FILENAME=%s\n", argv[1]);
fscanf(fp, "%s", buf);
printf("FIRST CHARACTER=%c\n", buf[0]);
return 0;
}
Please take note that when you are using "struct" in a C++ compiler, it is analogous to a class with all its members private. It is not the same as a "struct" in C. You may want to read some of the gotchas at Differences Between C and C++ - Cprogramming.com
If possible, use a C compiler such as GCC, LCC-Win. If you want to use Visual C++, either mandate using /Tc compiler option or make sure your source code ends with ".c" extension.
The Type of a structure is "struct <type_identifier>" in C, not just the identifier alone. Please be strict about this. Hence when you wanted to declare a pointer to a struct in C, it should be "struct HE_vert vertex". Even in C++, pointers to structure must be "struct <type_identifier> *<identifier>", not "<type_identifier> *<identifier>"
Your "output" function declaration is syntactically wrong.
v->x is the same as (*v).x.
the 'dot' operator is to access the member of a structure. 'v' is not a structure. v is a pointer to a structure. Hence to get a structure type, you need to dereference 'v' as such *v. *v is of Type structure. The reason to wrap it around the round parenthesis is because 'dot' operator has a higher precedence than '*'(dereference operator). *v.x would be dereferencing 'x', the member of 'v' instead.
I hope this is clear to you.
What "vector" are you talking about, are you talking about the equivalence of a Java Vector class, or you are referring to the mathematical Vector type? If it is Java vector, then C doesn't have it. The closest is a block of memory called array. You will need to design your own extensible array with the help of "realloc" function, or get an external library that does it for you.
If it's a maethematical Vector that you are referring to, the following structure should serve your needs
Code:struct _point { float x, y z; }; struct _vec { struct _point p1, p2; };
Another way of describing a mathematical Vector representing a matrix (x, y, z). It has no reference point though. If you want a reference point, you can always add one like this
Code:struct _point { float x, y z; }; struct _vec { struct _point ref_vert, direction; };
Can't help to identify your errors since I don't know what is the corresponding source code lines.
Well good you know of another good tool around. In GCC, you will find the command line equivalence called gdb. There are tons of much better tools available in Linux to help with your debugging.
flipcode - The Half-Edge Data Structure
I doubt I can help much with using Half-Edge structures since I don't major in CG and its relevance. You will need to do more research on how to use this data structure properly to answer queries on a mesh.
public class Graph {
private int graphSize = 0;
private int adjacencyMatrix[][];
public Graph(int size) {
//create an adjacency matrix based on the graph size
graphSize = size;
adjacencyMatrix = new int[size][size];
for (int i = 0; i < adjacencyMatrix.length; i++) {
for (int j = 0; j < adjacencyMatrix[0].length; j++) {
adjacencyMatrix[i][j] = 0;
}
}
}
public void printAdjacencyMatrix() {
if (!isEmpty()) {
for (int i = 0; i < adjacencyMatrix.length; i++) {
for (int j = 0; j < adjacencyMatrix[0].length; j++) {
System.out.print(adjacencyMatrix[i][j] + " ");
}
System.out.println();
}
}
}
/*
* insert the edges given the adjacency matrix.
* it will be arranged as of undirected graph order
*/
public void insertEdge(int nodeID, int edge) {
//take in nodeID and its correspodning edges
//iterate through the adjacencymatrix
//set adjacencymatrix based on undirect graph pending
if (!isEmpty()) {
adjacencyMatrix[nodeID][edge] = 1;
//since must be undirected so
//adjacency matrix finally cloned
adjacencyMatrix[edge][nodeID] = 1;
}
}
public boolean isEmpty() {
return graphSize == 0;
}
/*
* Print out the depth first search tree from vertex v
*/
public void printDepthFirstSearch(int v) {
if (!isEmpty()) {
boolean[] isVisited = new boolean[graphSize];
//given a verticies
dfs2(v, isVisited);
System.out.println();
}
}
private void dfs2(int v, boolean isVisited[]) {
//this area will be visited starting from the int v
//for each vertex v visited
//store the visited vertex into an array
//if not visited then print it out
if(!isVisited[v]){
System.out.print(v + " ");
}
isVisited[v] = true;
//iterate through the adjacency matrix
//each neighbour of v
int count = 0;
for (int neigh = 0; neigh < adjacencyMatrix[v].length; neigh++) {
if (adjacencyMatrix[v][neigh] == 1) {//if it exist
if (!isVisited[neigh]) { //if not visited for that particular neighbour
count ++;
dfs2(neigh, isVisited);
}
}
}
if(count == 0) System.out.println();
}
/*
*
* Print the depth first search given the verticies
* @param v as the starting point
*/
public void printBreathFirstSearch(int v) {
if (!isEmpty()) {
boolean[] isVisited = new boolean[graphSize];
//given a verticies
bfs2(v, isVisited);
System.out.println();
}
}
//the int need to be a node?
private void bfs2(int v, boolean isVisited[]) {
Queue1 queue = new Queue1();
queue.enqueue(v);
isVisited[v] = true;
if(!isVisited[v]){
System.out.print(v + " ");
}
while (!queue.isEmpty()) {
int vertex = Integer.parseInt(queue.dequeue().toString());
//given the vertex
for (int neigh = 0; neigh < adjacencyMatrix[vertex].length;neigh ++ ) {//for each neigh
if (adjacencyMatrix[vertex][neigh] == 1 && !isVisited[neigh]) {
//been visited
queue.enqueue(new Integer(neigh));//pending recursive visiting
//dequeue to search for more neighbours
bfs2(Integer.parseInt(queue.dequeue().toString()), isVisited);
}
//create a new line to break
}
}
}
public void printConnectedComponents() {
if (!isEmpty()) {
boolean[] isVisited = new boolean[graphSize];
for(int neigh = 0;neigh < adjacencyMatrix.length;neigh++){
//break
dfs2(neigh,isVisited);
}
System.out.println();
}
}
}
/*
* Read the graph from a text file.
*/
public static void readFile() {
int nodeID, size, numOfEdge,edge, count = 0;
try {
System.out.println("Enter the file name:");
Scanner in = new Scanner(new File(console.nextLine()));
size = in.nextInt();//verticies size
g = new Graph(size);
//not useful in this case as can get size from the lab8
for (int j = 0; j < size; j++) {
//first ndode past through already
nodeID = in.nextInt();
count++;
//check the number of edges
numOfEdge = in.nextInt();
for (int k = 0; k < numOfEdge; k++) {
//insert the edge with regards to the node id
edge = in.nextInt();
g.insertEdge(nodeID, edge);
}
}
// if need for debugging just use this method
// g.printAdjacencyMatrix();
//send the vertices and its edges to the adjacency matrix
} catch (FileNotFoundException ex) {
System.out.println("File not found!");
}
System.out.println(count + " nodes read");
}
Hi there,
when I was trying to using:
struct HE_edge
{
struct HE_vert* vert; // vertex at the end of the half-edge
struct HE_edge* pair; // oppositely oriented half-edge
struct HE_face* face; // the incident face
struct HE_edge* prev; // previous half-edge around the face
struct HE_edge* next; // next half-edge around the face
};
then this function:
void output_face_vertices (struct HE_face* f)
{
HE_edge* first_edge = f->edge ;
output(first_edge-> vert) ;
HE_edge* second_edge = first_edge->next ;
output (second_edge->vert) ;
HE_edge* third_edge = second_edge->next ;
output(third_edge->vert) ;
}
tried to compile,
it mentioned that undefined symbol in function,
even if I put struct HE_edge it doesn't work out,
when I use visual studio_ i don't have such
//assuming the following types are already created
// typedef struct _HE_face_ { ... } HE_face;
// typedef struct _HE_vert_ { ... } HE_vert;
typedef struct _HE_edge_
{
HE_vert* vert; // vertex at the end of the half-edge
struct _HE_edge_* pair; // oppositely oriented half-edge
HE_face* face; // the incident face
struct _HE_edge_* prev; // previous half-edge around the face
struct _HE_edge_* next; // next half-edge around the face
} HE_edge;
void output_face_vertices (HE_face* f)
{
HE_edge* first_edge = f->edge ;
output(first_edge->vert) ;
HE_edge* second_edge = first_edge->next ;
output(second_edge->vert) ;
HE_edge* third_edge = second_edge->next ;
output(third_edge->vert) ;
}
The full type of a structure is inclusive of the "struct" keyword.
You can define your own type and hence have the syntax more friendly looking as such
Code://assuming the following types are already created // typedef struct _HE_face_ { ... } HE_face; // typedef struct _HE_vert_ { ... } HE_vert; typedef struct _HE_edge_ { HE_vert* vert; // vertex at the end of the half-edge struct _HE_edge_* pair; // oppositely oriented half-edge HE_face* face; // the incident face struct _HE_edge_* prev; // previous half-edge around the face struct _HE_edge_* next; // next half-edge around the face } HE_edge;
Inside the structure declaration, "HE_edge" type is not fully declared yet, hence you still need to stick with "struct _HE_edge_" as the complete type since there is a reference inside the structure declaration.
After the new type "HE_edge" is declared, you can use it as such
Code:void output_face_vertices (HE_face* f) { HE_edge* first_edge = f->edge ; output(first_edge->vert) ; HE_edge* second_edge = first_edge->next ; output(second_edge->vert) ; HE_edge* third_edge = second_edge->next ; output(third_edge->vert) ; }