I am using the SFML library, which in its latest RC allows you to manipulate vertices and draw them like so :
// define a 100x100 square, red, with a 40x40 texture mapped on it
sf::Vertex vertices[] =
{
sf::Vertex(sf::Vector2f( 0, 0), sf::Color::White, sf::Vector2f( 0, 0)),
sf::Vertex(sf::Vector2f( 0, 100), sf::Color::White, sf::Vector2f( 0, 40)),
sf::Vertex(sf::Vector2f(100, 100), sf::Color::White, sf::Vector2f(40, 40)),
sf::Vertex(sf::Vector2f(100, 0), sf::Color::White, sf::Vector2f(40, 0))
};
Now my question is: what would be the best way to draw a curve / an angular sector?
The rendering process is calling OpenGL so you may be more familliar with it than SFML.
Basically is it possible to draw curves by not defining 1 point per pixel?
thanks
Without using OpenGL directly, no. But usually curves are made of a sequence of lines. Just calc points of your curve (no need to be one per pixel), and draw a line strip.
Related
I need to draw indented(concave) solid polygon with some vertices.
I use
void HelloWorld::draw(void)
{
CCPoint vertices[5] = {ccp(200, 200), ccp(400, 400), ccp(200, 600), ccp(500, 600), ccp(500, 200)};
ccDrawSolidPoly(vertices, 5, ccc4f(0.7f, 0.7f, 0.7f, 0.5f));
}
And get Rectangle with triangle inside.
But I expect indented(concave) solid polygon as in the picture
Try using drawPolygon function in CCDrawNode
void drawPolygon(CCPoint* verts, unsigned int count, const ccColor4F &fillColor,
float borderWidth, const ccColor4F& borderColor)
here is an example
CCPoint vertices[5] = {ccp(200, 200), ccp(400, 400), ccp(200, 600), ccp(500, 600), ccp(500, 200)};
CCDrawNode* polygon = CCDrawNode::create();
//creating red polygon with thin black border
polygon->drawPolygon(vertices, 5, ccc4f(1, 0, 0, 1), 1, ccc4f(0, 0, 0, 1));
addChild(polygon);
I hope it works
Without modifications to Cocos2d engine you can achive the polygon of the desired form either by starting your array from ccp(400,400) or by adding one more point ccp(500,400)! And then your array of points should start from this point like in the picture I attach.
The reason for this is that cocos2d uses by default GL_TRIANGLE_FAN flag while drawing complex polygons. This means that all the points in the triangles in your polygon will be built relative to the first point in the array of points.
You can go to CCDrawNode.cpp file and replace this flag by GL_TRIANGLE_SPLIT. To know more just google these two flags.
//component
glRotatef((GLfloat)-90, 1, 0, 0);
gluCylinder(qObj,t_width/2,t_width/2,t_height+2*UDwall, 20, 20);
glRotatef((GLfloat)90, 1, 0, 0);
I want to draw a Cylinder attaching the part of texture.
glBindTexture(GL_TEXTURE_2D, texName[1]);//+
But not like glVertex3f, when I bind a texture that can not do by using TexCoord.
(so just whole texture printed ;ㅅ;)
First is What can I do for adjusting the part of texture.
Second is (someone suggested using texture atlas)can I change the texture's Max coord(0.0~1.0) to other number?
You could use a TextureMatrix to transform the coordinates of the texture so the desired rectangle shape (from texture altas) is in the right position.
So lets say you want to texture a rect that has coordinates (x,y) and dimensions (a,b). What we want to achieve here is to have the texture be at (0,0) for (x,y) and (1,1) for (x+a, y+b).
Solution
use Texture Matrix
translate by (-x, -y)
scale by (1.0 / a, 1.0 / b)
It may be a duplicate with this question,
but I don't know how to apply this approach in my app, and which method I should use in cocos2d-x to draw a Bezier curve. My app should allow users to draw lines and curves when they touch the canvas. How can I achieve that?
From Cocos2dx v3.3 you can use DrawNode to draw Bezier curves. Check the DrawPrimitivesTest.cpp, it is very easy to use.
This is only a sample script taken from the above mentioned file. You can use it anywhere in your Scene:
auto draw = DrawNode::create();
addChild(draw, 10);
auto s = Director::getInstance()->getWinSize();
draw->drawQuadBezier(Vec2(0, s.height), Vec2(s.width/2, s.height/2), Vec2(s.width, s.height), 50, Color4F(CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), 0.5));
draw->drawCubicBezier(VisibleRect::center(), Vec2(VisibleRect::center().x+30,VisibleRect::center().y+50), Vec2(VisibleRect::center().x+60,VisibleRect::center().y-50),VisibleRect::right(),100, Color4F(CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), 0.5));
in CCDrawPrimitives.cpp file.
You can use this method.
ccDrawCubicBezier
ccDrawQuadBezier
-MyClass::draw() {
glLineWidth(4.0f);
ccPointSize(4);
//Draw a blue quadratic bezier curve
ccDrawColor4B(0, 0, 255, 255);
ccDrawQuadBezier(ccp(90,0), ccp(200, 70), ccp(350,0), 12);
//Draw cubic red bezier curve
ccDrawColor4B(255, 0, 0, 255);
ccDrawCubicBezier(ccp(100,100), ccp(300,150), ccp(250,50), ccp(350,100), 12);
//Restore original values
glLineWidth(1);
ccDrawColor4B(255,255,255,255);
ccPointSize(1);
}
Every time you move your touch positions, ccTouchesMoved method is called as you may know.
You can control the curve shape using the method and member variables.
I am a beginner in openGL. I am currently working on a program which take in inputs the width and the length of a board. Given those inputs i want to dynamically position my camera so that i can have a view on the whole board. Let' s say that my window size is 1024x768.
Are there any mathematical formula to compute the different parameters of the opengl function glookat to make it possible ?
the view i want to have on the board should look like this.
It doesn't matter if a board too big will make things look tiny. What matters the most here is to position the camera in a way that the view on the whole board is made possible
So far i am hopelessly randomly changing the parameters of my glookat function till i ran into something decent for a X size width and and Y size Height.
my gluperpective function :
gluPerspective(70 ,1024 / 768,1,1000)
my glooatfunction for a 40 * 40 board
gluLookAt(20, 20, 60, 20, -4, -20, 0, 1, 0);
how i draw my board (plane):
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(20, 20, 60, 20, -4, -20, 0, 1, 0);
glBindTexture(GL_TEXTURE_2D, texture_sol);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3i(width, 0, height);
glTexCoord2i(10, 0); glVertex3i(0, 0, height)
glTexCoord2i(10, 10); glVertex3i(0, 0, 0);
glTexCoord2i(0, 10); glVertex3i(width, 0, 0);
glEnd();
the output looks as follow :
gluLookAt takes 2 points and a vector; the eye and centre positions and the up vector. There's no issue with the last parameter. The first two are relevant to your question.
I see that your board in the world space is extending on the positive X and Y axes with some arbitrary width and height values. Lets take width = height = 1.0 for instance. So the board spans from (0, 0), (1, 0), (1, 1), (0, 1); the Y value is ignored here since the board lies on the Y = 0 plane and have the same value for all vertices; these are just (X, Z) values.
Now coming to gluLookAt, eye is where the camera is in world space and centre is the point where you want the camera to be looking at (in world space)
Say you want the camera to look at centre of the board I presume, so
eye = (width / 2.0f, 0, height/2.0f);
Now you've to position the camera at its vantage point. Say somewhere above the board but towards the positive Z direction since there's where the user is (assuming your world space is right handed and positive Z direction is towards the viewer), so
centre = (width / 2.0f, 5.0f, 1.0f);
Since the farthest point on Z is 0, I just added one more to be slightly father than that. Y is how much above you want to see the board from, I just chose 5.0 as an example. These are just arbitrary values I can come up with, you'll still have to experiment with these values. But I hope you got the essence of how gluLookAt works.
Though this is written as an XNA tutorial, the basic technique and math behind it should carry over to OpenGL and your project:
Positioning the Camera to View All Scene Objects
Also see
OpenGL FAQ
8.070 How can I automatically calculate a view that displays my entire model? (I know the bounding sphere and up vector.)
Edit in response to the comment question
A bounding sphere is simply a sphere that completely encloses your model. It can be described as:
A bounding sphere, S, of a point set P with n points is described by
a center point, c, and a radius, r.
So,
P = the vertices of your model (the board in this case)
c = origin of your model
r = distance from origin of the vertex, in P, farthest from the origin
So the Bounding Sphere for your board would be composed of the origin location (c) and the distance from one corner to the origin (r) assuming the board is a square and all points are equidistant.
For more complicated models, you may employ pre-created solutions [1] or implement your own calculations [2] [3]
I have just read the following:
Let's say we want to have the player view an object located at the
world's origin (0, 0, 0). We want the player to be viewing the object
from the coordinates (100, 100, 100). To do this we need to build a
matrix containing this data. We build this matrix using a function
called XMMatrixLookAtLH(). Here is how you use it:
XMVECTOR vecCamPosition = XMVectorSet(100, 100, 100, 0);
XMVECTOR vecCamLookAt = XMVectorSet(0, 0, 0, 0);
XMVECTOR vecCamUp = XMVectorSet(0, 1, 0, 0);
XMMATRIX matView = XMMatrixLookAtLH(vecCamPosition, vecCamLookAt, vecCamUp);
from: http://www.directxtutorial.com/Lesson.aspx?lessonid=111-6-1
I do not understand why if you want to look at an object located at 0, 0, 0, you should position the camera at 100, 100, 100... surely that would mean the camera was way past it... and then looking back at it?
thing is, if I set my camera to 0.0, 0.0, -1.0 and have my objects at a z index of 1.0... my camera can no longer see my objects...
I don't get it?
It sounds like you have 2D objects "facing" away from the camera when positioned at (0, 0, -1). If you reverse your ordering on your triangle vertices, they should show up.
You are fine to put the camera wherever you wish. If you are looking at 3D objects, you should have no issues.
In DirectX, 2D objects can only be seen when their vertices are in clockwise ordering as seen from the camera (though you can turn this off, or change it to discard counter-clockwise triangles if you wish). DirectX uses the clockwise vs counter-clockwise ordering to discard faces so it doesn't draw the backs of 3D objects.