I am trying to make a video game using Nim and OpenGL. I am using GLFW. I have some code to make a cube meant to be grass. However, when I run my program, I see a light blue background, but no cube. I have tried moving the camera around to different positions and this did not work. Does anyone know why this is?
Code:
import nimgl, nimgl/[opengl, glfw]
import strutils, os
# import camera, controller, dataprotocol, inventory
proc drawAll(xpos: float, ypos: float, zpos: float, window: GLFWWindow): void =
glfwPollEvents()
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(1.55+xpos, -1.75+ypos, -7.0+zpos)
glBegin(GL_TRIANGLES)
# Top face
glColor3f(0.0, 1.0, 0.0) # Green
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, 1.0)
# Bottom face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
# Front face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
# Back face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f( 1.0, 1.0, -1.0)
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
# Left face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
# Right face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(1.0, 1.0, 1.0)
glVertex3f(1.0, -1.0, 1.0)
glVertex3f(1.0, -1.0, -1.0)
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(1.0, -1.0, 1.0)
glEnd()
window.swapBuffers()
proc esc(window: GLFWwindow, key: int32, scancode: int32, action: int32, mods: int32){.cdecl.} =
if action == GLFWPress:
if key == int(GLFWKey.Escape):
window.setWindowShouldClose(true)
discard window.setKeyCallback(GLFWKeyFun(esc))
# var blocks = string(open("blocks.bmc").readAll).split(";")
discard glfwInit()
glfwWindowHint(GLFWContextVersionMajor, 3)
glfwWindowHint(GLFWContextVersionMinor, 3)
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE) # Used for Mac
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE) # Used for Mac
glfwWindowHint(GLFWResizable, GLFW_FALSE)
let window = glfwCreateWindow(800, 600, "BlueMC") # Making a window
window.makeContextCurrent
doAssert glInit()
glClearColor(GLFloat(172.0/255.0), GLFloat(246.0/255.0), GLFloat(246.0/255.0), GLFloat(1.0))
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glShadeModel(GL_SMOOTH)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
var xpos, ypos, zpos: float
if paramCount() == 0:
xpos = 0.0
ypos = 0.0
zpos = 0.0
elif paramCount() == 3:
xpos = parseFloat(paramStr(1))
ypos = parseFloat(paramStr(2))
zpos = parseFloat(paramStr(3))
while not window.windowShouldClose():
drawAll(xpos, ypos, zpos, window)
window.destroyWindow()
glfwTerminate()
what I did to make your code work:
deleted these lines:
glfwWindowHint(GLFWContextVersionMajor, 3)
glfwWindowHint(GLFWContextVersionMinor, 3)
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE) # Used for Mac
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE) # Used for Mac
enabled GL_DEPTH_CLAMP (maybe this will be a problem in the future, i'm not an expert, still it draws this cube without clipping it):
glEnable(GL_DEPTH_TEST)
glEnable(GL_DEPTH_CLAMP)
also i moved this line after glfwCreateWindow proc call:
discard window.setKeyCallback(GLFWKeyFun(esc))
i am learning too and can't explain this and that, just was curious to make it work.
here i'm rotating your cube:
import nimgl/[opengl, glfw]
proc drawAll(window: GLFWWindow) =
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glScalef(0.5,0.5,1)
glRotatef(-45,1,0,0)
glRotatef(glfwGetTime()*100,0,1,0)
glBegin(GL_TRIANGLES)
# Top face
glColor3f(0.0, 1.0, 0.0) # Green
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, -1.0)
glVertex3f(-1.0, 1.0, 1.0)
# Bottom face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
# Front face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f( 1.0, -1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, 1.0)
# Back face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f( 1.0, 1.0, -1.0)
glVertex3f( 1.0, -1.0, -1.0)
glVertex3f(-1.0, 1.0, -1.0)
# Left face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, -1.0)
glVertex3f(-1.0, -1.0, -1.0)
glVertex3f(-1.0, -1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, -1.0, -1.0)
# Right face
glColor3f(139.0/256.0, 69.0/256.0, 19.0/256.0) # Brown
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(1.0, 1.0, 1.0)
glVertex3f(1.0, -1.0, 1.0)
glVertex3f(1.0, -1.0, -1.0)
glVertex3f(1.0, 1.0, -1.0)
glVertex3f(1.0, -1.0, 1.0)
glEnd()
window.swapBuffers()
proc esc(window: GLFWwindow, key: int32, scancode: int32, action: int32, mods: int32){.cdecl.} =
if action == GLFWPress:
if key == int(GLFWKey.Escape):
window.setWindowShouldClose(true)
discard glfwInit()
glfwWindowHint(GLFWResizable, GLFW_FALSE)
let window = glfwCreateWindow(800, 600, "BlueMC") # Making a window
discard window.setKeyCallback(GLFWKeyFun(esc))
window.makeContextCurrent
doAssert glInit()
glClearColor(172.0/255.0, 246.0/255.0, 246.0/255.0, 1.0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_DEPTH_CLAMP)
while not window.windowShouldClose():
drawAll(window)
glfwPollEvents()
window.destroyWindow()
glfwTerminate()
Related
I am new to OpenGL and Shaders.
I want to write a toon shader.
I have this OpenGL code:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
float black[] = { 0.0, 0.0, 0.0, 1.0 };
float red[] = { 1.0, 0.0, 0.0, 1.0 };
float green[] = { 0.0, 1.0, 0.0, 1.0 };
float blue[] = { 0.0, 0.0, 1.0, 1.0 };
float white[] = { 1.0, 1.0, 1.0, 1.0 };
float lowAmbient[] = { 0.2, 0.2, 0.2, 1.0 };
float fullAmbient[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, blue);
glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialf(GL_FRONT, GL_SHININESS, 128.0);
glLightfv(GL_LIGHT0, GL_AMBIENT, lowAmbient);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -9);
glRotatef(45, 1, 0, 0);
glRotatef(45, 0, 0, 1);
glBegin(GL_QUADS);
//front
glNormal3f(0.0, 0.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
//back
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
//right
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
//left
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
//top
glNormal3f(0.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
//bottom
glNormal3f(0.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glEnd();
//Swap back and front buffer
glutSwapBuffers();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.2,0.2,0.2,1.0 };
float diffuseLight[] = { 0.8,0.8,0.8,1.0 };
float specularLight[] = { 1.0,1.0,1.0,1.0 };
float lightPosition[] = { 0.5,0.5,0.0,1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}
My Shader Codes:
#shader vertex
#version 330 core
void main()
{
}
#shader fragment
#version 330 core
vec3 LightPosition = gl_LightSource[0].position;//I don't know this is true or not
vec3 Normal;//I don't know how to calculate
void main()
{
vec4 color1 = gl_FrontMaterial.diffuse + gl_FrontMaterial.specular +
gl_FrontMaterial.ambient;
vec4 color2;
float intensity = dot(LightPosition, Normal);
if (intensity > 0.95) color2 = vec4(1.0, 1.0, 1.0, 1.0);
else if (intensity > 0.75) color2 = vec4(0.8, 0.8, 0.8, 1.0);
else if (intensity > 0.50) color2 = vec4(0.6, 0.6, 0.6, 1.0);
else if (intensity > 0.25) color2 = vec4(0.4, 0.4, 0.4, 1.0);
else color2 = vec4(0.2, 0.2, 0.2, 1.0);
gl_FragColor = color1 * color2;
}
To calculate light intensity and apply colors to my cube object I should know normals.
How can I calculate, or if there is a way, reach them?
(I have no problem with the shader compilation, or other OpenGL stuff. If I close my shader compilation lines I can see a green cube.)
I am trying to create and display a 3D square but for some reason when I render it, parts of it are missing:
void DrawCube::drawCubes(int amount){
glBegin(GL_POLYGON);
glVertex3f( 1.0, -1.0, 1);
glVertex3f( 1.0, -1.0, -1);
glVertex3f( 1.0, 1.0, -1);
glVertex3f( 1.0, 1.0, 1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(-1.0, -1.0, -1);
glVertex3f( 1.0, -1.0, -1);
glVertex3f( 1.0, 1.0, -1);
glVertex3f(-1.0, 1.0, -1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(-1.0, -1.0, 1);
glVertex3f( 1.0, -1.0, 1);
glVertex3f( 1.0, 1.0, 1);
glVertex3f(-1.0, 1.0, 1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f( -1.0, -1.0, 1);
glVertex3f( -1.0, -1.0, -1);
glVertex3f( -1.0, 1.0, -1);
glVertex3f( -1.0, 1.0, 1);
glEnd();
}
}
I'm not looking for answers that just give me the code, but rather an explanation as to what causes this thanks.
The cube seems to be clipped by the far plane of the projection. Increase the distance to the far plane, when you set the projection matrix by glOrtho.
Note, the projection matrix defines a view volume (see 3D projection). All the geometry which is out of the viewing volume is clipped.
I am trying to apply a texture to 1 face of a cube, but the problem I have is the cube is in the z direction as well.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Tex);
glBegin(GL_POLYGON);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, 1);
glTexCoord2f( 1.0, -1.0); glVertex3f( 1.0, -1.0, 1);
glTexCoord2f( 1.0, -1.0); glVertex3f( 1.0, -1.0, -1);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, -1);
glEnd();
glDisable(GL_TEXTURE_2D);
Obviously by doing it this way I end up with repeated texture vertices (1,1) and (1,-1) because they don't include the z axis. How can I resolve this issue?
It is not necessary that the texture coordinates are associated to the x and y component of the vertex coordinates or even have to be the same. The texture coordinates are completely independent.
You have to define how the 2 dimensional texture is wrapped on a surface in 3 dimensional space. For each side of the cube you've to define individual texture coordinates.
Chang the texture coordinates. e.g.:
glBegin(GL_POLYGON);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f( 1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f( 0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f( 0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glEnd();
I'm making a square arm with push-pop matrix and pop-up menu entries. I want to make the objects rotate individually, so I create the code below but the one finger moves along with the others. Why is it moving together?
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
draw_lines();
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glTranslatef(-1.0, 0.0, 0.0);
glRotatef((GLfloat)shoulder, 0.0, 0.0, 1.0);
glTranslatef(1.0, 0.0, 0.0);
glPushMatrix();
glScalef(2.0, 0.4, 1.5);
glutWireCube(1.0); //First square(Shoulder)
glPopMatrix();
glTranslatef(1.0, 0.0, 0.0);
glRotatef((GLfloat)elbow, 0.0, 0.0, 1.0);
glTranslatef(1.0, 0.0, 0.0);
glPushMatrix();
glScalef(2.0, 0.4, 1.5);
glutWireCube(1.0); //Second Square(Elbow)
glPopMatrix();
glTranslatef(1.0, 0.0, 0.0);
glRotatef((GLfloat)finger_1, 0.0, 0.0, 1.0);
glTranslatef(0.25, 0.0, 0.7);
glPushMatrix();
glScalef(0.5, 0.2, 0.2);
glutWireCube(1.0); //First Finger
glPopMatrix();
glTranslatef(-0.3, 0.0, 0.0);
glRotatef((GLfloat)finger_2, 0.0, 0.0, 1.0);
glTranslatef(0.25, 0.0, -0.4);
glPushMatrix();
glScalef(0.5, 0.2, 0.2);
glutWireCube(1.0); //Second Finger
glPopMatrix();
glTranslatef(-0.3, 0.0, 0.0);
glRotatef((GLfloat)finger_3, 0.0, 0.0, 1.0);
glTranslatef(0.25, 0.0, -0.5);
glPushMatrix();
glScalef(0.5, 0.2, 0.2);
glutWireCube(1.0); //Third Finger
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
Object rotation is made by separate functions.
I am making an apartment with C++ and openGl. I have made basic walls, roof and floor by just declaring points in the drawing function and everything of course works but code is messy and adding furniture this way would of course be very painful. So I am asking how should I organize my objects and format drawing function?
Here's the current code:
// Floor and roof of room 1
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 1.0);
glNormal3f(0.0, -1.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(0.0, 1.0, 1.0);
glEnd();
// Walls
glBegin(GL_QUAD_STRIP);
glNormal3f(1.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0,0.0,1.0);
glVertex3f(0.0,1.0,1.0);
glNormal3f(0.0, 0.0, -1.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glNormal3f(-1.0, 0.0, 0.0);
glColor3f(0.5, 0.0, 0.5);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glEnd();
And so on for room 2 and door spots..
Any places to read about this subject?
You can use 3d modelling software, e.g. →Blender to define your geometry etc. Then I recommend to use →Assimp to load the exported model. Also recommend to avoid the old fixed-function pipeline – write your own little scenegraph engine and manage your matrices and 3d math with →GLM