Rotating a label in Visual C++ 6 - visual-c++

I am trying to rotate a label using a function but it is not working.
I only get a label without a rotation.
The label should be rotated along the point (x, y) which is the middle position
of the label (just=TX_JUST_CENTER).
The counter-clockwise rotation angle (=theta) is given as degrees.
I would appreciate any help on this. Thanks.
void do_labely(
HDC meta_dc,
SLATE_REC *slate_rec,
const DEFAULT_STYLE *styl,
double x,
double y,
unsigned char *the_str,
short just,
short style_idx,
short size,
short stylebits,
short color,
short v_just,
BOOL clip,
double theta)
{
LOGFONT lf;
HFONT font;
UINT align;
setup_logfont(meta_dc ,&styl[ style_idx ], size, &lf, slate_rec, stylebits);
font = CreateFontIndirect( &lf );
GetObject(font, sizeof(lf), &lf);
SelectObject( meta_dc,font );
switch (color) {
case WHITE:
SetTextColor( meta_dc,RGB( 0xFF,0xFF,0xFF ) );
break;
case RED:
SetTextColor( meta_dc,RGB( 0xFF,0x00,0x00 ) );
break;
case GREEN:
SetTextColor( meta_dc,RGB( 0x00,0xFF,0x00 ) );
break;
case BLUE:
SetTextColor( meta_dc,RGB( 0x00,0x00,0xFF ) );
break;
case BLACK:
// this is the default
SetTextColor( meta_dc,RGB( 0x00,0x00,0x00 ) );
break;
}
switch (just) {
case TX_JUST_LEFT:
// this is the default
align = TA_LEFT;
break;
case TX_JUST_CENTER:
align = TA_CENTER;
break;
case TX_JUST_RIGHT:
align = TA_RIGHT;
break;
}
switch (v_just) {
case TX_JUST_TOP:
// this is the default
align += TA_TOP;
break;
case TX_JUST_BASE:
align += TA_BASELINE;
break;
case TX_JUST_BOTTOM:
align += TA_BOTTOM;
break;
}
SetTextAlign(meta_dc, align);
SetGraphicsMode(meta_dc, GM_ADVANCED);
double rad = theta * PI/180;
XFORM xform;
xform.eM11 = cos(rad);
xform.eM12 = -sin(rad);
xform.eM21 = sin(rad);
xform.eM22 = cos(rad);
//Apply rotation
ModifyWorldTransform(meta_dc, &xform, MWT_LEFTMULTIPLY);
//Draw the text
int x1 = (int)( x * slate_rec->xscale );
int y1 = (int)( y * slate_rec->yscale);
TextOut(meta_dc, x1, y1, (char *)the_str, strlen((char *)the_str));
//Reset the world transform to original
SetWorldTransform(meta_dc, &xform);
SelectObject( meta_dc,GetStockObject(SYSTEM_FONT) );
DeleteObject(font);
}

Related

How to switch between 'scenes' using switch statement

so I'm creating an interactive story, and I want to switch between scenes by clicking buttons (like a standard old pokemon game except there isn't movement, just clicking).
I should probably use a switch statement right? But I don't know how to implement the changing of scenes and loading scenes into the cases. I also don't know if I would need to use 'if' statements within the cases.
This might be confusing, because it is very confusing to me. I'd appreciate any help you guys offer! I am desperate ;)
Code so far is below:
//PImages
PImage startScreen;
PImage[] waves = new PImage[3];
PImage[] scenes = new PImage[1];
int switchVariable;
//Objects
Button play;
void setup() {
size(750, 600);
background(#A3E9EA);
//Initialising Objects
play = new Button(50, 480, 330);
//loading wave images
waves[0] = loadImage("wave1.png");
waves[1] = loadImage("wave2.png");
waves[2] = loadImage("wave3.png");
//loading start image
startScreen = loadImage("start-screen.png");
//loading scenes
scenes[0] = loadImage("scene-one.png");
//setting frame rate
frameRate(6);
}
void draw() {
background(#A3E9EA);
frameCount++;
println (frameCount);
//drawing wave animation
if (frameCount < 5) {
image(waves[0], 0, 0);
}
else {
image(waves[1], 0, 0);
}
if (frameCount < 15 & frameCount > 10) {
background(#A3E9EA);
image(waves[2], 0, 0);
frameCount = 0;
}
//drawing start screen
image(startScreen, 0, 0);
//displaying play button
if (play.visible) play.buttonDisplay();
}
void mousePressed() {
if (play.visible) {
float d = dist(play.x+110, play.y+22, mouseX, mouseY);
if (d <= play.radius){
background(#A3E9EA);
image(scenes[0], 0, 0);
}
}
}
Button Class:
class Button {
float radius;
float x;
float y;
PImage[] buttonImage = new PImage[2];
boolean visible;
Button(float _radius, float _x, float _y) {
radius = _radius;
visible = true;
x = _x;
y = _y;
buttonImage[0] = loadImage("play-game-button.png");
}
void buttonDisplay() {
image(buttonImage[0], x, y);
}
}
The source code below shows one possible approach to your question. It does not rely on ‘switch’ but instead uses a custom control with up and down buttons similar to a Java stepper. The stepper control value corresponds with images in the scenes array and the background() is set accordingly. A separate button class is required and code for this follows the demo.
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
color GREEN = color(0, 255, 0);
color ORANGE = color(247, 168, 7);
PFont font;
PImage[] scenes = new PImage[6];
// **** Up/Down Buttons init, min, max values **** //
final int _initValue = 2;
final int _maxValue = 5;
final int _minValue = 0;
int stepperValue = 0;
Button _up;
Button _dwn;
Button _quit;
final int _displayX = 160;
final int _displayY = 30;
final int _displayW = 100;
final int _displayH = 24;
final int _txtSize = 18;
void stepperValueDisplay(int value) {
fill(WHITE); // background color
noStroke();
rect(_displayX, _displayY, _displayW, _displayH, 0);
fill(BLACK); // text color
textSize(_txtSize);
textAlign(CENTER);
String str = String.format("Scene %d", value);
text(str, _displayX, _displayY, _displayW, _displayH);
}
void scene_0(){
background(RED);
save("scene0.png");
}
void scene_1(){
background(GREEN);
save("scene1.png");
}
void scene_2(){
background(BLACK);
save("scene2.png");
}
void scene_3(){
background(YELLOW);
save("scene3.png");
}
void scene_4(){
background(LTGRAY);
save("scene4.png");
}
void scene_5(){
background(ORANGE);
save("scene5.png");
}
void setup() {
size(600, 600);
background(BLUE);
font = createFont("Menlo-Bold", 20);
_dwn = new Button( _displayX - 40, _displayY, 40, 24, "--", LTGRAY, BLACK);
_up = new Button( _displayX + _displayW, _displayY, 40, 24, "++", LTGRAY, BLACK);
stepperValue = _initValue;
_quit = new Button(width - 60, 20, 30, 24, "Q", LTGRAY, BLACK);
scene_0();
scene_1();
scene_2();
scene_3();
scene_4();
scene_5();
scenes[0] = loadImage("scene0.png");
scenes[1] = loadImage("scene1.png");
scenes[2] = loadImage("scene2.png");
scenes[3] = loadImage("scene3.png");
scenes[4] = loadImage("scene4.png");
scenes[5] = loadImage("scene5.png");
}
void draw() {
background(scenes[stepperValue]);
_up.display();
_dwn.display();
_quit.display();
stepperValueDisplay(stepperValue);
}
void mousePressed() {
if (mouseX > _quit.x && mouseX < _quit.x + _quit.w && mouseY > _quit.y && mouseY < _quit.y + _quit.h) {
exit();
}
if (mouseX > _up.x && mouseX < _up.x + _up.w && mouseY > _up.y && mouseY < _up.y + _up.h) {
stepperValue++;
if (stepperValue > _maxValue) {
stepperValue = _maxValue;
}
stepperValueDisplay(stepperValue);
}
if (mouseX > _dwn.x && mouseX < _dwn.x + _dwn.w && mouseY > _dwn.y && mouseY < _dwn.y + _dwn.h) {
stepperValue--;
if (stepperValue < _minValue) {
stepperValue = _minValue;
}
stepperValueDisplay(stepperValue);
}
}
Button Class:
int _btnTxtSize = 18;
class Button {
float x, y, w, h;
String title;
color bkgrndColor;
color txtColor;
// Constructor
Button(int xpos, int ypos, float wt, float ht, String titleStr, color background, color textColor) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = titleStr;
bkgrndColor = background;
txtColor = textColor;
}
void display(){
fill(bkgrndColor);
noStroke();
rect( x, y, w, h, 0);
fill(txtColor);
textSize(_btnTxtSize);
textAlign(CENTER);
text(title, x, y, w, h);
}
}

Simple 3D Shape faces not rendering as expected - OpenGL ES in Android Studio

I am trying to make a rotating octahedron display correctly, I have successfully achieved other shapes such as a cube and tetrahedron, but I am experiencing some difficulty with this one.
Here is the simple obj file I am using:
v 0 -1 0
v 1 0 0
v 0 0 1
v -1 0 0
v 0 1 0
v 0 0 -1
#
f 1 2 3
f 4 1 3
f 5 4 3
f 2 5 3
f 2 1 6
f 1 4 6
f 4 5 6
f 5 2 6
My code is as follows:
class Shape(context: Context) {
private var mProgram: Int = 0
// Use to access and set the view transformation
private var mMVPMatrixHandle: Int = 0
//For Projection and Camera Transformations
private var vertexShaderCode = (
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
//"attribute vec4 vColor;" +
//"varying vec4 vColorVarying;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
//"vColorVarying = vColor;"+
"}")
private var fragmentShaderCode = (
"precision mediump float;" +
"uniform vec4 vColor;" +
//"varying vec4 vColorVarying;"+
"void main() {" +
//" gl_FragColor = vColorVarying;" +
" gl_FragColor = vColor;" +
"}")
internal var shapeColor = arrayOf<FloatArray>(
//front face (grey)
floatArrayOf(0f, 0f, 0f, 1f), //black
floatArrayOf(0f, 0f, 1f, 1f),
floatArrayOf(0f, 1f, 0f, 1f),
floatArrayOf(1f, 0f, 0f, 1f), // red
floatArrayOf(1f, 1f, 0f, 1f),
floatArrayOf(1f, 0f, 1f, 1f),
floatArrayOf(1f, 0f, 1f, 1f),
floatArrayOf(0f, 1f, 1f, 1f)
)
private var mPositionHandle: Int = 0
private var mColorHandle: Int = 0
// var objLoader = ObjLoader(context, "tetrahedron.txt")
// var objLoader = ObjLoader(context, "cube.txt")
var objLoader = ObjLoader(context, "octahedron.txt")
var shapeCoords: FloatArray
var numFaces: Int = 0
var vertexBuffer: FloatBuffer
var drawOrder: Array<ShortArray>
lateinit var drawListBuffer: ShortBuffer
init {
//assign coordinates and order in which to draw them (obtained from obj loader class)
shapeCoords = objLoader.vertices.toFloatArray()
drawOrder = objLoader.faces.toTypedArray()
numFaces = objLoader.numFaces
// initialize vertex byte buffer for shape coordinates
val bb = ByteBuffer.allocateDirect(
// (# of coordinate varues * 4 bytes per float)
shapeCoords.size * 4
)
bb.order(ByteOrder.nativeOrder())
vertexBuffer = bb.asFloatBuffer()
vertexBuffer.put(shapeCoords)
vertexBuffer.position(0)
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram()
val vertexShader = loadShader(
GLES20.GL_VERTEX_SHADER,
vertexShaderCode
)
val fragmentShader = loadShader(
GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode
)
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader)
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader)
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram)
}
var vertexStride = COORDS_PER_VERTEX * 4 // 4 bytes per vertex
fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix
for (face in 0 until numFaces) {
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram)
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition")
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor")
// Enable a handle to the cube vertices
GLES20.glEnableVertexAttribArray(mPositionHandle)
// Prepare the cube coordinate data
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer
)
GLES20.glUniform4fv(mColorHandle, 1, shapeColor[face], 0)
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0)
// initialize byte buffer for the draw list
var dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder[face].size * 2
)
dlb.order(ByteOrder.nativeOrder())
drawListBuffer = dlb.asShortBuffer()
drawListBuffer.put(drawOrder[face])
drawListBuffer.position(0)
GLES20.glDrawElements(
GLES20.GL_TRIANGLES,
dlb.capacity(),
GLES20.GL_UNSIGNED_SHORT,
drawListBuffer //position indices
)
}
// Disable vertex array
GLES20.glDisableVertexAttribArray(mMVPMatrixHandle)
}
companion object {
// number of coordinates per vertex in this array
internal var COORDS_PER_VERTEX = 3
}
}
class MyGLRenderer1(val context: Context) : GLSurfaceView.Renderer {
private lateinit var mShape: Shape
#Volatile
var mDeltaX = 0f
#Volatile
var mDeltaY = 0f
#Volatile
var mTotalDeltaX = 0f
#Volatile
var mTotalDeltaY = 0f
private val mMVPMatrix = FloatArray(16)
private val mProjectionMatrix = FloatArray(16)
private val mViewMatrix = FloatArray(16)
private val mRotationMatrix = FloatArray(16)
private val mAccumulatedRotation = FloatArray(16)
private val mCurrentRotation = FloatArray(16)
private val mTemporaryMatrix = FloatArray(16)
override fun onDrawFrame(gl: GL10?) {
// Redraw background color
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
val scratch = FloatArray(16)
// Create a rotation transformation for the square
Matrix.setIdentityM(mRotationMatrix, 0)
Matrix.setIdentityM(mCurrentRotation, 0)
Matrix.rotateM(mCurrentRotation, 0, mDeltaX, 0.0f, 1.0f, 0.0f)
// Matrix.rotateM(mCurrentRotation, 0, mDeltaY, 1.0f, 0.0f, 0.0f)
// Multiply the current rotation by the accumulated rotation, and then set the accumulated
// rotation to the result.
Matrix.multiplyMM(
mTemporaryMatrix,
0,
mCurrentRotation,
0,
mAccumulatedRotation,
0
)
System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16)
// Rotate the cube taking the overall rotation into account.
Matrix.multiplyMM(
mTemporaryMatrix,
0,
mRotationMatrix,
0,
mAccumulatedRotation,
0
)
System.arraycopy(mTemporaryMatrix, 0, mRotationMatrix, 0, 16)
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 2f, 2f, -5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
//Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0)
// Combine the rotation matrix with the projection and camera view
// Note that the mMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0)
gl?.glDisable(GL10.GL_CULL_FACE)
// Draw shape
mShape.draw(scratch)
}
override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
GLES20.glViewport(0, 0, width, height);
val ratio: Float = width.toFloat() / height.toFloat()
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1.0f, 1.0f, 3.0f, 7.0f)
}
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST)
// initialize a square
mShape = Shape(context)
// Initialize the accumulated rotation matrix
Matrix.setIdentityM(mAccumulatedRotation, 0)
}
}
fun loadShader(type: Int, shaderCode: String): Int {
return GLES20.glCreateShader(type).also { shader ->
GLES20.glShaderSource(shader, shaderCode)
GLES20.glCompileShader(shader)
}
}
class ObjLoader(context: Context, file: String) {
var numFaces: Int = 0
var vertices = Vector<Float>()
var normals = Vector<Float>()
var textures = Vector<Float>()
var faces = mutableListOf<ShortArray>()
init {
val reader: BufferedReader
val isr = InputStreamReader(context.assets.open(file))
reader = BufferedReader(isr)
var line = reader.readLine()
// read file until EOF
while (line != null) {
val parts = line.split((" ").toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
when (parts[0]) {
"v" -> {
var part1 = parts[1].toFloat()
var part2 = parts[2].toFloat()
var part3 = parts[3].toFloat()
// vertices
vertices.add(part1)
vertices.add(part2)
vertices.add(part3)
}
"vt" -> {
// textures
textures.add(parts[1].toFloat())
textures.add(parts[2].toFloat())
}
"vn" -> {
// normals
normals.add(parts[1].toFloat())
normals.add(parts[2].toFloat())
normals.add(parts[3].toFloat())
}
"f" -> {
// faces: vertex/texture/normal
faces.add(shortArrayOf(parts[1].toShort(), parts[2].toShort(), parts[3].toShort()))
println("dbg: points are "+ parts[1]+" "+parts[2]+" "+parts[3])
}
}
line = reader.readLine()
}
numFaces = faces.size
}}
The shape produced can be seen in the following screenshots, it is also visible on the black surface that there is possibly some sort of z fighting taking place? The black triangle flickers red and yellow:
Sometimes the following shapes are produced, flickering in and out of existence, in different colours:
Any help is much appreciated, thanks in advance.
Edit:
I have managed to make the vertices plot correctly thanks to the below answer however there is still this flickering going on, I really appreciate the help.
Array indices start at 0, but Wavefront (.obj) indices start at 1:
faces.add(shortArrayOf(parts[1].toShort(), parts[2].toShort(), parts[3].toShort()))
faces.add(shortArrayOf(
parts[1].toShort()-1, parts[2].toShort()-1, parts[3].toShort()-1))

How do I change the outline color (stroke) of my shape after drawing it?

I'm coding in Processing for the first time (previously familiar with Java) and I'm trying to make a grid of triangles where when I click one, it changes the fill and stroke to a different color. The fill is changing but the stroke remains the default color. Here is my code:
void setup() {
size(800, 600); // size of canvas
triangles = new ArrayList<TriangleClass>(); // Create an empty ArrayList
int L = 50; // length of triangle side
double halfStep = L * Math.sqrt(3);
// all the code about making the grid
}
void draw() {
background(0);
TriangleClass myCurrentTriangle;
for (int i = 0; i < triangles.size(); i++) {
// get object from ArrayList
myCurrentTriangle = triangles.get(i);
myCurrentTriangle.display();
}
}
void mouseClicked () {
TriangleClass myCurrentTriangle ;
for (int i=0; i < triangles.size(); i++) {
// get object from ArrayList
myCurrentTriangle = triangles.get(i);
myCurrentTriangle.mouseOver();
}
}
class TriangleClass {
double x1, y1, x2, y2, x3, y3; // points
color fill; // fill color
color stroke; // stroke color
float mouseSensorX, mouseSensorY;// check point for dist to mouse
// constructor
TriangleClass(
// ...
stroke = color(174, 208, 234);
fill = color(249, 249, 249);
mouseSensorX = (float) (x1+x2+x3 )/ 3;
mouseSensorY = (float) (y1+y2+y3 )/ 3;
}
void mouseOver() {
if (dist(mouseX, mouseY, mouseSensorX, mouseSensorY) < 17) {
if (fill == color(249, 249, 249)) {
stroke = color(251, 84, 84);
fill = color(251,84,84);
// ... repeated for other colors
}
}
void display() {
// show triangle
stroke(stroke);
fill(fill);
triangle((float) x1, (float) y1, (float) x2, (float) y2, (float) x3, (float) y3);
}
}
// =====================================================================
I believe the problem is the stroke weight. All you need to do it have this line of code at the end of your setup function:
strokeWeight(3);
The larger the number, the larger the outline.

Multiple Render Targets (MRT) and OSG

Folks,
I have studied about FBO, RTT and MRT to include this feature in my application, however I faced with some problems/doubts I did not find answers/tips during my search. Follows below the description of my scenario. I´ll be grateful if anyone can help me.
What I want to do?
Attach two render textures (for color and depth buffers) to the same camera;
Display only the color buffer in the post render camera;
Read images from depth and color buffer in a final draw callback;
Write collected float images in disk.
What have I got so far?
Allow rendering for color or depth buffers separately, but not both on the same camera;
Display the color buffer in the post render camera;
Read color or depth buffer in the final draw callback;
Write collected image (color or depth) in disk - only images as GL_UNSIGNED_BYTE. The following error is presented:
Error writing file ./Test-depth.png: Warning: Error in writing to "./Test-depth.png".
What are the doubts? (help!)
How can I properly render both textures (color and depth buffer) in the same camera?
How can I properly read both depth and color buffers in the final draw callback?
During image writing in disk, why the error is presented only for images as GL_FLOAT, not for GL_UNSIGNED_BYTE?
Is the render texture attached to an osg::Geode mandatory or optional in this process? Do I need to create two osg::Geode (one for each buffers), or only one osg::Geode for both?
Please take a look in my current source code (what am I doing wrong here?):
// OSG includes
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osg/Camera>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>
struct SnapImage : public osg::Camera::DrawCallback {
SnapImage(osg::GraphicsContext* gc) {
_image = new osg::Image;
_depth = new osg::Image;
if (gc->getTraits()) {
int width = gc->getTraits()->width;
int height = gc->getTraits()->height;
_image->allocateImage(width, height, 1, GL_RGBA, GL_FLOAT);
_depth->allocateImage(width, height, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
}
}
virtual void operator () (osg::RenderInfo& renderInfo) const {
osg::Camera* camera = renderInfo.getCurrentCamera();
osg::GraphicsContext* gc = camera->getGraphicsContext();
if (gc->getTraits() && _image.valid()) {
int width = gc->getTraits()->width;
int height = gc->getTraits()->height;
_image->readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT);
_depth->readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT);
osgDB::writeImageFile(*_image, "./Test-color.png");
osgDB::writeImageFile(*_depth, "./Test-depth.png");
}
}
osg::ref_ptr<osg::Image> _image;
osg::ref_ptr<osg::Image> _depth;
};
osg::Camera* setupMRTCamera( osg::ref_ptr<osg::Camera> camera, std::vector<osg::Texture2D*>& attachedTextures, int w, int h ) {
camera->setClearColor( osg::Vec4() );
camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setRenderOrder( osg::Camera::PRE_RENDER );
camera->setViewport( 0, 0, w, h );
osg::Texture2D* tex = new osg::Texture2D;
tex->setTextureSize( w, h );
tex->setSourceType( GL_FLOAT );
tex->setSourceFormat( GL_RGBA );
tex->setInternalFormat( GL_RGBA32F_ARB );
tex->setResizeNonPowerOfTwoHint( false );
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
attachedTextures.push_back( tex );
camera->attach( osg::Camera::COLOR_BUFFER, tex );
tex = new osg::Texture2D;
tex->setTextureSize( w, h );
tex->setSourceType( GL_FLOAT );
tex->setSourceFormat( GL_DEPTH_COMPONENT );
tex->setInternalFormat( GL_DEPTH_COMPONENT32 );
tex->setResizeNonPowerOfTwoHint( false );
attachedTextures.push_back( tex );
camera->attach( osg::Camera::DEPTH_BUFFER, tex );
return camera.release();
}
int main() {
osg::ref_ptr< osg::Group > root( new osg::Group );
root->addChild( osgDB::readNodeFile( "cow.osg" ) );
unsigned int winW = 800;
unsigned int winH = 600;
osgViewer::Viewer viewer;
viewer.setUpViewInWindow( 0, 0, winW, winH );
viewer.setSceneData( root.get() );
viewer.realize();
// setup MRT camera
std::vector<osg::Texture2D*> attachedTextures;
osg::Camera* mrtCamera ( viewer.getCamera() );
setupMRTCamera( mrtCamera, attachedTextures, winW, winH );
// set RTT textures to quad
osg::Geode* geode( new osg::Geode );
geode->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(-1,-1,0), osg::Vec3(2.0,0.0,0.0), osg::Vec3(0.0,2.0,0.0)) );
geode->getOrCreateStateSet()->setTextureAttributeAndModes( 0, attachedTextures[0] );
geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
geode->getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
// configure postRenderCamera to draw fullscreen textured quad
osg::Camera* postRenderCamera( new osg::Camera );
postRenderCamera->setClearMask( 0 );
postRenderCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER, osg::Camera::FRAME_BUFFER );
postRenderCamera->setReferenceFrame( osg::Camera::ABSOLUTE_RF );
postRenderCamera->setRenderOrder( osg::Camera::POST_RENDER );
postRenderCamera->setViewMatrix( osg::Matrixd::identity() );
postRenderCamera->setProjectionMatrix( osg::Matrixd::identity() );
postRenderCamera->addChild( geode );
root->addChild(postRenderCamera);
// setup the callback
SnapImage* finalDrawCallback = new SnapImage(viewer.getCamera()->getGraphicsContext());
mrtCamera->setFinalDrawCallback(finalDrawCallback);
return (viewer.run());
}
Thanks in advance,
Rômulo Cerqueira

how to apply gradient effect on Image GDI

How can I apply gradient effect on image like this image in c#. I have a transparent image with black drawing I want to apply 2 color gradient on the image is this possible in gdi?
Here is the effect i want to achieve
http://postimg.org/image/ikz1ie7ip/
You create a PathGradientBrush and then you draw your texts with that brush.
To create a bitmap filled with a gradient brush you could do something like:
public Bitmap GradientImage(int width, int height, Color color1, Color color2, float angle)
{
var r = new Rectangle(0, 0, width, height);
var bmp = new Bitmap(width, height);
using (var brush = new LinearGradientBrush(r, color1, color2, angle, true))
using (var g = Graphics.FromImage(bmp))
g.FillRectangle(brush, r);
return bmp;
}
So now that you have an image with the gradient in it, all you have to do is to bring over the alpha channel from your original image into the newly created image. We can take the transferOneARGBChannelFromOneBitmapToAnother function from a blog post I once wrote:
public enum ChannelARGB
{
Blue = 0,
Green = 1,
Red = 2,
Alpha = 3
}
public static void transferOneARGBChannelFromOneBitmapToAnother(
Bitmap source,
Bitmap dest,
ChannelARGB sourceChannel,
ChannelARGB destChannel )
{
if ( source.Size!=dest.Size )
throw new ArgumentException();
Rectangle r = new Rectangle( Point.Empty, source.Size );
BitmapData bdSrc = source.LockBits( r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );
BitmapData bdDst = dest.LockBits( r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb );
unsafe
{
byte* bpSrc = (byte*)bdSrc.Scan0.ToPointer();
byte* bpDst = (byte*)bdDst.Scan0.ToPointer();
bpSrc += (int)sourceChannel;
bpDst += (int)destChannel;
for ( int i = r.Height * r.Width; i > 0; i-- )
{
*bpDst = *bpSrc;
bpSrc += 4;
bpDst += 4;
}
}
source.UnlockBits( bdSrc );
dest.UnlockBits( bdDst );
}
Now you could do something like:
var newImage = GradientImage( original.Width, original.Height, Color.Yellow, Color.Blue, 45 );
transferOneARGBChannelFromOneBitmapToAnother( original, newImage, ChannelARGB.Alpha, ChannelARGB.Alpha );
And there you are. :-)

Resources