Related
When I use glRotatef to change the diretion of the objects(table and cups) which are created by my own using plenty of triangles(I know it seems a little bit stupid QAQ), the lighting effects change weirdly as if the light position has also changed. However the lighting effects on teapot which is directly invoked by using glutSolidTeapot acts normally. I think that invoking glRotatef will not change the light position, so I cannot figure out where comes the problems.
The code is shown below:
#include<GLFW\glfw3.h>
#include<GL/glut.h>
#include<math.h>
#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
//系统屏幕大小初始化
GLint SCREEN_WIDTH = 0;
GLint SCREEN_HEIGHT = 0;
//窗口大小初始化
GLint window_width = 1000;
GLint window_height = 800;
//中心坐标计算
#define MIDWIDTH window_width/2
#define MIDHEIGHT window_height/2
//设置模型旋转角度
GLfloat xAngle = 0.0f;
GLfloat yAngle = 0.0f;
//设置模型初始距离
GLfloat distancex;
GLfloat distancey;
//受支持的点大小范围
GLfloat sizes[2];
//受支持的点大小增量
GLfloat step;
GLfloat mat_ambient_skew[] = { 0,0,0,0 };
GLfloat mat_diffuse_skew[] = { 0,0,0,0 };
GLfloat mat_specular_skew[] = { 0,0,0,0 };
GLfloat low_shininess[] = { 3.0 };
//线框0 or 实体1
GLint l_or_r = 1;
GLboolean mouseLeftDown = false; //鼠标左键按下状态,默认是未按下
//缩放倍数
GLfloat times = 0.8f;
//定义光源的颜色和位置
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //环境光
GLfloat position[] = { 10.0f,10.0f,10.0f,1.0f }; //光源位置
GLfloat matEmission[] = { 1.0f, 1.0f, 1.0f, 1.0 }; //反射光颜色
GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; //漫射光
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //镜面反射
GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; // 环境
GLfloat mat_diffuse[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 散射
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 镜面反射
GLfloat high_shininess[] = { 18.0f }; // 镜面反射指数为
GLfloat no_mat[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 无材质颜色
void init() {
GLfloat local_view[] = { 0.0 };
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
//glLightfv(GL_LIGHT0, GL_SPECULAR, mat_specular);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, local_view);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
// 启用光照
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matEmission);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, no_mat);
}
void translate()
{
//glColor3f(0.0f, 1.0f, 1.0f);
glScalef(times, times, times);
glTranslatef(distancex, distancey, 0);
glRotatef(xAngle, 1.0f, 0.0f, 0.0f);
glRotatef(yAngle, 0.0f, 1.0f, 0.0f);
}
void drawCube(double l, double w, double h, double x, double y, double z) {
glPushMatrix();
translate();
glTranslated(x, y, z);
glScaled(l, w, h);//沿x y z轴缩放 先缩放 再平移 一开始中心在原点
glColor3f(0.7, 0.35, 0.01);
if (l_or_r == 0) glutWireCube(1);
else if (l_or_r == 1) glutSolidCube(1);
glPopMatrix();
}
GLvoid DrawCircleArea(float height, float top, float bot, int num_segments, int cup) {
if (l_or_r == 0) {
glPolygonMode(GL_BACK, GL_LINE);//线框
glPolygonMode(GL_FRONT, GL_LINE);//线框
}
else if (l_or_r == 1) {
glPolygonMode(GL_BACK, GL_FILL);//实体
glPolygonMode(GL_FRONT, GL_FILL);//实体
}
GLfloat vertex[4];
const GLfloat delta_angle = 2.0 * 3.1415926 / num_segments;
int h = height;
float cx = 0;
float cy = 0;
float cz = 0;
// 画底面
glBegin(GL_TRIANGLES);
for (int i = 0; i <= num_segments; i++) {
int j = i + 1;
vertex[0] = cx;
vertex[1] = cy;
vertex[2] = cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * i) * bot + cx;
vertex[1] = cy;
vertex[2] = sin(delta_angle * i) * bot + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * j) * bot + cx;
vertex[1] = cy;
vertex[2] = sin(delta_angle * j) * bot + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
}
glEnd();
if (cup != 1) { // 画顶面
glBegin(GL_TRIANGLE_FAN);
for (int i = 0; i <= num_segments; i++) {
int j = i + 1;
vertex[0] = cx;
vertex[1] = cy + h;
vertex[2] = cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * i) * top + cx;
vertex[1] = cy + h;
vertex[2] = sin(delta_angle * i) * top + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * j) * top + cx;
vertex[1] = cy + h;
vertex[2] = sin(delta_angle * j) * top + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
}
glEnd();
}
for (int i = 0; i <= num_segments; i++) { // 画侧面
int j = i + 1;
glBegin(GL_TRIANGLES);
vertex[0] = cos(delta_angle * i) * bot + cx;
vertex[1] = cy;
vertex[2] = sin(delta_angle * i) * bot + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * j) * bot + cx;
vertex[1] = cy;
vertex[2] = sin(delta_angle * j) * bot + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * j) * top + cx;
vertex[1] = cy + h;
vertex[2] = sin(delta_angle * j) * top + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * i) * top + cx;
vertex[1] = cy + h;
vertex[2] = sin(delta_angle * i) * top + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * j) * top + cx;
vertex[1] = cy + h;
vertex[2] = sin(delta_angle * j) * top + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
vertex[0] = cos(delta_angle * i) * bot + cx;
vertex[1] = cy;
vertex[2] = sin(delta_angle * i) * bot + cz;
vertex[3] = 1.0;
glVertex4fv(vertex);
glEnd();
}
}
void MydrawCylinder(GLdouble l, GLdouble w, GLdouble h,
GLdouble x, GLdouble y, GLdouble z,
GLdouble base, GLdouble top, GLdouble height,
GLint slices, GLint stacks, GLint cup,
GLfloat r, GLfloat g, GLfloat b) {
if (l_or_r == 0) {
glPolygonMode(GL_BACK, GL_LINE);//线框
glPolygonMode(GL_FRONT, GL_LINE);//线框
}
else if (l_or_r == 1) {
glPolygonMode(GL_BACK, GL_FILL);//实体
glPolygonMode(GL_FRONT, GL_FILL);//实体
}
glPushMatrix();
translate();
glTranslated(x, y, z);
glScaled(l, w, h);//沿x y z轴缩放 先缩放 再平移 一开始中心在原点
glColor3f(r, g, b); // 桌子颜色
DrawCircleArea(height, top, base, slices, cup);
glPopMatrix();
}
void drawTeapot() {
//FILE* filePtr = fopen("./1.bmp", "rb");
glPushMatrix();
// 平滑处理
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH, GL_NICEST);
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH, GL_NICEST);
translate();
glColor3f(0., 0.35, 0.01); // 茶壶颜色
// 线框 or 实体
if (l_or_r == 0) glutWireTeapot(3.0f);
else if (l_or_r == 1) glutSolidTeapot(3.0f);
glPopMatrix();
}
void display() {
init();
glClearColor(0.7f, 0.9f, 1.0f, 0.3f); // 背景颜色
glClearStencil(1);
glEnable(GL_STENCIL_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //清空颜色缓冲和深度缓冲
//设置观察点的位置,这里设置为从 - z轴观察
glLoadIdentity();
// GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks
// 桌子 table
MydrawCylinder(1, 1, 1, 0, -4.2, 0, 15, 15, 2, 100, 100, 0, 0.66, 0.47, 0.294);
MydrawCylinder(1, 1, 1, 0, -(4.2 + 15), 0, 0.75, 0.75, 15, 12, 100, 0, 0.66, 0.47, 0.294);
MydrawCylinder(1, 1, 1, 0, -(4.2 + 15 + 1), 0, 5, 5, 1, 100, 100, 0, 0.66, 0.47, 0.294);
// 四个杯子 four cups
int far = 5; // 杯子距离中心距离
MydrawCylinder(1, 1, 1, far, -2.2, -far, 0.5, 0.75, 2, 12, 100, 1, 0.478, 0.827, 0.475);
MydrawCylinder(1, 1, 1, -far, -2.2, far, 0.5, 0.75, 2, 12, 100, 1, 0.478, 0.827, 0.475);
MydrawCylinder(1, 1, 1, far, -2.2, far, 0.5, 0.75, 2, 12, 100, 1, 0.478, 0.827, 0.475);
MydrawCylinder(1, 1, 1, -far, -2.2, -far, 0.5, 0.75, 2, 12, 100, 1, 0.478, 0.827, 0.475);
// teapot
drawTeapot();
glutSwapBuffers();
}
void changeSize(GLint width, GLint height) { // 窗口改变尺寸
GLfloat ratio;
GLfloat coordinatesize = 16.0f;
if ((width == 0) || (height == 0))
return;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ratio = (GLfloat)width / (GLfloat)height;
if (width < height)
glOrtho(-coordinatesize, coordinatesize, -coordinatesize / ratio, coordinatesize / ratio, -coordinatesize, coordinatesize);
else
glOrtho(-coordinatesize * ratio, coordinatesize * ratio, -coordinatesize, coordinatesize, -coordinatesize, coordinatesize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void menuFunc(int key) {
switch (key) {
case 1:
l_or_r = 0;
break;
case 2:
l_or_r = 1;
break;
case 3:
position[0] -= 10.0;
break;
case 4:
position[0] += 10.0;
break;
case 5:
position[2] += 10.0;
break;
case 6:
position[2] -= 10.0;
break;
}
glutPostRedisplay();
}
void setMenu() { // 设置鼠标右键菜单
int mainMenu;
int slrMenu;
int lightPositionMenu;
slrMenu = glutCreateMenu(menuFunc);
glutAddMenuEntry("线框", 1);
glutAddMenuEntry("实体", 2);
lightPositionMenu = glutCreateMenu(menuFunc);
glutAddMenuEntry("向下", 3);
glutAddMenuEntry("向上", 4);
glutAddMenuEntry("向外", 5);
glutAddMenuEntry("向内", 6);
mainMenu = glutCreateMenu(menuFunc);
glutAddSubMenu("线框 or 实体", slrMenu);
glutAddSubMenu("光照位置", lightPositionMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutPostRedisplay();
}
void keyFunc(int key, int x, int y) //键盘控制
{
//旋转
if (key == GLUT_KEY_UP) xAngle -= 5.0f; //绕x轴顺时针旋转
else if (key == GLUT_KEY_DOWN) xAngle += 5.0f; //绕x轴逆时针旋转
else if (key == GLUT_KEY_LEFT) yAngle -= 5.0f; //绕y轴顺时针旋转
else if (key == GLUT_KEY_RIGHT) yAngle += 5.0f; //绕y轴逆时针旋转
//缩放
if (key == GLUT_KEY_F1) times += 0.2f;
else if (key == GLUT_KEY_F2) times -= 0.2f;
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
SCREEN_WIDTH = glutGet(GLUT_SCREEN_WIDTH);
SCREEN_HEIGHT = glutGet(GLUT_SCREEN_HEIGHT);
glutCreateWindow(" ");
glutReshapeWindow(window_width, window_height);
setMenu();
glutReshapeFunc(changeSize);
glutDisplayFunc(display);
glutSpecialFunc(keyFunc);
glutMainLoop();
return 0;
}
The shadow of teapot does not match that of the table, and if rotate the table, the reflect light of teapot doesn't change it's postion while the reflect light of table changing weirdly.
image1
image2
I have a 2D transformation problem in OpenGL. My program draws two letters on screen and, by pressing assigned keys, letters have to move up (GLUT_KEY_UP) down (GLUT_KEY_DOWN) left (GLUT_KEY_LEFT) right (GLUT_KEY_RIGHT) and rotate CW (GLUT_KEY_HOME) and CCW (GLUT_KEY_END). (On keys GLUT_KEY_PAGE_UP and GLUT_KEY_PAGE_DOWN both letters rotate around their own centers simultaniously in oposite directions, pressing e.g. GLUT_KEY_UP after GLUT_KEY_PAGE_UP moves both letters in a correct direction).
I can't make the letters do the correct movement (up, down, left or right) after the objects had been rotated with GLUT_KEY_HOME or GLUT_KEY_END:
case GLUT_KEY_HOME: //rotate clockwise around the center of the model
glMatrixMode(GL_MODELVIEW);
setRotationMatrix(-angle, modelSizeX, modelSizeY);
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
display();
break;
Function that 'sets' the rotation matrix inserts angle and rotation point into Identity matrix [4x4]:
void setRotationMatrix(float theta, float x0, float y0)
{
theta = theta * (2 * acos(0.0)) / 180; // convert theta from degrees to radian
rotationMatrix[0] = cos(theta);
rotationMatrix[1] = sin(theta);
rotationMatrix[4] = -sin(theta);
rotationMatrix[5] = cos(theta);
rotationMatrix[12] = ((x0 * 0.5f) * (1 - cos(theta)) + (y0 * 0.5f) * sin(theta));
rotationMatrix[13] = ((y0 * 0.5f) * (1 - cos(theta)) - (x0 * 0.5f) * sin(theta));
}
After the objects have been rotated, if I press KEY_UP, they move not 'up' (in normal direction against x axis ) but in the direction normal to the horizontal plane of the object after rotation (slightly sideways).
case GLUT_KEY_UP:
glMatrixMode(GL_MODELVIEW);
glTranslated(0, delta, 0);
display();
break;
how do I make it move straightly to the 'north', meaning, not the 'north' of the object but the 'north' of my coordinate system?
#include <Windows.h>
#include <GL/glut.h>
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;
#define EscKey 27
#define PlusKey 43
#define MinusKey 45
struct Point
{
int x, y;
};
double pi = 2 * acos(0.0);
void reshape(int w, int h);
void display();
void drawInitials();
void processNormalKeys(unsigned char key, int x, int y);
void processSpecialKeys(int key, int x, int y);
void setRotationMatrix(float theta, float x0, float y0);
void readFromFile();
void lineto(Point p);
void moveto(Point p);
void drawM();
void drawJ();
vector <Point> point;
vector <int> code;
Point currentPoint;
int modelSizeX = 202; int modelSizeY = 89;
int letterMSizeX = 107; int letterJSizeX = 78;
int delta = 5; // movement size
float zoomRate = 0.1; // scale-and-translate rate: 0.1 = resize by 10%
float angle = 1, rotaterR = 1 * pi / 180, rotater, angleCount = 0.0; // saved rotation angle
GLfloat modelviewStateMatrix[16];
int windowSizeX, windowSizeY;
boolean separate = false;
float rotationMatrix[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
float plusKeyMatrix[16] = { 1.0f + zoomRate, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f + zoomRate, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
-(modelSizeX * zoomRate * 0.5f), -(modelSizeY * zoomRate * 0.5f), 0.0f, 1.0f };
float minusKeyMatrix[16] = { 1.0f - zoomRate, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f - zoomRate, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
modelSizeX * zoomRate * 0.5f, modelSizeY * zoomRate * 0.5f, 0.0f, 1.0f };
void readFromFile()
{
fstream f("initials_points_2.txt", ios::in);
int pointNumber;
Point p;
f >> pointNumber;
for (int i = 0; i < pointNumber;i++)
{
f >> p.x >> p.y;
point.push_back(p);
}
int movesNumber, m;
f >> movesNumber;
for (int i = 0; i < movesNumber; i++)
{
f >> m; code.push_back(m);
}
f.close();
}
void moveto(Point p)
{
currentPoint.x = p.x; currentPoint.y = p.y;
}
void lineto(Point p)
{
glBegin(GL_LINES);
glVertex2i(currentPoint.x, currentPoint.y);
glVertex2i(p.x, p.y);
glEnd();
currentPoint.x = p.x; currentPoint.y = p.y;
}
void setRotationMatrix(float theta, float x0, float y0)
{
theta = theta * (2 * acos(0.0)) / 180; // convert theta from degrees to radian
rotationMatrix[0] = cos(theta);
rotationMatrix[1] = sin(theta);
rotationMatrix[4] = -sin(theta);
rotationMatrix[5] = cos(theta);
rotationMatrix[12] = ((x0 * 0.5f) * (1 - cos(theta)) + (y0 * 0.5f) * sin(theta));
rotationMatrix[13] = ((y0 * 0.5f) * (1 - cos(theta)) - (x0 * 0.5f) * sin(theta));
}
void drawM()
{
int i = 1;
moveto(point[0]);
while (code[i] > 0 && i < code.size())
{
lineto(point[code[i] - 1]);
i++;
}
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(letterMSizeX, 0.0, 0.0);
glVertex3f(letterMSizeX, 0.0, 0.0);
glVertex3f(letterMSizeX, modelSizeY, 0.0);
glVertex3f(letterMSizeX, modelSizeY, 0.0);
glVertex3f(0.0, modelSizeY, 0.0);
glVertex3f(0.0, modelSizeY, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINES);
glVertex2i(0, 0); glVertex2i(letterMSizeX, modelSizeY);
glVertex2i(letterMSizeX, 0); glVertex2i(0, modelSizeY);
glEnd();
}
void drawJ()
{
glColor3f(1.0, 0.0, 0.0);
int i = 14;
moveto(point[-1 * (code[i]) - 1]);
i++;
while (i < code.size())
{
lineto(point[code[i] - 1]);
i++;
}
glBegin(GL_LINES);
glVertex3f((modelSizeX - letterJSizeX), 0.0, 0.0);
glVertex3f((modelSizeX - letterJSizeX), modelSizeY, 0.0);
glVertex3f((modelSizeX - letterJSizeX), modelSizeY, 0.0);
glVertex3f(modelSizeX, modelSizeY, 0.0);
glVertex3f(modelSizeX, modelSizeY, 0.0);
glVertex3f(modelSizeX, 0.0, 0.0);
glVertex3f(modelSizeX, 0.0, 0.0);
glVertex3f((modelSizeX - letterJSizeX), 0.0, 0.0);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINES);
glVertex2i(letterMSizeX + 17, 0); glVertex2i(modelSizeX, modelSizeY);
glVertex2i(letterMSizeX + 17, modelSizeY); glVertex2i(modelSizeX, 0);
glEnd();
}
void drawInitials()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
setRotationMatrix(-rotater, letterMSizeX, modelSizeY);
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
drawM();
glTranslatef(-letterMSizeX * 0.5, -modelSizeY * 0.5, 0);
glPopMatrix();
glPushMatrix();
glTranslatef((modelSizeX - letterJSizeX), 0, 0);
setRotationMatrix(rotater, letterJSizeX, modelSizeY);
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
glTranslatef(-(modelSizeX - letterJSizeX), 0, 0);
drawJ();
glPopMatrix();
}
void processNormalKeys(unsigned char key, int x, int y)
{
switch (key)
{
case EscKey:
exit(0);
break;
case PlusKey: // "zoom in"
glMatrixMode(GL_MODELVIEW);
glMultMatrixf(plusKeyMatrix); // multiply current Modelview Matrix by scale-and-translate matrix
display();
break;
case MinusKey: // "zoom out"
glMatrixMode(GL_MODELVIEW);
glMultMatrixf(minusKeyMatrix); // multiply current Modelview Matrix by scale-and-translate matrix
display();
break;
}
}
void processSpecialKeys(int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
glMatrixMode(GL_MODELVIEW);
glTranslated(0, delta, 0);
display();
break;
case GLUT_KEY_DOWN:
glMatrixMode(GL_MODELVIEW);
glTranslated(0, -delta, 0);
display();
break;
case GLUT_KEY_LEFT:
glMatrixMode(GL_MODELVIEW);
glTranslated(-delta, 0, 0);
display();
break;
case GLUT_KEY_RIGHT:
glMatrixMode(GL_MODELVIEW);
glTranslated(delta, 0, 0);
display();
break;
case GLUT_KEY_HOME: //rotate clockwise around the center of the model
glMatrixMode(GL_MODELVIEW);
setRotationMatrix(-angle, modelSizeX, modelSizeY);
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
display();
break;
case GLUT_KEY_END: //rotate counterclockwise around the center of the model
glMatrixMode(GL_MODELVIEW);
setRotationMatrix(angle, modelSizeX, modelSizeY);
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
display();
break;
case GLUT_KEY_PAGE_UP:
rotater -= rotaterR;
if (rotater <= -2 * pi)
rotater += 2 * pi;
display();
break;
case GLUT_KEY_PAGE_DOWN:
rotater += rotaterR;
if (rotater >= 2 * pi)
rotater -= 2 * pi;
display();
break;
}
}
int main(int argc, char* argv[])
{
currentPoint.x = 0; currentPoint.y = 0;
readFromFile();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 150);
glutCreateWindow("OpenGL lab");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);
glutMainLoop();
return 0;
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
windowSizeX = w;
windowSizeY = h;
gluOrtho2D(-modelSizeX, modelSizeX * 2, -modelSizeY, modelSizeY * 2); // World size
}
void display()
{
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex2i(-windowSizeX, 0); glVertex2i(windowSizeX, 0);
glVertex2i(0, -windowSizeY); glVertex2i(0, windowSizeY);
glEnd();
glPopMatrix();
glColor3d(1, 0, 0);
drawInitials();
glPointSize(5);
glBegin(GL_POINTS);
glVertex3f(modelSizeX * 0.5, modelSizeY * 0.5, 0.0);
glVertex3f(letterMSizeX * 0.5, modelSizeY * 0.5, 0.0);
glVertex3f(letterJSizeX * 0.5 + letterMSizeX + 17, modelSizeY * 0.5, 0.0);
glEnd();
glFlush();
}
vertices file: initials_points_2.txt
I was trying to:
encapsulate _HOME/_END rotation with glPushMatrix()/glPopMatrix()
revert the rotation after the drawal of the object by multiplying MODELVIEW matrix with (-angle, same point)
was trying to drop glMultMatrix() and use glTranslate(), glRotate()
none of them had worked as I intended
Consider the following steps:
At first, rotate the object on the object coordinate system.
Next, place the object into the space (coordinate system) that you are considering the directions {up, down, left, and right} in.
i.e. for first rotation, the center must be the value in the object coordinate system. For example, object coordinate system is often defined as the origin equals to the center of object. In this case, rotation center is (0,0,0).
glPushMatrix();
//2nd step : Place the object
glTranslatef( ... );
//1st step : rotate the object
glRotatef( ... );
//object draw code
//(all vertex value is in the object coordinate system)
glPopMatrix();
I found out what I was doing wrong: buttons GLUT_KEY_HOME/GLUT_KEY_END should be performing rotations similar to those of GLUT_KEY_PAGE_UP/GLUT_KEY_PAGE_DOWN:
increase current rotation angle for the whole model (new variable to save rotation angle around the middle of the model);
call display method();
Then, inside display() method:
push current matrix into stack;
rotate model by the angle;
another push matrix into stack
rotate letters by the rotater variable changed in PAGE_UP/PAGE_DOWN
draw letters
pop matrix
pop matrix;
Code on keys:
case GLUT_KEY_HOME: //rotate clockwise around the center of the model
glMatrixMode(GL_MODELVIEW);
angle -= rotationRate;
if (angle <= -2 * pi)
angle += 2 * pi;
display();
break;
case GLUT_KEY_END: //rotate counterclockwise around the center of the model
glMatrixMode(GL_MODELVIEW);
angle += rotationRate;
if (angle >= 2 * pi)
angle -= 2 * pi;
display();
break;
edited drawInitials() method (called from display() method):
void drawInitials()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
setRotationMatrix(angle, modelSizeX, modelSizeY); //set rotation matrix to rotate around the center of the model by current angle
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
glPushMatrix();
setRotationMatrix(-rotater, letterMSizeX, modelSizeY); //set to rotate around the center of the letter M by current rotater Clockwise
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
drawM();
glPopMatrix();
glPushMatrix();
glTranslatef((modelSizeX - letterJSizeX), 0, 0); // move OX axis by the size of letter M + space between the letters
setRotationMatrix(rotater, letterJSizeX, modelSizeY);//set to rotate around the center of the letter J by current rotater Counter Clockwise
glMultMatrixf(rotationMatrix); // multiply current Modelview Matrix by rotate-and-translate matrix
glTranslatef(-(modelSizeX - letterJSizeX), 0, 0); // return OX axis to its previous place
drawJ();
glPopMatrix();
glPopMatrix();
}
In setRotationMatrix() remove conversion into radian;
Add new variable rotationRate to use it as an incriment for both rotations:
float angle;
// saved rotation angle around center of the model (radian)
float rotater;
// rotater - saved rotation angle around center of the letter (radian)
float rotationRate = 1 * pi / 180; // rotation rate (radian), ex rotaterR
I'm trying to make a program where I'm able to zoom in & out on the figures I've drawn, but is not doing it; it's switching the orientation of the figures and if I keep scrolling, it just disappears. The function that are suppose to be executed for this to work are the MouseFunc() along with the renderScene(). Any explanation for the problem or help is welcomed.
#include"glut.h"
#include<cmath>
#include<iostream>
using namespace std;
float xr = 0, yr = 0; //to control the object's movement from left to right
// XZ position of the camera
float x = 0.0f, z = 5.0f; //Module 4
float angleX = 0.0f; //Module 4
//Shift + ArrowKey rotation
float transX = 0.0f;
float transY = 0.0f;
float rotY = 0.0f;
//end
//Mouse Commands
//float ZoomFactor = 0.5;
GLfloat theta3 = 0;
GLfloat phi = 0;
GLfloat rho = 5;
GLfloat camX = 0;
GLfloat camY = 0;
GLfloat camZ = 0;
GLfloat upX = 0;
GLfloat upY = 0;
GLfloat upZ = 0;
//end
GLfloat angle = 0.0f;
int refreshmill = 1;
void timer(int value) { //to control the rotation of the object
glutTimerFunc(refreshmill, timer, 0);
}
void myDisplay(void) {
//Circle One
float theta;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0);
glPushMatrix();
glBegin(GL_POLYGON);
for (int x = 0; x < 360; x++) {
theta = x * 3.142 / 180;
glVertex2f(150 * cos(theta) + xr, 150 * sin(theta) + yr);
}
glEnd();
glPopMatrix();
//Circle Two
float theta2;
glPushMatrix();
glTranslatef(0.5f, 0.0f, 0.0f); // rotation
glRotatef(angle, 0.0f, 0.0f, -0.5f); // rotation
glBegin(GL_POLYGON);
glColor3f(0, 0, 1);
for (int x = 0; x < 360; x++) {
theta2 = x * 3.142 / 180;
glVertex2f(150 + 15 * cos(theta2) + xr, 15 * sin(theta2) + yr);
}
angle += 0.2; // rotation
glEnd();
glPopMatrix();
//Draw Star
glColor3ub(119, 193, 15);
glPushMatrix();
glBegin(GL_POLYGON);
glVertex2d(15 + xr, 60 + yr);
glVertex2d(75 + xr, 75 + yr); //right peak
glVertex2d(15 + xr, 90 + yr);
glVertex2d(0 + xr, 150 + yr); //Up-peak Changed
glVertex2d(-15 + xr, 90 + yr);
glVertex2d(-75 + xr, 75 + yr);
glVertex2d(-15 + xr, 60 + yr);
glVertex2d(0 + xr, 0 + yr);
glEnd();
glPopMatrix();
}
//Close code
void handleKeypress(unsigned char key, int x, int y){
switch (key){
case 27: //when the escape key is pressed the program will exit.
exit(0);
}
}
//Movement of drawing
void keyboard(int key, int x, int y) {
float fraction = 0.1f;
bool shift = false;
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_SHIFT) {
shift = true;
}
if (!shift) {
switch (key) {
case GLUT_KEY_RIGHT: xr++; break;
case GLUT_KEY_LEFT: xr--; break;
case GLUT_KEY_UP: angleX -= 1.0f; break; //Module 4
case GLUT_KEY_DOWN: angleX += 1.0f; break; //Module 4
}
}
else {
switch (key) {
case GLUT_KEY_LEFT:// Rotación del dibujo hacia la izquierda en el eje de Y
rotY -= 1.0f;
break;
case GLUT_KEY_RIGHT:// Rotación del dibujo hacia la derecha en el eje de Y
rotY += 1.0f;
break;
}
}
}
//Mouse Function
void MouseFunc(int button, int state, int x, int y){
if (button > 4){
rho = rho + 3.0;
}
else (button < 3);{
rho = rho - 3.0;
}
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
glRotatef(rotY, 0.0, 1.0, 0.0); //Rotation with Shift + ArrowKey
GLfloat camX = rho * cos(theta3*3.1415926f / 180)*sin(phi*3.1415926f / 180);
GLfloat camY = rho * sin(theta3*3.1415926f / 180);
GLfloat camZ = rho * cos(theta3*3.1415926f / 180)*cos(phi*3.1415926f / 180);
// Reduce theta slightly to obtain another point on the same longitude line on the sphere.
GLfloat dt = 1;
GLfloat eyeXtemp = -rho * cos((theta3 - dt)*3.1415926f / 180)*sin(phi*3.1415926f / 180);
GLfloat eyeYtemp = -rho * sin((theta3 - dt)*3.1415926f / 180);
GLfloat eyeZtemp = -rho * cos((theta3 - dt)*3.1415926f / 180)*cos(phi*3.1415926f / 180);
// Connect these two points to obtain the camera's up vector.
GLfloat upX = eyeXtemp - camX;
GLfloat upY = eyeYtemp - camY;
GLfloat upZ = eyeZtemp - camZ;
// Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the camera
gluLookAt(camX, camY, camZ, 0, 0, 0, upX, upY, upZ);
gluLookAt(x, 0.0f, z, x, 0.0f, z - 1.0f, 0.0f, 1.0f, 0.0f); //Module 4
glRotatef(angleX, 1, 0, 0); //Module 4
myDisplay();
glFlush();
glutPostRedisplay();
glutSwapBuffers();
}
void init() {
glClearColor(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(0.0f, 0.1f, 0.1f, 0.0f);
glOrtho(-250, 250, -250, 250, -250, 250); //IMPORTANT- Define from negative to positive
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
// init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Homework: Circle");
// register callbacks
glutDisplayFunc(renderScene);
glutTimerFunc(0,timer,0);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(keyboard);
glutMouseFunc(MouseFunc);
// OpenGL init
init();
// enter GLUT event processing cycle
glutMainLoop();
}
Is wired to set a perspective and an orthographic projection. Delete the perspective projection gluPerspective:
void init() {
glClearColor(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(0.0f, 0.1f, 0.1f, 0.0f); <---- delete
glOrtho(-250, 250, -250, 250, -250, 250);
glMatrixMode(GL_MODELVIEW);
}
If you want to zoom, the the orthographic projection has to be changed (glOrtho). The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport.
Implement a mouse wheel event, which changes the zoom, in a restricted range:
e.g.
GLdouble zoom = 0.0f;
void MouseFunc(int button, int state, int x, int y){
GLdouble min_z = -100.0;
GLdouble max_z = 100.0;
if (button == 4 && zoom < max_z) {
zoom += 3.0;
}
else if (button == 3 && zoom > min_z) {
zoom -= 3.0;
}
}
Modify the orthographic projection, dependent on the zoom in the display loop renderScene:
void renderScene(void) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble ortho = 250 + zoom;
glOrtho(-ortho, ortho, -ortho, ortho, -250, 250);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// [...]
}
void drawTire(void)
{
GLint num_of_tri = 32;
GLfloat vertex[3];
const GLfloat delta_angle = 2.0*PI/float(num_of_tri);
//Draw Front tire
glBegin(GL_TRIANGLE_FAN);
glColor3f(0.5, 0.5, 0.5);
vertex[0] = vertex[1] = vertex[2] = 0.0;
glVertex3fv(vertex);
for(int i = 0; i < num_of_tri ; i++)
{
vertex[0] = cos(delta_angle*i) * wheelRadius; //wheel Radius is 1.0
vertex[1] = sin(delta_angle*i) * wheelRadius;
vertex[2] = 0.0;
glVertex3fv(vertex);
}
vertex[0] = 1.0 * wheelRadius;
vertex[1] = 0.0 * wheelRadius;
vertex[2] = 0.0;
glVertex3fv(vertex);
glEnd();
//Draw Back Tire
const GLfloat depth = -wheelRadius/1.5;
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0, 0.0, 0.0);
vertex[0] = vertex[1] = 0.0;
vertex[2] = depth;
glVertex3fv(vertex);
for(int i = 0; i < num_of_tri ; i++)
{
vertex[0] = cos(delta_angle*i) * wheelRadius;
vertex[1] = sin(delta_angle*i) * wheelRadius;
vertex[2] = depth;
glVertex3fv(vertex);
}
vertex[0] = 1.0 * wheelRadius;
vertex[1] = 0.0 * wheelRadius;
vertex[2] = depth;
glVertex3fv(vertex);
glEnd();
//Connect Front&Back
glBegin(GL_QUADS);
glColor3f(0.0, 0.0, 0.0);
for(int i = 0; i < num_of_tri; i++)
{
vertex[0] = cos(delta_angle*i) * wheelRadius;
vertex[1] = sin(delta_angle*i) * wheelRadius;
vertex[2] = 0;
glVertex3fv(vertex);
vertex[0] = cos(delta_angle*i) * wheelRadius;
vertex[1] = sin(delta_angle*i) * wheelRadius;
vertex[2] = depth;
glVertex3fv(vertex);
vertex[0] = cos(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
vertex[1] = sin(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
vertex[2] = depth;
glVertex3fv(vertex);
vertex[0] = cos(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
vertex[1] = sin(delta_angle*((i + 1)%num_of_tri)) * wheelRadius;
vertex[2] = 0;
glVertex3fv(vertex);
}
glEnd();
glFlush();
}
I'm using the above code to draw a (kind of) 3D car wheel. This code appears to work.
This is my init function:
void init(void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45.0f, (GLfloat)1366/(GLfloat)768, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0, 0, 0, 0, 1, 0);
}
This is my display function:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
drawTire();
glFlush();
}
The result is messed up car wheel as can be seen here: http://postimg.org/image/fuf9o75ub/
The front of the tire (the side that the camera should be looking at) is gray. The camera somehow looks at the back of the tire, which is red.
Also, the tire side (the one the that touches the ground. I have no idea how to name it) is also shown, which is weird (the black color).
Why does gluPerspective messes up 3D object, and how can one fix this? (I have tried changing the fov... result were almost the same)
Right now, you aren't using depth testing. This means that the last primitive rendered is the one "on top", since without depth testing, OpenGL has no way of knowing the 'depth' of a pixel after it has been rendered.
To solve this problem, OpenGL uses a depth buffer, which is a hidden screen-sized buffer that stores how far away each pixel is from the camera. With depth testing enabled, when OpenGL renders a fragment, it first checks the depth of the fragment and compares it to the value in the depth buffer. If the fragment's depth value is smaller than the stored value (note 1), then OpenGL concludes that the fragment is in front of an already rendered object and writes the fragment. Otherwise, its behind an object and ignores the fragment.
To use depth testing, you first need to make sure you've allocated a depth buffer when you created your context. This depends on what windowing library you are using, but usually they give you a depth buffer by default.
You then need call glEnable(GL_DEPTH_TEST) to begin using depth testing.
Additionally, you need to clear the depth values in the depth buffer when you re-render your scene. Change glClear(GL_COLOR_BUFFER_BIT) to glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT).
And that's all you need to use depth testing.
(note 1): More specfically, it uses whatever function was set glDepthFunc, though 99% of the time this is GL_LESS or GL_LEQUAL.
I'm trying to draw simple circle with C++/OpenGl
my code is:
#include <GL/glut.h>
#include <math.h>
void Draw() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glColor3f (0.0, 0.0, 0.0);
glVertex3f (0.1, 0.1, 0.0);
glVertex3f (0.9, 0.1, 0.0);
glVertex3f (0.9, 0.9, 0.0);
glVertex3f (0.1, 0.9, 0.0);
glEnd();
glFlush();
}
void DrawCircle(float cx, float cy, float r, int num_segments)
{
glBegin(GL_LINE_LOOP);
for(int ii = 0; ii < num_segments; ii++)
{
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void Initialize() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(950, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("Universum");
Initialize();
glutDisplayFunc(Draw);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
DrawCircle(0.5, 0.5, 0.2, 5);
glutMainLoop();
return 0;
}
I'm beginner with OpenGL and now i'm starting to learn,
Can someone please explain me why i don't get the circle (i only see the black box),
Thanks!
It looks like immediately after you draw the circle, you go into the main glut loop, where you've set the Draw() function to draw every time through the loop. So it's probably drawing the circle, then erasing it immediately and drawing the square. You should probably either make DrawCircle() your glutDisplayFunc(), or call DrawCircle() from Draw().
#include <Windows.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define window_width 1080
#define window_height 720
void drawFilledSun(){
//static float angle;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -10);
int i, x, y;
double radius = 0.30;
//glColor3ub(253, 184, 19);
glColor3ub(255, 0, 0);
double twicePi = 2.0 * 3.142;
x = 0, y = 0;
glBegin(GL_TRIANGLE_FAN); //BEGIN CIRCLE
glVertex2f(x, y); // center of circle
for (i = 0; i <= 20; i++) {
glVertex2f (
(x + (radius * cos(i * twicePi / 20))), (y + (radius * sin(i * twicePi / 20)))
);
}
glEnd(); //END
}
void DrawCircle(float cx, float cy, float r, int num_segments) {
glBegin(GL_LINE_LOOP);
for (int ii = 0; ii < num_segments; ii++) {
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void main_loop_function() {
int c;
drawFilledSun();
DrawCircle(0, 0, 0.7, 100);
glutSwapBuffers();
c = getchar();
}
void GL_Setup(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
gluPerspective(45, (float)width / height, .1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("GLUT Example!!!");
glutIdleFunc(main_loop_function);
GL_Setup(window_width, window_height);
glutMainLoop();
}
This is what I did. I hope this helps. Two types of circle are here. Filled and unfilled.
There is another way to draw a circle - draw it in fragment shader.
Create a quad:
float right = 0.5;
float bottom = -0.5;
float left = -0.5;
float top = 0.5;
float quad[20] = {
//x, y, z, lx, ly
right, bottom, 0, 1.0, -1.0,
right, top, 0, 1.0, 1.0,
left, top, 0, -1.0, 1.0,
left, bottom, 0, -1.0, -1.0,
};
Bind VBO:
unsigned int glBuffer;
glGenBuffers(1, &glBuffer);
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*20, quad, GL_STATIC_DRAW);
and draw:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_VALUE);
glVertexAttribPointer(ATTRIB_VERTEX , 3, GL_FLOAT, GL_FALSE, 20, 0);
glVertexAttribPointer(ATTRIB_VALUE , 2, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Vertex shader
attribute vec2 value;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
varying vec2 val;
void main() {
val = value;
gl_Position = projectionMatrix*viewMatrix*vertex;
}
Fragment shader
varying vec2 val;
void main() {
float R = 1.0;
float R2 = 0.5;
float dist = sqrt(dot(val,val));
if (dist >= R || dist <= R2) {
discard;
}
float sm = smoothstep(R,R-0.01,dist);
float sm2 = smoothstep(R2,R2+0.01,dist);
float alpha = sm*sm2;
gl_FragColor = vec4(0.0, 0.0, 1.0, alpha);
}
Don't forget to enable alpha blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
UPDATE: Read more
We will find the value of X and Y from this image. We know, sinθ=vertical/hypotenuse and cosθ=base/hypotenuse from the image we can say X=base and Y=vertical. Now we can write X=hypotenuse * cosθ and Y=hypotenuse * sinθ.
Now look at this code
void display(){
float x,y;
glColor3f(1, 1, 0);
for(double i =0; i <= 360;){
glBegin(GL_TRIANGLES);
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
i=i+.5;
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
glVertex2d(0, 0);
glEnd();
i=i+.5;
}
glEnd();
glutSwapBuffers();
}
glBegin(GL_POLYGON); // Middle circle
double radius = 0.2;
double ori_x = 0.0; // the origin or center of circle
double ori_y = 0.0;
for (int i = 0; i <= 300; i++) {
double angle = 2 * PI * i / 300;
double x = cos(angle) * radius;
double y = sin(angle) * radius;
glVertex2d(ori_x + x, ori_y + y);
}
glEnd();
Here is a code to draw a fill elipse, you can use the same method but replacing de xcenter and y center with radius
void drawFilledelipse(GLfloat x, GLfloat y, GLfloat xcenter,GLfloat ycenter) {
int i;
int triangleAmount = 20; //# of triangles used to draw circle
//GLfloat radius = 0.8f; //radius
GLfloat twicePi = 2.0f * PI;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x, y); // center of circle
for (i = 0; i <= triangleAmount; i++) {
glVertex2f(
x + ((xcenter+1)* cos(i * twicePi / triangleAmount)),
y + ((ycenter-1)* sin(i * twicePi / triangleAmount))
);
}
glEnd();
}
I have done it using the following code,
glBegin(GL.GL_LINE_LOOP);
for(int i =0; i <= 300; i++){
double angle = 2 * Math.PI * i / 300;
double x = Math.cos(angle);
double y = Math.sin(angle);
gl.glVertex2d(x,y);
}
glEnd();
glBegin(GL_POLYGON);
double x = 2;
double y = 2;
for (int i = 0; i <= 360; i++) {
glVertex2d(x * sin(i), y * cos(i));
}
glEnd();